STM32CubeMX配置HAL库输入捕获
STM32的输入捕获功能可以用来测量脉冲宽度或者频率。其工作原理是,通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如
上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。
硬件
- STM32F407IGT6
- Stlink
- USB-TTL
软件
- STM32CubeMX
- CLion
配置
-
RCC->High Speed Clock (HSE)-> Crystal/Ceramic Resonator
-
SYS->Debug->Serial Wire
-
Clock Configuration -> HCLK->84
-
设置PWM->TIM3
- 设置输入捕获->TIM2 适当设置滤波器 打开NVIC中断
默认输入捕获通道可以设置低电平,上升沿触发
编写程序
初始化变量(全局)
uint32_t capture_left_Buf[3] = {0}; //左电机存放计数值
uint32_t capture_right_Buf[3] = {0}; //右存放计数值
uint8_t capture_left_Cnt = 0; //左电机状态标志位
uint8_t capture_right_Cnt = 0; //右电机状态标志位
uint32_t left_time, right_time; //周期时间
uint32_t left_speed, right_speed; //电机速度
中断服务函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)// 捕获中断发生时执行
{if(htim->Instance == TIM2){if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){switch(capture_left_Cnt){case 1:capture_left_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值
// __HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING); //设置为下降沿捕获capture_left_Cnt++;break;case 2:capture_left_Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
// capture_Num = capture_flag;
// capture_flag = 0;HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); //停止捕获 或者: __HAL_TIM_DISABLE(&htim2);capture_left_Cnt++;}}if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){switch(capture_right_Cnt){case 1:capture_right_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);//获取当前的捕获值capture_right_Cnt++;break;case 2:capture_right_Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);//获取当前的捕获值.HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_2); //停止捕获 或者: __HAL_TIM_DISABLE(&htim2);capture_right_Cnt++;}}}
}
主函数
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1); //开启TIM2的捕获通道1HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2); //开启TIM2的捕获通道2__HAL_TIM_ENABLE_IT(&htim2,TIM_IT_UPDATE); //使能更新中断/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */Load_PWM(500, 500);switch (capture_left_Cnt){case 0:capture_left_Cnt++;__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); //启动输入捕获 或者: __HAL_TIM_ENABLE(&htim2);break;case 3:left_time = capture_left_Buf[1]- capture_left_Buf[0]; //周期capture_left_Cnt = 0; //清空标志位break;}switch (capture_right_Cnt){case 0:capture_right_Cnt++;__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); //启动输入捕获 或者: __HAL_TIM_ENABLE(&htim2);break;case 3:right_time = capture_right_Buf[1]- capture_right_Buf[0]; //周期capture_right_Cnt = 0; //清空标志位break;}printf("{\"left_time\":%d,\"right_time\":%d} \r\n",left_time, right_time);HAL_Delay(1000);}
演示
用杜邦线连接PA6->PA0 PA7->PA1
PWM脉冲 84M/168/1000 = 500Hz 1/500Hz = 20ms = 200us
(之前的截图没设置滤波器,配置都一样)