STM32 HAL 库延时函数 HAL_Delay 解析

Rohana ·
更新时间:2024-09-21
· 579 次阅读

HAL 库有提供延时函数,只不过它只能实现简单的毫秒级别延时,没有实现 us 级别延时。
下面我们列出HAL 库实现延时相关的函数。首先是功能配置函数:

//调用 HAL_SYSTICK_Config 函数配置每隔 1ms 中断一次 __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { /* 配置系统在 1ms 的时间基础上有中断*/ if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) { return HAL_ERROR; } /* 配置 SysTick IRQ 优先级*/ if (TickPriority < (1UL << __NVIC_PRIO_BITS)) { HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); uwTickPrio = TickPriority; } else { return HAL_ERROR; } return HAL_OK; } //HAL 库的 SYSTICK 配置函数:文件 stm32f1xx_hal_context.c 中定义 uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) { return SysTick_Config(TicksNumb); } //内核的 Systick 配置函数,配置每隔 ticks 个 systick 周期中断一次 //文件 core_cm3.h 中 __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { ...//此处省略函数定义 }

上面三个函数,实际上开放给 HAL 调用的主要HAL_InitTick 函数,该函数在 HAL 库初始化函数 HAL_Init 中会被调用。
该函数通过间接调用 SysTick_Config 函数配置 Systick 定时器每隔 1ms 中断一次,永不停歇。
接下来我们来看看延时的逻辑控制代码:

//Systick 中断服务函数 void SysTick_Handler(void) { HAL_IncTick(); } //下面代码均在文件 stm32l0xx_hal.c 中 static __IO uint32_t uwTick; //定义计数全局变量 __weak void HAL_IncTick(void) { uwTick += uwTickFreq; } __weak uint32_t HAL_GetTick(void) //获取全局变量 uwTick 的值 { return uwTick; } //开放的 HAL 延时函数,延时 Delay 毫秒 __weak void HAL_Delay(__IO uint32_t Delay) { uint32_t tickstart = HAL_GetTick(); uint32_t wait = Delay; if (wait < HAL_MAX_DELAY) { wait += (uint32_t)(uwTickFreq); } while ((HAL_GetTick() - tickstart) < wait) { } }

HAL 库实现延时功能非常简单,首先定义了一个 32 位全局变量 uwTick,在 Systick 中断服务函数 SysTick_Handler 中通过调用 HAL_IncTick 实现 uwTick 值不断增加,也就是每隔 1ms增加 1。
而 HAL_Delay 函数在进入函数之后先记录当前 uwTick 的值,然后不断在循环中读取uwTick 当前值,进行减运算,得出的就是延时的毫秒数,整个逻辑非常简单也非常清晰。


作者:吃醋蘸饺子叭



stm32 函数 hal delay

需要 登录 后方可回复, 如果你还没有账号请 注册新账号