系统方法详解
HAL 库提供了一组系统级函数,用于初始化、延时、获取系统时间以及错误处理。这些函数虽然简单,但在几乎每个项目中都会用到。
HAL_Init
HAL_StatusTypeDef HAL_Init(void);
功能
初始化 HAL 库,包括:
- 配置 Flash 预取取指和等待周期。
- 配置 NVIC 优先级分组为
NVIC_PRIORITYGROUP_4。 - 配置 SysTick 为 1 ms 中断,用于
HAL_Delay和HAL_GetTick。
示例
int main(void)
{
HAL_Init();
SystemClock_Config();
// ...
}
HAL_Init() 必须在所有 HAL 外设初始化之前调用,通常放在 main() 函数的最开始。
HAL_DeInit
HAL_StatusTypeDef HAL_DeInit(void);
功能
反初始化 HAL 库,把所有外设恢复到复位状态。在需要软件复位或低功耗场景中使用。
HAL_Delay
void HAL_Delay(uint32_t Delay);
参数拆解
HAL_Delay(500);
// │
// └── 延时毫秒数
功能
阻塞延时指定的毫秒数。
示例
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
HAL_Delay(500);
HAL_Delay 依赖 SysTick 中断。不能在中断服务函数中调用,除非 SysTick 优先级更高。否则会导致死循环。
HAL_GetTick
uint32_t HAL_GetTick(void);
功能
获取系统启动以来经过的毫秒数。该值在 SysTick 中断中递增。
示例
uint32_t start = HAL_GetTick();
while (HAL_GetTick() - start < 1000) {
// 非阻塞等待 1 秒
}
由于 HAL_GetTick 返回 uint32_t,在计算时间差时不需要担心溢出,因为无符号整数的减法会自动处理回绕。
HAL_GetTickPrio
uint32_t HAL_GetTickPrio(void);
功能
获取 SysTick 中断的优先级。
HAL_SetTickFreq
HAL_StatusTypeDef HAL_SetTickFreq(uint32_t Freq);
参数拆解
HAL_SetTickFreq(HAL_TICK_FREQ_1KHZ);
// │
// └── 滴答频率
功能
设置 SysTick 中断频率,默认是 1 kHz(1 ms)。
HAL_IncTick
void HAL_IncTick(void);
功能
递增系统滴答计数器。该函数在 SysTick 中断中被调用,一般不需要手动调用。
HAL_SuspendTick / HAL_ResumeTick
void HAL_SuspendTick(void);
void HAL_ResumeTick(void);
功能
HAL_SuspendTick:暂停 SysTick 中断,常用于进入低功耗模式前。HAL_ResumeTick:恢复 SysTick 中断。
Error_Handler
void Error_Handler(void);
功能
HAL 库在发生严重错误时调用的默认错误处理函数。通常由 STM32CubeMX 生成,实现为无限循环,并关闭中断。
默认实现
void Error_Handler(void)
{
__disable_irq();
while (1) {
// 可以在这里闪烁 LED 或输出调试信息
}
}
自定义建议
可以在 Error_Handler 中加入 LED 闪烁或串口输出,方便定位初始化失败的位置:
void Error_Handler(void)
{
__disable_irq();
while (1) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
for (volatile int i = 0; i < 500000; i++);
}
}
HAL_DBGMCU_EnableDBGSleepMode
void HAL_DBGMCU_EnableDBGSleepMode(void);
功能
使能调试器在 CPU 进入 Sleep 模式时保持连接。调试低功耗程序时常用。
完整示例:系统函数使用
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(1000);
uint32_t now = HAL_GetTick();
printf("System run time: %lu ms\r\n", now);
}
}