STM32的官方库文件stm32f1xx_hal.c部分摘录如下
__IO uint32_t uwTick;
/**
* @brief This function is called to increment a global variable "uwTick"
* used as application time base.
* @note In the default implementation, this variable is incremented each 1ms
* in SysTick ISR.
* @note This function is declared as __weak to be overwritten in case of other
* implementations in user file.
* @retval None
*/
__weak void HAL_IncTick(void)
{
uwTick += uwTickFreq;
}
/**
* @brief Provides a tick value in millisecond.
* @note This function is declared as __weak to be overwritten in case of other
* implementations in user file.
* @retval tick value
*/
__weak uint32_t HAL_GetTick(void)
{
return uwTick;
}
/**
* @brief This function provides minimum delay (in milliseconds) based
* on variable incremented.
* @note In the default implementation , SysTick timer is the source of time base.
* It is used to generate interrupts at regular time intervals where uwTick
* is incremented.
* @note This function is declared as __weak to be overwritten in case of other
* implementations in user file.
* @param Delay specifies the delay time length, in milliseconds.
* @retval None
*/
__weak void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait)
{
}
}
如果工程中开启了systick功能,默认是1ms一个中断,每次 uwTick增加1,上述代码的uwTickFreq就等于1,具体可以查看底层的定义。
那么在HAL_Delay中,使用就是uwTick来计算延迟,但是uwTick是一个uint32_t的变量,会不会因为溢出,而导致延迟时间变化呢?
举例如下:
1)要延迟10ms,即Delay = 10(此处,wait有个初始判断+1,可以不用关注,延迟11ms,Delay = 11)
2)第一种情况,不存在uwTick溢出,调用HAL_Delay时,tickstart获取的tick假设是30000,然后当uwTick到30011时延迟结束
3)第二种情况,存在uwTick溢出,调用HAL_Delay时,tickstart获取的tick假设是65530,但是wait是11,那么当uwtick=65535+1,就会溢出uwtick = 0,此时计算uwtick-tickstart=-65530:二进制表示0000 0000 0000 0110,无符号十进制6,那么当uwtick=5(0000 0000 0000 0101)时,延时还是11ms(0000 0000 0000 1011),所以无符号的uwtick溢出并不会导致延迟错乱,此处差值不存在负数,要考虑好无符号数的计算方法
这个问题的主要依据是使用了计算机的原码,反码,补码的知识。可以参考如下链接,写的非常好
https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html