你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32h7 定时器输出比较模式+dma,生成脉冲异常

[复制链接]
n1249624160 提问时间:2026-3-6 17:43 / 已解决

测试程序生成3个脉冲。第一次生成脉冲正常,第二次异常(少一个脉冲,脉宽也不对),第三次又正常。波形如下:

正常波形.png

异常波形.png

程序如下:

uint32_t count = 0; void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) { // 检查是否为 TIM5 的 DMA if (hdma == &hdma_tim5_ch4) {

while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) && count++ < 10000);
HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4);
HAL_DMA_Abort(&hdma_tim5_ch4);
if(count >= 10000)
count = 0;

} else if (hdma == &hdma_tim23_ch1) { HAL_TIM_PWM_Stop(&htim23, TIM_CHANNEL_1); } }

uint32_t pulseBuff[100] = { 200,600,1200,2000,3000,4200 }; //200--1US,400--2US,600--3US,800--4US //uint32_t pulseBuff[100] = { // 200,1000,1800,2600 //}; void Test_TIM5_FixedPulses(uint32_t pulse_count, uint32_t freq_hz) { uint32_t timer_clk = HAL_RCC_GetPCLK1Freq() 2; uint32_t arr = (timer_clk / (2 freq_hz)) - 1; if (arr < 2) arr = 2;

// // 停止任何正在进行的传输 HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4); HAL_DMA_Abort(&hdma_tim5_ch4);

// 填充缓冲区 0 htim5.Instance->CNT = 0; // uint32_t temp = htim5.Instance->CNT; // for (uint32_t i = 0; i < pulse_count; i++) { // temp += i % 2 ? arr 2 : arr; // pulseBuff[2 i] = temp; // temp += i % 2 ? arr 2 : arr; // pulseBuff[2 i + 1] = temp;

// }

__HAL_TIM_ENABLE_DMA(&htim5, TIM_DMA_CC4);

__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE | TIM_FLAG_CC4); // 清中断标志

htim5.Instance->CNT = 0; htim5.Instance->CCR4 = pulseBuff[0]; for(volatile int i=0; i<100; i++){} // 确保 CCR4 写入完成 HAL_DMA_Start_IT(&hdma_tim5_ch4, (uint32_t) &pulseBuff[1], (uint32_t) &htim5.Instance->CCR4, pulse_count * 2-1); // TIM_CCxChannelCmd(htim5.Instance, TIM_CHANNEL_4, TIM_CCx_ENABLE); // __HAL_TIM_ENABLE(&htim5);

// HAL_TIM_GenerateEvent(&htim5, TIM_EVENTSOURCE_CC4);

__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_CC4); // __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE);

HAL_TIM_OC_Start(&htim5, TIM_CHANNEL_4); }

int main(void) {

/ USER CODE BEGIN 1 /

/ USER CODE END 1 /

/ MPU Configuration--------------------------------------------------------/ // MPU_Config();

/ Enable the CPU Cache /

/ Enable I-Cache---------------------------------------------------------/ // SCB_EnableICache();

/ MCU Configuration--------------------------------------------------------/

/ Reset of all peripherals, Initializes the Flash interface and the Systick. / HAL_Init();

/ USER CODE BEGIN Init /

/ USER CODE END Init /

/ Configure the system clock / SystemClock_Config();

/ USER CODE BEGIN SysInit /

/ USER CODE END SysInit /

/ Initialize all configured peripherals / MX_GPIO_Init(); MX_DMA_Init(); MX_UART9_Init(); MX_TIM5_Init(); MX_TIM23_Init(); / USER CODE BEGIN 2 /

/ USER CODE END 2 /

/ Infinite loop / / USER CODE BEGIN WHILE / while (1) { if(HAL_GetTick()%1000 == 0) { HAL_GPIO_WritePin(GPIOA, SYS_LED1_Pin, GPIO_PIN_SET); } else if(HAL_GetTick()%1000 == 500) { HAL_GPIO_WritePin(GPIOA, SYS_LED1_Pin, GPIO_PIN_RESET); } if(receiveFlag) { receiveFlag = 0; HAL_UART_Transmit(&huart9, receiveBuff, 1, 0xffff);

    static uint8_t flag = 0;

    if(flag == 0)
    {
        flag = 1;
    Test_TIM5_FixedPulses(3, 5000);
    }
    else
    {
        flag = 0;
        Test_TIM5_FixedPulses(3, 50000);
    }
}
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

} / USER CODE END 3 / }

void MX_TIM5_Init(void) {

/ USER CODE BEGIN TIM5_Init 0 /

/ USER CODE END TIM5_Init 0 /

TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0};

/ USER CODE BEGIN TIM5_Init 1 /

/ USER CODE END TIM5_Init 1 / htim5.Instance = TIM5; htim5.Init.Prescaler = 0; htim5.Init.CounterMode = TIM_COUNTERMODE_UP; htim5.Init.Period = 0xFFFFFFFF; htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_OC_Init(&htim5) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_TOGGLE; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_OC_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) { Error_Handler(); }

HAL_TIM_MspPostInit(&htim5);

/ USER CODE BEGIN TIM5_Init 2 / extern void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef hdma); HAL_DMA_RegisterCallback(&hdma_tim5_ch4, HAL_DMA_XFER_CPLT_CB_ID, HAL_DMA_XferCpltCallback); / USER CODE END TIM5_Init 2 */ }

void HAL_TIM_OC_MspInit(TIM_HandleTypeDef* tim_ocHandle) {

if(tim_ocHandle->Instance==TIM5) { / USER CODE BEGIN TIM5_MspInit 0 /

/* USER CODE END TIM5_MspInit 0 */
/* TIM5 clock enable */
__HAL_RCC_TIM5_CLK_ENABLE();

/* TIM5 DMA Init */
/* TIM5_CH4 Init */
hdma_tim5_ch4.Instance = DMA1_Stream0;
hdma_tim5_ch4.Init.Request = DMA_REQUEST_TIM5_CH4;
hdma_tim5_ch4.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tim5_ch4.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim5_ch4.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim5_ch4.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim5_ch4.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_tim5_ch4.Init.Mode = DMA_NORMAL;
hdma_tim5_ch4.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_tim5_ch4.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_tim5_ch4) != HAL_OK)
{
    Error_Handler();
}

__HAL_LINKDMA(tim_ocHandle,hdma[TIM_DMA_ID_CC4],hdma_tim5_ch4);

/* TIM5 interrupt Init */
HAL_NVIC_SetPriority(TIM5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM5_IRQn);
/* USER CODE BEGIN TIM5_MspInit 1 */

/* USER CODE END TIM5_MspInit 1 */

} }

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle) {

GPIO_InitTypeDef GPIO_InitStruct = {0}; if(timHandle->Instance==TIM5) { / USER CODE BEGIN TIM5_MspPostInit 0 /

/* USER CODE END TIM5_MspPostInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM5 GPIO Configuration
PA3     ------> TIM5_CH4
*/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN; //GPIO_PULLUP;//GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM5;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* USER CODE BEGIN TIM5_MspPostInit 1 */

/* USER CODE END TIM5_MspPostInit 1 */

} else if(timHandle->Instance==TIM23) { / USER CODE BEGIN TIM23_MspPostInit 0 /

/* USER CODE END TIM23_MspPostInit 0 */

__HAL_RCC_GPIOF_CLK_ENABLE();
/**TIM23 GPIO Configuration
PF0     ------> TIM23_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF13_TIM23;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

/* USER CODE BEGIN TIM23_MspPostInit 1 */

/* USER CODE END TIM23_MspPostInit 1 */

} }

收藏 评论9 发布时间:2026-3-6 17:43

举报

9个回答
xmshao 最优答案 回答时间:2026-3-9 10:58:00

n1249624160 发表于 2026-3-9 10:07
buffer在AXI SRAM。arr是8个f,不变,只改变ccr实现电平翻转,翻转快慢决定频率快慢。源码发您邮箱了 ...

[md]OK

我这边先测试下,有结果了会回复你。

使用TIMER随意输出多个不同占空比脉冲的示例

n1249624160 回答时间:2026-3-6 18:01:31
void MX_TIM5_Init(void)
{

    /* USER CODE BEGIN TIM5_Init 0 */

    /* USER CODE END TIM5_Init 0 */

    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_OC_InitTypeDef sConfigOC = {0};

    /* USER CODE BEGIN TIM5_Init 1 */

    /* USER CODE END TIM5_Init 1 */
    htim5.Instance = TIM5;
    htim5.Init.Prescaler = 0;
    htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim5.Init.Period = 0xFFFFFFFF;
    htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_OC_Init(&htim5) != HAL_OK)
    {
        Error_Handler();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
    {
        Error_Handler();
    }
    sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    if (HAL_TIM_OC_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
    {
        Error_Handler();
    }

    HAL_TIM_MspPostInit(&htim5);
       
        /* USER CODE BEGIN TIM5_Init 2 */
    extern void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma);
    HAL_DMA_RegisterCallback(&hdma_tim5_ch4, HAL_DMA_XFER_CPLT_CB_ID,
                             HAL_DMA_XferCpltCallback);
    /* USER CODE END TIM5_Init 2 */

}

n1249624160 回答时间:2026-3-6 17:58:47

uint32_t count = 0; void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) { // 检查是否为 TIM5 的 DMA if (hdma == &hdma_tim5_ch4) {

while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) && count++ < 10000);
HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4);
HAL_DMA_Abort(&hdma_tim5_ch4);
if(count >= 10000)
count = 0;

} else if (hdma == &hdma_tim23_ch1) { HAL_TIM_PWM_Stop(&htim23, TIM_CHANNEL_1); } }

uint32_t pulseBuff[100] = { 200,600,1200,2000,3000,4200 }; //200--1US,400--2US,600--3US,800--4US //uint32_t pulseBuff[100] = { // 200,1000,1800,2600 //}; void Test_TIM5_FixedPulses(uint32_t pulse_count, uint32_t freq_hz) { uint32_t timer_clk = HAL_RCC_GetPCLK1Freq() 2; uint32_t arr = (timer_clk / (2 freq_hz)) - 1; if (arr < 2) arr = 2;

// // 停止任何正在进行的传输 HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4); HAL_DMA_Abort(&hdma_tim5_ch4);

// 填充缓冲区 0 htim5.Instance->CNT = 0; // uint32_t temp = htim5.Instance->CNT; // for (uint32_t i = 0; i < pulse_count; i++) { // temp += i % 2 ? arr 2 : arr; // pulseBuff[2 i] = temp; // temp += i % 2 ? arr 2 : arr; // pulseBuff[2 i + 1] = temp;

// }

__HAL_TIM_ENABLE_DMA(&htim5, TIM_DMA_CC4);

__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE | TIM_FLAG_CC4); // 清中断标志

htim5.Instance->CNT = 0; htim5.Instance->CCR4 = pulseBuff[0]; for(volatile int i=0; i<100; i++){} // 确保 CCR4 写入完成 HAL_DMA_Start_IT(&hdma_tim5_ch4, (uint32_t) &pulseBuff[1], (uint32_t) &htim5.Instance->CCR4, pulse_count * 2-1); // TIM_CCxChannelCmd(htim5.Instance, TIM_CHANNEL_4, TIM_CCx_ENABLE); // __HAL_TIM_ENABLE(&htim5);

// HAL_TIM_GenerateEvent(&htim5, TIM_EVENTSOURCE_CC4);

__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_CC4); // __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE);

HAL_TIM_OC_Start(&htim5, TIM_CHANNEL_4); }

n1249624160 回答时间:2026-3-6 17:59:58
uint32_t count = 0;
void HAL_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) {
    // 检查是否为 TIM5 的 DMA
    if (hdma == &hdma_tim5_ch4) {

        while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) && count++ < 10000);
        HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4);
        HAL_DMA_Abort(&hdma_tim5_ch4);
                if(count >= 10000)
                count = 0;
    }
    else if (hdma == &hdma_tim23_ch1) {
        HAL_TIM_PWM_Stop(&htim23, TIM_CHANNEL_1);
        }
}


uint32_t pulseBuff[100] = {
        200,600,1200,2000,3000,4200
};        //200--1US,400--2US,600--3US,800--4US
//uint32_t pulseBuff[100] = {
//        200,1000,1800,2600
//};
void Test_TIM5_FixedPulses(uint32_t pulse_count, uint32_t freq_hz) {
    uint32_t timer_clk = HAL_RCC_GetPCLK1Freq() * 2;
    uint32_t arr = (timer_clk / (2 * freq_hz)) - 1;
    if (arr < 2)     arr = 2;

    //        // 停止任何正在进行的传输
    HAL_TIM_OC_Stop(&htim5, TIM_CHANNEL_4);
    HAL_DMA_Abort(&hdma_tim5_ch4);

    // 填充缓冲区 0
    htim5.Instance->CNT = 0;
       
//    uint32_t temp = htim5.Instance->CNT;
//    for (uint32_t i = 0; i < pulse_count; i++) {
//        temp += i % 2 ? arr * 2 : arr;
//        pulseBuff[2 * i] = temp;
//        temp += i % 2 ? arr * 2 : arr;
//        pulseBuff[2 * i + 1] = temp;

//    }
       
    __HAL_TIM_ENABLE_DMA(&htim5, TIM_DMA_CC4);
       
         __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE | TIM_FLAG_CC4); // 清中断标志
       
        htim5.Instance->CNT = 0;
        htim5.Instance->CCR4 = pulseBuff[0];
        for(volatile int i=0; i<100; i++){}  // 确保 CCR4 写入完成
    HAL_DMA_Start_IT(&hdma_tim5_ch4, (uint32_t) &pulseBuff[1],
                     (uint32_t) &htim5.Instance->CCR4, pulse_count * 2-1);

//    TIM_CCxChannelCmd(htim5.Instance, TIM_CHANNEL_4, TIM_CCx_ENABLE);
//    __HAL_TIM_ENABLE(&htim5);

//    HAL_TIM_GenerateEvent(&htim5, TIM_EVENTSOURCE_CC4);
       
    __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_CC4);
       
//    __HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE);

    HAL_TIM_OC_Start(&htim5, TIM_CHANNEL_4);

}

n1249624160 回答时间:2026-3-6 18:00:55
int main(void)
{

    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /* MPU Configuration--------------------------------------------------------*/
//  MPU_Config();

    /* Enable the CPU Cache */

    /* Enable I-Cache---------------------------------------------------------*/
//  SCB_EnableICache();

    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_UART9_Init();
    MX_TIM5_Init();
    MX_TIM23_Init();
    /* USER CODE BEGIN 2 */

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        if(HAL_GetTick()%1000 == 0)
        {
            HAL_GPIO_WritePin(GPIOA, SYS_LED1_Pin, GPIO_PIN_SET);
        }
        else if(HAL_GetTick()%1000 == 500)
        {
            HAL_GPIO_WritePin(GPIOA, SYS_LED1_Pin, GPIO_PIN_RESET);
        }
        if(receiveFlag)
        {
            receiveFlag = 0;
            HAL_UART_Transmit(&huart9, receiveBuff,
                              1, 0xffff);

                        static uint8_t flag = 0;
                       
                        if(flag == 0)
                        {
                                flag = 1;
            Test_TIM5_FixedPulses(3, 5000);
                        }
                        else
                        {
                                flag = 0;
                                Test_TIM5_FixedPulses(3, 50000);
                        }
        }
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

xmshao 回答时间:2026-3-9 09:14:34

我看你给出的波形,怎么感觉第一个 第二个波形是正常的,第三个异常呢?

既然有输出了,DMA配置这块应该没啥问题了。 问题可能出在TIMER CCR这个地方了。

你的代码:

__HAL_TIM_ENABLE_DMA(&htim5, TIM_DMA_CC4);

__HAL_TIM_CLEAR_FLAG(&htim5, TIM_FLAG_UPDATE | TIM_FLAG_CC4); // 清中断标志

htim5.Instance->CNT = 0;

htim5.Instance->CCR4 = pulseBuff[0];

加上一句:TIM5->EGR = TIM_EGR_UG; 然后测试下。

n1249624160 回答时间:2026-3-9 09:38:32

xmshao 发表于 2026-3-9 09:14
我看你给出的波形,怎么感觉第一个 第二个波形是正常的,第三个异常呢?</p>
<p>既然有输出了,DMA配置这块应 ...

[md]谢谢您的回答!试过了还是一样的问题。

image.png

xmshao 回答时间:2026-3-9 09:45:29

n1249624160 发表于 2026-3-9 09:38
谢谢您的回答!试过了还是一样的问题。</p>
<p>![image.png](data/attachment/forum/202603/09/093652sun9u ...

[md]另外,你确认下你存放CCR数据的buffer没有在TCM区域,其它AXI SRAM 或SRAM1/2/3都可以。

你的ARR始终是8个F?

如果这里没有问题,那就是再细看你的代码了。尽可能将代码简化,缩小范围。

n1249624160 回答时间:2026-3-9 10:07:48

xmshao 发表于 2026-3-9 09:45
另外,你确认下你存放CCR数据的buffer没有在TCM区域,其它AXI SRAM 或SRAM1/2/3都可以。</p>
<p>你的ARR始 ...

[md]buffer在AXI SRAM。arr是8个f,不变,只改变ccr实现电平翻转,翻转快慢决定频率快慢。源码发您邮箱了,有空帮忙分析下吧。

image.png

image.png

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版