TIM定时器中断

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
    • 溢出事件频率 $ frequency= $

使用TIM定时器#

使能定时器中断 Hal_TIM_Base_Start_IT(&htimx);

定义中断回调函数的实函数

1
2
3
4
5
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. 代码部分#

同上使能定时器中断,并定义实函数

1
2
3
4
5
6
7
8
9
10
11
12
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; //更新记录的电平状态
}
}