当前位置:首页 > 单片机 > 单片机
[导读]前段时间在编写延时程序时遇到了个定时器计数器回绕的问题,也就是计数器达到最大值后溢出,想找个简单的解决方案一直想不出来,函数如下

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

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 won't 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

* wouldn't 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回绕问题。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭