您的位置 首页 元件

单片机嵌入式发生准确延时的一种办法

前段时间在编写延时程序时遇到了个定时器计数器回绕的问题,也就是计数器达到最大值后溢出,想找个简单的解决方案一直想不出来,函数如下:v…

前段时刻在编写延时程序时遇到了个定时器计数器缭绕的问题,也便是计数器到达最大值后溢出,想找个简略的处理方案一向想不出来,函数如下:

void Delay(Uint16 ms)

{

Uint16 currcnt;

currcnt = TCNT; //get current cnt register val

while(TCNT < currcnt+ms);

}

TCNT为硬件的寄存器值,在做单片机程序时,准确的延时很常用,也很便利,能够用一个定时器来完成准确延时,上面为完成原理,但遇到一个问题便是上面简略的

处理后有个计数器溢出缭绕的问题,运用变量能够处理但是感觉想找一个通用简略的办法一向没找到,忽然看到linux内核上关于时刻比较的代码,激动呀,问题的答案

有了,内核的人仍是很猛的,一句话搞定,我把小脑袋想破也没想出来,。

在linux编程中,常常运用jiffies作为时刻的衡量。一般都是运用unsigned long来保存jiffies的值,并用之比较时刻的先后顺序。

但是即使是unsigned long的位数现已比较大了,jiffies依然或许产生缭绕问题。

比方unsigned long a = jiffies; sleep(some time)。这时jiffies缭绕了,然后unsigned long b = jiffies。

因为jiffies缭绕,b本来是产生在a之后的事情,但是b的值却小于a。

这种状况下,假如仅仅简略比较b>a来判别b是否产生在a之后,无疑是过错的。

Linux内核为了处理jiffies的缭绕问题,供给了现成的宏,用于判别时刻的先后。今日就以time_after为例,看看它为什么能够应对jiffies的缭绕问题。

/*
* These inlines deal with timer wrapping correctly. You are
* strongly encouraged to use them
* 1. Because people otherwise forget
* 2. Because if the timer wrap changes in future you wont have to
* alter your driver code.
*
* time_after(a,b) returns true if the time a is after time b.
*
* Do this with “<0" and ">=0″ to only test the sign of the result. A
* good compiler would generate better code (and a really good compiler
* wouldnt care). Gcc is currently neither.
*/
#define time_after(a,b) \
(typecheck(unsigned long, a) && \
typecheck(unsigned long, b) && \
((long)(b) – (long)(a) < 0))

这个宏界说很简略,能够疏忽typecheck,其便是用于查看参数的类型是否正确。如这儿便是用于判别a和b是否为unsigned long类型。

最要害的便是((long)(b) – (long)(a) < 0)。

在抱负的状况下,时刻是能够不断增加的,后来的时刻值必定比前面的值大。所以b-a必定小于0。然后计算机的国际不是一个抱负的国际,

一切的值都有其位数约束的。在32位平台上,long的位数为32位。依照二进制补码的表明方法,从0到0x7fffffff的区间,值是逐步递加的。

从0x80000000到0xFFFFFFFF这个区间,值是逐步缩小的。

这就有4中状况:

1. a和b都在0到0x7FFFFFFF之间:

a若在b之后产生,则a的值大于b。那么(long)b-(long)a<0。

2. a和b都在0x80000000到0xFFFFFFFF之间:

a若在b之后产生,b为较大的负数,a为较小的负数,那么(long)b-(long)a<0。

3. b在0到0x7FFFFFFF之间,而a在0x80000000到0xFFFFFFFF之间:

a为负数。b-a,相当于b+(-a)。只需a与b之间的肯定差值小于或等于0x80000000,则b+(-a)依然为负数。

4. b在0x80000000到0xFFFFFFFF之间,而a在0到0x7FFFFFFF之间:

b为负数,b-a等于b+(-a)。同样在a与b之间的肯定差值小于或等于0x80000000,则b+(-a)依然为负数。

总结这四种状况,在a与b的肯定值相差不到0x80000000时,这个宏是正确的。而在运用jiffies作为时刻衡量和比较单位时,时刻差并不会太大。

所以这个time_after能够有用的防止jiffies缭绕问题。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/yuanjian/265962.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部