7天入门HAL库(2)
7天入门HAL库(2)
项目一:系统滴答(SysTick)控制LED闪烁

注意:下载程序后开发板没有现象,是由于芯片未复位
问题:HAL库默认每次都进Systick中断吗?
是的,HAL 库默认会让 SysTick 每次都进中断。
1. HAL 库的默认行为
在 STM32 的 HAL 库中,当你调用 HAL_Init() 时,它会调用 HAL_InitTick(TICK_INT_PRIORITY),这个函数会配置 SysTick 定时器并使能其中断。具体过程如下:
// 简化自 HAL_Init() 中的调用
HAL_InitTick(TICK_INT_PRIORITY);
在 HAL_InitTick() 内部(通常位于 stm32xx_hal.c),会调用类似下面的代码:
__HAL_RCC_SYSCFG_CLK_ENABLE();
// 设置 SysTick 重装载值,使周期为 1ms
// 假设系统时钟为 72MHz,则 SysTick_Config(72000)
SysTick_Config(ticks); // 这个函数会将 TICKINT 位置 1,使能中断
SysTick_Config() 是 CMSIS 提供的标准函数,它会:
- 设置
LOAD寄存器为重载值; - 清空
VAL寄存器; - 设置
CTRL寄存器的第 1 位TICKINT = 1(使能中断); - 设置
CTRL寄存器的第 2 位CLKSOURCE = 1(通常使用内核时钟); - 使能计数器(
CTRL的 ENABLE 位 = 1); - 设置 SysTick 的中断优先级(通过
NVIC_SetPriority)。
因此,HAL 库默认开启了 SysTick 中断,每隔 1ms 就会进入 SysTick_Handler 中断服务函数。
2. 你的代码中的验证
在你的 SysTick_Handler 中:
HAL_IncTick()是 HAL 库用来维护系统时间基准(uwTick全局变量)的函数,每次中断都会被调用。- 你额外添加了一个静态计数器,每 500 次中断(即 500ms)翻转一次 LED。
这正好说明了 HAL 库默认的 1ms 中断频率:每 1ms 进一次中断,你的计数器累加到 500 时执行一次 LED 翻转。
3. 如果不想让 SysTick 进中断怎么办?
虽然 HAL 库默认开启中断,但在某些特殊场景(如低功耗、需要自己完全控制定时器),你可以:
-
在调用
HAL_Init()之后,手动清除TICKINT位:SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;但这样做会导致
HAL_Delay()、HAL_GetTick()等函数失效,因为它们依赖每 1ms 的中断来更新uwTick。 -
不使用 HAL 的 SysTick 中断,改用其他定时器:
可以通过HAL_InitTick()的弱定义函数,替换为其他定时器中断来提供时间基准。 -
在 CubeMX 中,虽然默认会生成 SysTick 中断的代码,但你可以通过修改
stm32xx_hal_conf.h或直接注释相关初始化来避免。
4. 总结
| 项目 | HAL 库默认行为 |
|---|---|
| SysTick 是否使能 | 是(通过 HAL_Init() 自动配置) |
| TICKINT 位 | 1(每次溢出都产生中断) |
| 中断频率 | 1ms(由系统时钟和重装载值决定) |
| 中断服务函数 | SysTick_Handler(在 stm32xx_it.c 中实现,并调用了 HAL_IncTick()) |
所以,在绝大多数 HAL 工程中,SysTick 默认是每次都进中断的,这正是你看到的现象。如果你需要改变这一行为,需要主动修改初始化代码。

浙公网安备 33010602011771号