[STM32WBA] 【STM32WBA52CG测评】-4- 定时器模块TIM例程分析

[复制链接]
2021|1
 楼主| 南来之风 发表于 2023-7-31 22:19 | 显示全部楼层 |阅读模式
本帖最后由 南来之风 于 2023-7-31 22:24 编辑

ST的官方库有非常丰富的外设使用例程,本文体验的就是:STM32Cube_FW_WBA_V1.1.0\Projects\NUCLEO-WBA52CG\Examples\TIM\TIM_TimeBase
该例程配置使用TIM模块产生一个1s的中断,然后再中断服务函数中翻转LED。

初始化外设,Flash和Systick:
  1. HAL_Init();


SystemClock_Config() 函数用于配置STM32WBA52CGUx 设备系统时钟为100 MHz
  1.   /* Configure the system clock */
  2.   SystemClock_Config();

根据官方ReadMe,TIM模块的时钟频率,TIM2模块的计数器时钟频率,以及周期都有相应的公式:


In this example TIM2 input clock (TIM2CLK)  is set to APB1 clock (PCLK1),since APB1 prescaler is equal to 1.  TIM2CLK = PCLK1  PCLK1 = HCLK  => TIM2CLK = HCLK = SystemCoreClockTo get TIM2 counter clock at 10 KHz, the Prescaler is computed as following:Prescaler = (TIM2CLK / TIM2 counter clock) - 1Prescaler = (SystemCoreClock /10 KHz) - 1
SystemCoreClock is set to 100 MHz for STM32WBAxx Devices.
The TIM2 ARR register value is equal to 10000 - 1
Update rate = TIM2 counter clock / (Period + 1) = 1 Hz
So the TIM2 generates an interrupt each 1 s
When the counter value reaches the auto-reload register value, the TIM update interrupt is generated and, in the handler routine, pin PB.4 (connected to LD1 on board NUCLEO-WBA52CG) is toggled. So led blinks at the following frequency: 0.5Hz.
In case of error, LD3 is turned ON.

在main.h中,有相应的参数定义:
  1. /* Compute the prescaler value to have TIMx counter clock equal to 10000 Hz */

  2. #define PRESCALER_VALUE (uint32_t)(((SystemCoreClock) / (10000)) - 1)

  3.   /* Initialize TIMx peripheral as follows:
  4.        + Period = 10000 - 1
  5.        + Prescaler = (SystemCoreClock/10000) - 1
  6.        + ClockDivision = 0
  7.        + Counter direction = Up
  8.   */

  9. #define PERIOD_VALUE (10000 - 1);


在main.c中,调用如下函数进行TIM模块初始化:
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url] TIM2 Initialization Function
  3.   * @param None
  4.   * @retval None
  5.   */
  6. static void MX_TIM2_Init(void)
  7. {

  8.   /* USER CODE BEGIN TIM2_Init 0 */

  9.   /* USER CODE END TIM2_Init 0 */

  10.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  11.   TIM_MasterConfigTypeDef sMasterConfig = {0};

  12.   /* USER CODE BEGIN TIM2_Init 1 */

  13.   /* USER CODE END TIM2_Init 1 */
  14.   htim2.Instance = TIM2;
  15.   htim2.Init.Prescaler = PRESCALER_VALUE;
  16.   htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  17.   htim2.Init.Period = PERIOD_VALUE;
  18.   htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  19.   htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  20.   if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  21.   {
  22.     Error_Handler();
  23.   }
  24.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  25.   if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  26.   {
  27.     Error_Handler();
  28.   }
  29.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  30.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  31.   if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  32.   {
  33.     Error_Handler();
  34.   }
  35.   /* USER CODE BEGIN TIM2_Init 2 */

  36.   /* USER CODE END TIM2_Init 2 */

  37. }

如下定义了TIM2模块的中断服务子程序:
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url] This function handles TIM2 global interrupt.
  3.   */
  4. void TIM2_IRQHandler(void)
  5. {
  6.   /* USER CODE BEGIN TIM2_IRQn 0 */

  7.   /* USER CODE END TIM2_IRQn 0 */
  8.   HAL_TIM_IRQHandler(&htim2);
  9.   /* USER CODE BEGIN TIM2_IRQn 1 */

  10.   /* USER CODE END TIM2_IRQn 1 */
  11. }

接着调用HAL库中的中断服务子程序:
  1. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
  2. {
  3.   uint32_t itsource = htim->Instance->DIER;
  4.   uint32_t itflag   = htim->Instance->SR;

  5.   /* Capture compare 1 event */
  6.   if ((itflag & (TIM_FLAG_CC1)) == (TIM_FLAG_CC1))
  7.   {
  8.     if ((itsource & (TIM_IT_CC1)) == (TIM_IT_CC1))
  9.     {
  10.       {
  11.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
  12.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;

  13.         /* Input capture event */
  14.         if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
  15.         {
  16. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  17.           htim->IC_CaptureCallback(htim);
  18. #else
  19.           HAL_TIM_IC_CaptureCallback(htim);
  20. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  21.         }
  22.         /* Output compare event */
  23.         else
  24.         {
  25. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  26.           htim->OC_DelayElapsedCallback(htim);
  27.           htim->PWM_PulseFinishedCallback(htim);
  28. #else
  29.           HAL_TIM_OC_DelayElapsedCallback(htim);
  30.           HAL_TIM_PWM_PulseFinishedCallback(htim);
  31. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  32.         }
  33.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  34.       }
  35.     }
  36.   }
  37.   /* Capture compare 2 event */
  38.   if ((itflag & (TIM_FLAG_CC2)) == (TIM_FLAG_CC2))
  39.   {
  40.     if ((itsource & (TIM_IT_CC2)) == (TIM_IT_CC2))
  41.     {
  42.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
  43.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
  44.       /* Input capture event */
  45.       if ((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
  46.       {
  47. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  48.         htim->IC_CaptureCallback(htim);
  49. #else
  50.         HAL_TIM_IC_CaptureCallback(htim);
  51. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  52.       }
  53.       /* Output compare event */
  54.       else
  55.       {
  56. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  57.         htim->OC_DelayElapsedCallback(htim);
  58.         htim->PWM_PulseFinishedCallback(htim);
  59. #else
  60.         HAL_TIM_OC_DelayElapsedCallback(htim);
  61.         HAL_TIM_PWM_PulseFinishedCallback(htim);
  62. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  63.       }
  64.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  65.     }
  66.   }
  67.   /* Capture compare 3 event */
  68.   if ((itflag & (TIM_FLAG_CC3)) == (TIM_FLAG_CC3))
  69.   {
  70.     if ((itsource & (TIM_IT_CC3)) == (TIM_IT_CC3))
  71.     {
  72.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
  73.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
  74.       /* Input capture event */
  75.       if ((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
  76.       {
  77. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  78.         htim->IC_CaptureCallback(htim);
  79. #else
  80.         HAL_TIM_IC_CaptureCallback(htim);
  81. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  82.       }
  83.       /* Output compare event */
  84.       else
  85.       {
  86. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  87.         htim->OC_DelayElapsedCallback(htim);
  88.         htim->PWM_PulseFinishedCallback(htim);
  89. #else
  90.         HAL_TIM_OC_DelayElapsedCallback(htim);
  91.         HAL_TIM_PWM_PulseFinishedCallback(htim);
  92. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  93.       }
  94.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  95.     }
  96.   }
  97.   /* Capture compare 4 event */
  98.   if ((itflag & (TIM_FLAG_CC4)) == (TIM_FLAG_CC4))
  99.   {
  100.     if ((itsource & (TIM_IT_CC4)) == (TIM_IT_CC4))
  101.     {
  102.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
  103.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
  104.       /* Input capture event */
  105.       if ((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
  106.       {
  107. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  108.         htim->IC_CaptureCallback(htim);
  109. #else
  110.         HAL_TIM_IC_CaptureCallback(htim);
  111. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  112.       }
  113.       /* Output compare event */
  114.       else
  115.       {
  116. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  117.         htim->OC_DelayElapsedCallback(htim);
  118.         htim->PWM_PulseFinishedCallback(htim);
  119. #else
  120.         HAL_TIM_OC_DelayElapsedCallback(htim);
  121.         HAL_TIM_PWM_PulseFinishedCallback(htim);
  122. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  123.       }
  124.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  125.     }
  126.   }
  127.   /* TIM Update event */
  128.   if ((itflag & (TIM_FLAG_UPDATE)) == (TIM_FLAG_UPDATE))
  129.   {
  130.     if ((itsource & (TIM_IT_UPDATE)) == (TIM_IT_UPDATE))
  131.     {
  132.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
  133. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  134.       htim->PeriodElapsedCallback(htim);
  135. #else
  136.       HAL_TIM_PeriodElapsedCallback(htim);
  137. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  138.     }
  139.   }
  140.   /* TIM Break input event */
  141.   if ((itflag & (TIM_FLAG_BREAK)) == (TIM_FLAG_BREAK))
  142.   {
  143.     if ((itsource & (TIM_IT_BREAK)) == (TIM_IT_BREAK))
  144.     {
  145.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
  146. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  147.       htim->BreakCallback(htim);
  148. #else
  149.       HAL_TIMEx_BreakCallback(htim);
  150. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  151.     }
  152.   }
  153.   /* TIM Break2 input event */
  154.   if ((itflag & (TIM_FLAG_BREAK2)) == (TIM_FLAG_BREAK2))
  155.   {
  156.     if ((itsource & (TIM_IT_BREAK)) == (TIM_IT_BREAK))
  157.     {
  158.       __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_BREAK2);
  159. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  160.       htim->Break2Callback(htim);
  161. #else
  162.       HAL_TIMEx_Break2Callback(htim);
  163. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  164.     }
  165.   }
  166.   /* TIM Trigger detection event */
  167.   if ((itflag & (TIM_FLAG_TRIGGER)) == (TIM_FLAG_TRIGGER))
  168.   {
  169.     if ((itsource & (TIM_IT_TRIGGER)) == (TIM_IT_TRIGGER))
  170.     {
  171.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
  172. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  173.       htim->TriggerCallback(htim);
  174. #else
  175.       HAL_TIM_TriggerCallback(htim);
  176. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  177.     }
  178.   }
  179.   /* TIM commutation event */
  180.   if ((itflag & (TIM_FLAG_COM)) == (TIM_FLAG_COM))
  181.   {
  182.     if ((itsource & (TIM_IT_COM)) == (TIM_IT_COM))
  183.     {
  184.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
  185. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  186.       htim->CommutationCallback(htim);
  187. #else
  188.       HAL_TIMEx_CommutCallback(htim);
  189. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  190.     }
  191.   }
  192.   /* TIM Encoder index event */
  193.   if ((itflag & (TIM_FLAG_IDX)) == (TIM_FLAG_IDX))
  194.   {
  195.     if ((itsource & (TIM_IT_IDX)) == (TIM_IT_IDX))
  196.     {
  197.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_IDX);
  198. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  199.       htim->EncoderIndexCallback(htim);
  200. #else
  201.       HAL_TIMEx_EncoderIndexCallback(htim);
  202. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  203.     }
  204.   }
  205.   /* TIM Direction change event */
  206.   if ((itflag & (TIM_FLAG_DIR)) == (TIM_FLAG_DIR))
  207.   {
  208.     if ((itsource & (TIM_IT_DIR)) == (TIM_IT_DIR))
  209.     {
  210.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_DIR);
  211. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  212.       htim->DirectionChangeCallback(htim);
  213. #else
  214.       HAL_TIMEx_DirectionChangeCallback(htim);
  215. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  216.     }
  217.   }
  218.   /* TIM Index error event */
  219.   if ((itflag & (TIM_FLAG_IERR)) == (TIM_FLAG_IERR))
  220.   {
  221.     if ((itsource & (TIM_IT_IERR)) == (TIM_IT_IERR))
  222.     {
  223.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_IERR);
  224. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  225.       htim->IndexErrorCallback(htim);
  226. #else
  227.       HAL_TIMEx_IndexErrorCallback(htim);
  228. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  229.     }
  230.   }
  231.   /* TIM Transition error event */
  232.   if ((itflag & (TIM_FLAG_TERR)) == (TIM_FLAG_TERR))
  233.   {
  234.     if ((itsource & (TIM_IT_TERR)) == (TIM_IT_TERR))
  235.     {
  236.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_TERR);
  237. #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
  238.       htim->TransitionErrorCallback(htim);
  239. #else
  240.       HAL_TIMEx_TransitionErrorCallback(htim);
  241. #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
  242.     }
  243.   }
  244. }

注意其中有个函数调用:

  1. HAL_TIM_PeriodElapsedCallback(htim);

这个回调函数的定义如下:

  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  Period elapsed callback in non blocking mode
  3.   * @param  htim : TIM handle
  4.   * @retval None
  5.   */
  6. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  7. {
  8.         BSP_LED_Toggle(LD1);
  9. }


烧录后,可以看到LD1以1s频率闪烁。
2195864c7c3045699c.png





gejigeji521 发表于 2024-1-12 17:03 | 显示全部楼层
分析的少了,全是源码了,没看太懂,应该先将一下整个原理。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

69

主题

294

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部