STM32定时器中断

本文最后更新于 2024年9月18日 晚上

STM32CubeMX配置

时钟树,外部时钟,端口定义都采取与流水灯实践相同的配置,可以重新按照之前重新操作一遍也可以将上次的工程复制一份出来,在副本上操作。

加上对TIM2的配置。(时钟挂载的总线请查阅相关文档或者直接看STM32CubeMX上的时钟树)

这里给出STM32F446的时钟特征图(详细信息请查阅用户手册)

时钟挂载

F4的时钟挂载如下:

时钟周期计算

当APB1和APB2分频数为1的时候,TIM1、TIM8~TIM11的时钟为APB2的时钟,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟;

而如果APB1和APB2分频数不为1,那么TIM1、TIM8~TIM11的时钟为APB2的时钟的两倍,TIM2~TIM7、TIM12~TIM14的时钟为APB1的时钟的两倍。

公式中就是分频系数,就是计数值,达到这个计数就会发生溢出中断,就是上述分析的时钟源频率。

配置参数详解

Prescaler 预分频器值,设置范围为0~65535,实际分频系数为1~65536

Counter Mode 计数模式,基础定时器只有递增模式UP

Counter Period 计数周期,设置为499,那么总共计时500个时钟周期

auto-reload preload 是否启用自重载。即当你动态改变计数周期的时候,是在下一个中断触发之后修改还是立刻修改

Triggle Event Selection 主模式下触发输出信号

- RESET:使用定时器复位信号作为TRGO的输出

- Enable:使用计数器使能信号作为TRGO的输出

- Update Event:使用定时器的UEV信号作为TRGO输出

配置操作参考

配置时钟源和时钟周期

开启定时器中断

代码

回调函数

打开keil工程,找到stm32f4xx_it.c文件。这个文件是中断回调的处理文件,所有在CubeMX中打开的中断都可以在这里找到对应的函数。

我们可以在两段USER CODE BEGIN 和 USER CODE END之间写上我们想要在触发中断时要执行的操作。

(关于为什么能够做到进入中断就调用相对应的函数,实际上涉及到汇编与硬件中固有的中断线路,这个在这里不细说,有兴趣自己可以去查相关资料。)

但是这样要是我们要改变定义在其他文件中的参数就不得不将其他文件中的参数声明为外部变量,所以我更推荐使用相对应的回调函数。

打开如图所示的信息检索

编译后对HAL_TIM_IRQHandler()右键,转到HAL_TIM_IRQHandler()函数的定义

可以看到HAL_TIM_IRQHandler()函数中调用了HAL_TIM_PeriodElapsedCallback()函数,然后再一步深究,发现HAL_TIM_PeriodElapsedCallback()函数的定义前有__weak关键词,这代表我们可以在其它文件中对它进行重定义。

代码编辑

以下代码都在main.c中。

定义回调函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int count = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM2){
if(count == 0){
HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
}
else if(count == 1){
HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
}
else if(count == 2){
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);
}
else if(count == 3){
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET);
}
count = (count + 1) % 4;
}
}

在main函数中加上如下代码

1
HAL_TIM_Base_Start_IT(&htim2);

表示打开TIM2外设时钟并且打开TIM2中断。

工程文件

百度网盘

链接:https://pan.baidu.com/s/1YZJ9w0Dn7WxT75pVc81JEA?pwd=xtqb

提取码:xtqb

实践作业

  1. 在源码基础上添加多个定时器中断,实现每个灯闪烁周期分别为1s,0.5s,0.2s,0.1s
  2. 用定时器实现4个不同亮度的灯

STM32定时器中断
http://example.com/posts/46409/
作者
晓寒
发布于
2023年10月28日
许可协议