关于STM32库中超时函数tick溢出的分析

本文探讨了在STM32官方库中,当使用HAL_Delay进行延迟时,如何处理uwTick变量可能的溢出问题。通过举例说明,在无符号整数的溢出情况下,延迟时间不会因uwTick溢出而发生错误,关键在于理解无符号数的计算方式,特别是计算机原码、反码和补码的概念。

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

 

 

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值