计数器的更新

计数器uwTick是在每次Systick中断中加一更新,此处配置Systick中断为每1ms中断一次。uwTickuint32_t类型,那么uwTick的最长计时为0xFFFFFFFF毫秒(约为49.7天),也就是说 uwTick 会在系统持续运行49天后溢出清零。

函数的实现

void HAL_Delay(__IO uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  while((HAL_GetTick() - tickstart) < Delay)
  {
  }
}

函数中计时的实现是通过循环读取uwTick 变量,比较差值来实现延迟,那么当计数器溢出时,此函数是否继续有效呢?

无符号整数的特性

我们知道:1 - (-1) = 2
将其转换为32位补码形式为:0x00000001 - 0xFFFFFFFF = 0x00000002
HAL_GetTick()0xFFFFFFFF时,正好将tickstart赋值。而当计数器溢出重新开始比较的时候,可以发现,上面的比较方式任然成立
此处需要注意HAL_GetTick()返回的无符号类型要与当前CPU的位数一致。
uint16_t a = 0xffff,在32位系统中参与运算,赋值到32位的寄存器变量中变为0x0000FFFF,运算的结果显然不正确。

linux 的解决方法

在linux中,jiffies溢出是通过time_after和time_before宏来解决

#define time_after(a,b)        \
    (typecheck(unsigned long, a) && \
     typecheck(unsigned long, b) && \
     ((long)(b) - (long)(a) < 0))
#define time_before(a,b)    time_after(b,a)

#define time_after_eq(a,b)    \
    (typecheck(unsigned long, a) && \
     typecheck(unsigned long, b) && \
     ((long)(a) - (long)(b) >= 0))
#define time_before_eq(a,b)    time_after_eq(b,a)

#define time_in_range(a,b,c) \
    (time_after_eq(a,b) && \
     time_before_eq(a,c))

/* Same as above, but does so with platform independent 64bit types.
 * These must be used when utilizing jiffies_64 (i.e. return value of
 * get_jiffies_64() */
#define time_after64(a,b)    \
    (typecheck(__u64, a) &&    \
     typecheck(__u64, b) && \
     ((__s64)(b) - (__s64)(a) < 0))
#define time_before64(a,b)    time_after64(b,a)

#define time_after_eq64(a,b)    \
    (typecheck(__u64, a) && \
     typecheck(__u64, b) && \
     ((__s64)(a) - (__s64)(b) >= 0))
#define time_before_eq64(a,b)    time_after_eq64(b,a)

其中需要保证ab均为无符号整数

---------------------
作者:贝特菲尔
来源:CSDN
原文:https://blog.csdn.net/sinat_20598829/article/details/77509086?spm=1001.2101.3001.6650.14&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-14-77509086-blog-53615060.pc_relevant_downloadblacklistv1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-14-77509086-blog-53615060.pc_relevant_downloadblacklistv1&utm_relevant_index=19
版权声明:本文为作者原创文章,转载请附上博文链接!

其它参考
关于STM32库中超时函数tick溢出的分析

jiffies溢出与时间先后比较-time_after,time_before

对 jiffies 溢出、回绕及 time_after 宏的理解
time_after方法对jiffies回绕问题的解决

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐