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

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管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版