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的捕获通道1
HAL_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
(之前的截图没设置滤波器,配置都一样)