2.4 定时器中断
TIM 定时器分类
基本定时器
预分频、自动装载值、自定义计数方向、自定义触发事件
单个脉冲输出
可以产生 DMA 请求定期搬运数据(DMA 在 UART 章节会提到)
通用定时器
- 基本定时器的全部功能
- 四个独立 GPIO 通道可以进行输入捕获、输出比较、PWM 生成、编码器模式等
高级定时器
- 通用定时器的全部功能
- 八个 GPIO 通道可以支持反向或互补 PWM 输出
- 一个 GPIO 通道可以支持外部输入信号引入刹车重启等功能
其他常用功能
预分频(Prescaler,PSC)
- 定时器输入频率从时钟树上的 APB 总线获取,但定时器本身可能不需要太高频率,因此需要对定时器输入频率进行分频,得到定时器的主频
计数模式
定时器有个计数器(Counter,CNT
根据其主频每产生一次脉冲,计数器改变 1) , 向上计数,则 + 1;向下计数,则 - 1,双向计数则既可以 + 1 也可以 - 1
自动装载值(Auto Reload Register,ARR)
- 定时器的计数器只能在 0 到 ARR 之间变动
- 向上计数,则从 0 计数到 ARR,然后再开启一轮循环
- 向下计数,则从 ARR 计数到 0,然后再开启一轮循环
- 双向计数,则从 0 计数到 ARR-1,然后再从 ARR 计数到 1,然后再开启一轮循环
- 当计数器向上到达 ARR 或向下到达 0 时,下一个定时器主频周期会产生溢出中断
Delay 函数
Hal 库利用 SysTick 定期维护变量 uwTick 以实现计时功能
一般只在 main 中使用,不建议在中断中使用
配置定时器
- 配置 RCC-HSE 为外部晶振
- 配置时钟树 HSE 输出主频 50MHz(便于后续计算)
- 配置定时器 TIMx
- 设定为内部时钟 并调整 PSC 与 ARR
- 溢出事件频率
使用 TIM 定时器
使能定时器中断 Hal_TIM_Base_Start_IT(&htimx);
定义中断回调函数的实函数
c
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim5) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
}
}
利用 TIM 定时器中断实现按键检测消抖
1. 修改定时器配置
HSE 输出主频 50MHz
PSC:999
ARR:499
此时检测频率为 10ms
2. 修改按键配置
依据原理图定义相关按键为上拉输入
3. 代码部分
同上使能定时器中断,并定义实函数
C
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim5) {
static GPIO_PinState pre_status =
GPIO_PIN_SET; // 记录上次检测时的电平状态
GPIO_PinState now_status = HAL_GPIO_ReadPin(
GPIOE, GPIO_PIN_3); // 记录此次检测时的电平状态
if (pre_status == GPIO_PIN_SET && now_status == GPIO_PIN_RESET) {
/* 当上次为高电平(未被按下)
且此次为低电平(已被按下)*/
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5); // 反转LED电平
}
pre_status = now_status; // 更新记录的电平状态
}
}