加载中...
STM32CubeMX配置HAL库输入捕获
发表于:2023-12-25 | 分类: 单片机 STM32

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

image-20231222170505554

  • 设置输入捕获->TIM2 打开NVIC中断

默认输入捕获通道可以设置低电平,上升沿触发

image-20231222170712990

编写程序

初始化变量(全局)

1
2
3
4
5
6
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; //电机速度

中断服务函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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++;
}
}
}
}

主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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

(之前的截图,配置都一样)

image-20231222190002435

上一篇:
点云在ROS中的应用
下一篇:
C++_Eigen库的使用
本文目录
本文目录