STM32 HAL library delay function HAL_Delay analysis

The HAL library provides a delay function, but it can only implement a simple millisecond-level delay, and does not implement a us-level delay.
Below we list the functions related to HAL library implementation delay. The first is the function configuration function:

//调用 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)
{
...//此处省略函数定义
}

The above three functions are actually open to the main HAL_InitTick function called by HAL. This function will be called in the HAL library initialization function HAL_Init.
This function configures the Systick timer to interrupt every 1ms by indirectly calling the SysTick_Config function, and never stops.
Next, let's take a look at the logic control code of delay:

//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)
{
}
}

The implementation of the delay function in the HAL library is very simple. First, a 32-bit global variable uwTick is defined. In the Systick interrupt service function SysTick_Handler, the uwTick value is continuously increased by calling HAL_IncTick, that is, it is increased by 1 every 1ms.
The HAL_Delay function first records the current uwTick value after entering the function, and then continuously reads the current uwTick value in the loop, and performs the subtraction operation. The result is the delay in milliseconds. The whole logic is very simple and very clear.

Published 7 original articles · praised 7 · visits 56

Guess you like

Origin blog.csdn.net/a1347563271/article/details/105474024