You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F0单定时器能否生成多延迟时间中断?

STM32F0单定时器实现多延迟中断方案

可以实现,利用STM32F0通用定时器的输出比较(OC)模式,通过4个独立的比较通道,就能在单次启动定时器后,分别在指定的20us、50us、100us、300us触发中断,无需占用多个定时器。

核心原理

STM32F0的16位通用定时器(如TIM2、TIM3、TIM4)具备最多4个输出比较通道,每个通道拥有独立的捕获/比较寄存器(CCR1~CCR4)。当定时器计数器(CNT)的值等于某个通道的CCRx值时,该通道会触发中断,以此实现不同时间点的中断触发。

具体实现步骤(基于HAL库)

  1. 定时器基础配置
    假设APB1时钟为48MHz(STM32F0默认总线时钟),将定时器预分频器设为47,这样定时器计数频率为48MHz/(47+1)=1MHz,即每计数1次对应1us。将自动重装载寄存器(ARR)设为最大值65535,让定时器持续向上计数。

    TIM_HandleTypeDef htim2;
    
    void MX_TIM2_Init(void)
    {
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
      TIM_OC_InitTypeDef sConfigOC = {0};
    
      htim2.Instance = TIM2;
      htim2.Init.Prescaler = 47;
      htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim2.Init.Period = 65535;
      htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
      if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      if (HAL_TIM_OC_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
    }
    
  2. 通道比较值配置与中断开启
    分别为4个通道设置对应的CCRx值(20、50、100、300),并开启每个通道的比较中断:

    // 配置通道1:20us触发
    sConfigOC.OCMode = TIM_OCMODE_TIMING;
    sConfigOC.Pulse = 20;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
    {
      Error_Handler();
    }
    HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_1);
    
    // 通道2:50us触发
    sConfigOC.Pulse = 50;
    if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
    {
      Error_Handler();
    }
    HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_2);
    
    // 通道3:100us触发
    sConfigOC.Pulse = 100;
    if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
    {
      Error_Handler();
    }
    HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_3);
    
    // 通道4:300us触发
    sConfigOC.Pulse = 300;
    if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
    {
      Error_Handler();
    }
    HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_4);
    
  3. 中断回调处理
    在HAL库中,通道比较中断会触发HAL_TIM_OC_DelayElapsedCallback函数,通过判断当前触发的通道,执行对应逻辑:

    void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
    {
      if (htim->Instance == TIM2)
      {
        if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1))
        {
          __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC1);
          // 执行20us延迟后的任务
        }
        else if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2))
        {
          __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC2);
          // 执行50us延迟后的任务
        }
        else if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3))
        {
          __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC3);
          // 执行100us延迟后的任务
        }
        else if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4))
        {
          __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC4);
          // 执行300us延迟后的任务
        }
      }
    }
    

注意事项

  • 如果需要重复触发某一延迟的中断,需在对应通道的中断处理中,将CCRx的值加上当前计数器值(或固定偏移),确保下一次触发时间正确。
  • STM32F0的TIM1是高级定时器,也支持多通道比较,但通用定时器TIM2/TIM3/TIM4已足够满足需求,无需占用高级定时器资源。
  • 务必在NVIC中正确配置定时器中断的优先级,避免与其他中断冲突。

内容的提问来源于stack exchange,提问作者ElecDesigner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 21:20:26