7天入门HAL库(2)

7天入门HAL库(2)

项目一:系统滴答(SysTick)控制LED闪烁

image-20260322222904849

注意:下载程序后开发板没有现象,是由于芯片未复位


问题: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 库默认开启中断,但在某些特殊场景(如低功耗、需要自己完全控制定时器),你可以:

  1. 在调用 HAL_Init() 之后,手动清除 TICKINT

    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
    

    但这样做会导致 HAL_Delay()HAL_GetTick() 等函数失效,因为它们依赖每 1ms 的中断来更新 uwTick

  2. 不使用 HAL 的 SysTick 中断,改用其他定时器
    可以通过 HAL_InitTick() 的弱定义函数,替换为其他定时器中断来提供时间基准。

  3. 在 CubeMX 中,虽然默认会生成 SysTick 中断的代码,但你可以通过修改 stm32xx_hal_conf.h 或直接注释相关初始化来避免


4. 总结

项目 HAL 库默认行为
SysTick 是否使能 是(通过 HAL_Init() 自动配置)
TICKINT 位 1(每次溢出都产生中断)
中断频率 1ms(由系统时钟和重装载值决定)
中断服务函数 SysTick_Handler(在 stm32xx_it.c 中实现,并调用了 HAL_IncTick()

所以,在绝大多数 HAL 工程中,SysTick 默认是每次都进中断的,这正是你看到的现象。如果你需要改变这一行为,需要主动修改初始化代码。

posted @ 2026-03-22 22:27  Q&25  阅读(14)  评论(0)    收藏  举报