【STM32】HAL库——定时器溢出中断

本文档介绍了一位工程师在STM32F103RCT6单片机上进行实物编程的经验,包括使用STM32CubeMX配置时钟、TIM定时器,选择内部时钟,设置向上计数模式,以及通过Keil MDK进行中断处理。在Keil工程中,详细解释了HAL_TIM_IRQHandler函数和HAL_TIM_PeriodElapsedCallback回调函数的应用,用于实现定时器1每隔1ms中断一次,当计数达到500ms时翻转PB0引脚状态,从而控制LED灯闪烁。整个过程涵盖了从时钟配置到中断回调的完整流程,为STM32初学者提供了实用的教程。

经过多次调试,我发现Proteus 8的仿真效果并不是很理想,所以接下来的例程将改用STM32F103RCT6单片机实物进行讲解.

前期准备:

  1. STM32CubeMX
  2. STM32RCT6核心板
  3. IDE Keil(MDK-ARM)

STM32CubeMX部分


1. 配置时钟

选择STM32F103RCTx系列芯片,配置时钟的同时会自动配置IO口引脚
在这里插入图片描述

将HCLK设置为最大频率72MHz
在这里插入图片描述

2.配置TIM

在这里插入图片描述

Internal Clock(内部时钟)
Prtscaler (定时器分频系数) : 71
Counter Mode(计数模式) Up(向上计数模式)
Counter Period(自动重装载值) : 999
CKD(时钟分频因子) :No Division (不分频 )
auto-reload-preload(自动重装载) : Enable (使能)

在这里插入图片描述
勾选update interrupt(更新中断)

1. 定时器溢出时间计算公式:

在这里插入图片描述
Tout:中断溢出的时间
arr:自动重装载值
psc:定时器分频系数
Tclk:时钟频率

Tout = ((71+1)*(999+1))/72 us
Tout = ( 72 * 1000 ) / 72 us
1000us = 1ms
所以这里我们的定时时间为:1ms
也就是说单片机1ms进入一次定时器中断

2. 定时器计数模式:
  1. 向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
  2. 向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
  3. 向上/向下计数模式(中央对齐模式):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
    在这里插入图片描述
2. 计数时钟:
  1. 内部时钟(TIMx_CLK)
  2. 外部时钟模式1:外部捕捉比较引脚(TIx)
  3. 外部时钟模式2:外部引脚输入(TIMx_ETR)
  4. 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。

3.配置IO口

在这里插入图片描述
将PB0设置为:
低电平
Output模式
既不上拉也不下拉
响应速度低

4. 工程生成

在这里插入图片描述

在这里插入图片描述
工程管理依旧是这几个选项,然后GENERATE CODE,STM32CubeMX部分完成。



MDK 5部分

  • HAL_TIM_IRQHandler(&htim1);//定时器中断处理函数
    此函数的作用是判断中断是否正常,是哪一类定时器中断(溢出中断/捕获中断/PWM中断…),然后进入相应的中断回调函数
  • void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定时器溢出中断回调函数
    定时器中断时,每进行完一个中断,并不会立刻退出,而是会进入到中断回调函数中

点开main.c在这里插入图片描述
在如图位置上添加

HAL_TIM_Base_Start_IT(&htim1);//开启定时器1

然后再tim.c文件中,添加

/* USER CODE BEGIN 0 */
uint16_t Tim_cnt = 0;  //定时器计数
/* USER CODE END 0 */

然后在tim.c文件中重写
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)函数

在这里插入图片描述

/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance == htim1.Instance) 
	{
		Tim_cnt++;
		if(Tim_cnt==500)  //0.5s进行一次下列代码
		{
			Tim_cnt=0;   //清0
			HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
		}
	}
}
/* USER CODE END 1 */

设一个全局变量,每进一次中断+1,因为1ms进入一次中断,所以当Tim_cnt=500的时候(即0.5s)写入我们需要运行的代码(不要忘记清0)



编译下载时需要选择相对应的下载器,勾选以下
在这里插入图片描述
运行即可


本期工程文档——>Gitee

在这里插入图片描述

### STM32 HAL定时器溢出中断的判断方法 在STM32 HAL中,当使用定时器功能时,可以通过配置定时器的基础模式并启用中断来检测定时器溢出事件。具体来说,`HAL_TIM_Base_Start_IT()` 函数用于启动定时器的同时开启其更新事件中断[^2]。一旦定时器计数值达到设定的最大值(即发生溢出),就会触发中断,并调用 `HAL_TIM_PeriodElapsedCallback()` 中断回调函数。 以下是详细的实现方式: #### 配置定时器基础模式 为了使能定时器溢出中断,需先通过初始化结构体配置定时器的相关参数,例如预分频系数和自动重装载值。这些参数决定了定时器的时间间隔以及何时触发溢出中断。之后调用 `HAL_TIM_Base_Init()` 初始化定时器硬件资源[^1]。 #### 启动定时器并允许中断 调用 `HAL_TIM_Base_Start_IT(&htimX)` 来激活定时器及其关联的更新事件中断。此操作会在 NVIC(嵌套向量中断控制器)中注册对应的中断优先级并向 CPU 请求响应。 #### 实现中断回调函数 每当定时器产生溢出事件时,程序会跳转至用户定义好的 `HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)` 回调函数执行特定逻辑处理[^4]。在此函数内部可以依据传入指针变量 `htim->Instance` 或者直接比较全局句柄地址确认当前正在运行的是哪个具体的定时器实例[^3]。 下面是一个简单的例子展示如何利用上述机制控制 LED 的亮灭状态切换: ```c // 假设已经完成了必要的 GPIO 和 TIMx 初始化工作 volatile uint8_t toggleFlag = 0; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if(htim == (&htim2)){ static uint16_t counter = 0; // 每次进入中断增加计数器直到满足条件才改变输出 if(++counter >= 100){ counter = 0; // 反转标志位从而交替点亮/熄灭LED灯泡 TOGGLE_LED(); } } } ``` 以上代码片段展示了基于每秒触发一百次左右频率下对指定端口上的外接设备进行周期性操控的应用场景之一。 ### 注意事项 - 确保正确设置了定时器的工作模式、时钟源以及其他相关属性以便获得预期的行为表现。 - 如果项目中有多个独立工作的定时单元,则需要分别编写各自的分支语句加以区分管理各自的任务流程。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值