0%

HAL库 - 定时器输入捕获

输入捕获:捕捉信号变化的时间点,保存起来

常用函数

HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
作用:启动输入捕获
*htim:定时器句柄的指针
Channel:通道编号,TIM_CHANNEL_1~`TIM_CHANNEL_4`

HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
作用:停止输入捕获
*htim:定时器句柄的指针
Channel:通道编号,TIM_CHANNEL_1~`TIM_CHANNEL_4`

__HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__)
作用:清除标志位
例如:__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC1),清除TIM1计时器的CC1标志位

__HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__)
作用:查询标志位的值
返回值(uint32_t):0 - 标志位等于0; 非零标志位等于1
例如查询TIM1计时器的CC1的标志位:uint32_t cc1Flag = __HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_CC1);

示例:超时波测距

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  /* USER CODE BEGIN WHILE */
OLED_Init();
OLED_ShowString(1,1,"Distance:");
while (1)
{
//1、向CNT计数器写0
__HAL_TIM_SET_COUNTER(&htim1, 0);

//2、清除CC1、CC2标志位
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC1);
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC2);

//3、启用定时器
HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_2);

//4、向Trig口发送脉冲,不少于10us
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
for(uint32_t i=0; i<10; i++);//每执行一次for循环认为是一个指令周期,8MHz.因此每次1us
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);

//5、等待cc1、cc2标志位
uint32_t expireTime = HAL_GetTick() + 50;//超时时间50ms
uint32_t success = 0;
while(HAL_GetTick() < expireTime )//如果没有超时
{
uint32_t cc1Flag = __HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_CC1);
uint32_t cc2Flag = __HAL_TIM_GET_FLAG(&htim1, TIM_FLAG_CC2);
if(cc1Flag && cc2Flag)
{
success = 1;//成功测量
break;
}
}

//6、关闭定时器
HAL_TIM_IC_Stop(&htim1, TIM_CHANNEL_1);
HAL_TIM_IC_Stop(&htim1, TIM_CHANNEL_2);

//7、计算结果
if(success == 1)
{
//读取cc1、cc2寄存器的值
uint16_t ccr1 = __HAL_TIM_GET_COMPARE(&htim1, TIM_CHANNEL_1);
uint16_t ccr2 = __HAL_TIM_GET_COMPARE(&htim1, TIM_CHANNEL_2);
//计算脉宽
float pulseWidth = (ccr2 - ccr1) * 1e-6f;
//计算距离 = 声速 * 传播时间 / 2
float distance = 340.0f * pulseWidth/2.0f;
//距离小于0.2,点灯
if(distance < 0.2)
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_0,GPIO_PIN_RESET);
OLED_ShowNum(1,10,distance*1000.0,5);//显示距离
}
else
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_0,GPIO_PIN_SET);
OLED_ShowNum(1,10,distance*1000.0,5);//显示距离
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}