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

【经验分享】STM32F0 定时器中断 小白掉进的坑(FreeModbus)Timeout

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码

2)通常每个IRQn对应一个zho中断函数
  1. /**
  2.   * @brief  This function handles TIM14 global interrupt request.
  3.   * @param  None
  4.   * @retval None
  5.   */
  6. void TIM14_IRQHandler(void)
  7. {
  8.   HAL_TIM_IRQHandler(&Input_Handle);
  9. }
复制代码

3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断

  1. /**
  2.   * @brief  This function handles TIM interrupts requests.
  3.   * @param  htim TIM  handle
  4.   * @retval None
  5.   */
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
  7. {
  8.   /* Capture compare 1 event */
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
  10.   {
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
  12.     {
  13.       {
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;

  16.         /* Input capture event */
  17.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
  18.         {
  19.           HAL_TIM_IC_CaptureCallback(htim);
  20.         }
  21.         /* Output compare event */
  22.         else
  23.         {
  24.           HAL_TIM_OC_DelayElapsedCallback(htim);
  25.           HAL_TIM_PWM_PulseFinishedCallback(htim);
  26.         }
  27.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  28.       }
  29.     }
  30.   }
  31.   /* Capture compare 2 event */
  32.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
  33.   {
  34.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
  35.     {
  36.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
  37.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
  38.       /* Input capture event */
  39.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
  40.       {
  41.         HAL_TIM_IC_CaptureCallback(htim);
  42.       }
  43.       /* Output compare event */
  44.       else
  45.       {
  46.         HAL_TIM_OC_DelayElapsedCallback(htim);
  47.         HAL_TIM_PWM_PulseFinishedCallback(htim);
  48.       }
  49.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  50.     }
  51.   }
  52.   /* Capture compare 3 event */
  53.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
  54.   {
  55.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
  56.     {
  57.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
  58.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
  59.       /* Input capture event */
  60.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
  61.       {
  62.         HAL_TIM_IC_CaptureCallback(htim);
  63.       }
  64.       /* Output compare event */
  65.       else
  66.       {
  67.         HAL_TIM_OC_DelayElapsedCallback(htim);
  68.         HAL_TIM_PWM_PulseFinishedCallback(htim);
  69.       }
  70.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  71.     }
  72.   }
  73.   /* Capture compare 4 event */
  74.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
  75.   {
  76.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)
  77.     {
  78.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
  79.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
  80.       /* Input capture event */
  81.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
  82.       {
  83.         HAL_TIM_IC_CaptureCallback(htim);
  84.       }
  85.       /* Output compare event */
  86.       else
  87.       {
  88.         HAL_TIM_OC_DelayElapsedCallback(htim);
  89.         HAL_TIM_PWM_PulseFinishedCallback(htim);
  90.       }
  91.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  92.     }
  93.   }
  94.   /* TIM Update event */
  95.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
  96.   {
  97.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
  98.     {
  99.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
  100.       HAL_TIM_PeriodElapsedCallback(htim);
  101.     }
  102.   }
  103.   /* TIM Break input event */
  104.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
  105.   {
  106.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
  107.     {
  108.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
  109.       HAL_TIMEx_BreakCallback(htim);
  110.     }
  111.   }
  112.   /* TIM Trigger detection event */
  113.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
  114.   {
  115.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
  116.     {
  117.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
  118.       HAL_TIM_TriggerCallback(htim);
  119.     }
  120.   }
  121.   /* TIM commutation event */
  122.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
  123.   {
  124.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)
  125.     {
  126.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
  127.       HAL_TIMEx_CommutationCallback(htim);
  128.     }
  129.   }
  130. }
复制代码

4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);

5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码

  2. void TIM14_IRQHandler(void)
  3. {
  4.   HAL_TIM_IRQHandler(&Input_Handle);

  5. //其他处理代码
  6. }
复制代码

6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。

7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。

8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。

在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。

9)ken坑啊,都怪对库的执行sh顺序不了解。


收藏 评论0 发布时间:2021-11-25 16:00

举报

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