本文主要讲解如何使用TIMER通道的输入脉冲捕获功能。基于STM32F7的Timer2 Channel3来进行讲解。
Timer2的时钟频率,对应APB1 Timer。


分频设置为96-1,这样设置定时器每次counter加1,对应的时间为1us(计时精度是1us)。Counter设置为最大即可,默认不使用定时器中断。


每个通道对应一个GPIO。

注意CubeMx生成代码不会开启捕捉,要调用HAL_TIM_IC_Start_IT进行捕捉。
- /* TIM2 init function */
- void MX_TIM2_Init(void)
- {
-
- /* USER CODE BEGIN TIM2_Init 0 */
-
- /* USER CODE END TIM2_Init 0 */
-
- TIM_ClockConfigTypeDef sClockSourceConfig = {0};
- TIM_MasterConfigTypeDef sMasterConfig = {0};
- TIM_IC_InitTypeDef sConfigIC = {0};
-
- /* USER CODE BEGIN TIM2_Init 1 */
-
- /* USER CODE END TIM2_Init 1 */
- htim2.Instance = TIM2;
- htim2.Init.Prescaler = 96-1;
- htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim2.Init.Period = 0xFFFFFFFF;
- 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_IC_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();
- }
- sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
- sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
- sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
- sConfigIC.ICFilter = 0;
- if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_3) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_4) != HAL_OK)
- {
- Error_Handler();
- }
-
- // Start Capture
- if(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_3) != HAL_OK)
- {
- Error_Handler();
- }
-
- if(HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_4) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN TIM2_Init 2 */
-
- /* USER CODE END TIM2_Init 2 */
-
- }
注意TIM输入捕获不会对捕获的脉冲进行计数,需要在中断处理函数里面进行累加处理。HAL_TIM_ACTIVE_CHANNEL_3对应当前输入捕获的Channel是TIM Channel 3。
- void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
- {
- if(htim == &htim2)
- {
- if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3) Curr_PGA_Counter++;
- }
- }
注意HAL_TIM_ReadCapturedValue获取的是以1us为单位的定时器的counter(对应时间),通过此函数可以获取捕捉到脉冲的瞬间对应的时刻。当没有捕获到新的脉冲的话,HAL_TIM_ReadCapturedValue的值返回最后一次脉冲捕获的时刻。如果定时器的counter period设置过小,会很快溢出,重新从0开始计数。建议counter period设置为最大。
- uint32_t Get_PG_ChannelA_TimCounter(void)
- {
- return HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_3);
- }
-
- void PG_Test(void)
- {
- //Pre_PGA_Counter = Curr_PGA_Counter;
- //Pre_PGB_Counter = Curr_PGB_Counter;
- uint32_t timer_us = Get_PG_ChannelA_TimCounter();
- double timer_s = (double)timer_us/1000000.0;
-
- Usart_Printf("PGA Counter: %d Timestamp: %fs\n", Curr_PGA_Counter, timer_s);
- //Usart_Printf("Curr_PGB_Counter: %d\n", Curr_PGB_Counter);
- }

