原创 C语言精确延时设计

2008-12-2 02:26 4153 10 12 分类: MCU/ 嵌入式
    在用C语言写程序时,初学者遇到的一个难题时精确延时程序的设计。我刚开始用C语言写程序时同样遇到了这个问题,后来参考了一些文章和实际设计后才知道了精确延时程序的设计。


    我现在就用两种方法来实现,一种是while()语句,另一种是for()语句,这两种语句均可产生汇编语句中的DJNZ语句,以12MHZ晶振为例(说明:在编写C程序时,变量尽量使用unsigned char,如满足不了才使用unsigned int):


    1.delay=99;while(--delay);


产生的汇编代码为:


000FH    MOV    08H,#63H


0012H    DJNZ    08H,0012H


这样产生的延时时间为:(99+1)×2us。最小延时时间为2us,若加上对delay赋值语句,则最小为4us。


 


    2.for(i=delay;i>0;i--);


产生的汇编代码同while()语句。


 


    下面来举例几个延时函数:


    一. 500ms延时子程序


void delay500ms(void)


{


    unsigned char i,j,k;


    for(i=15;i>0;i--)


    for(j=202;j>0;j--)


    for(k=81;k>0;k--);


}


产生的汇编代码:


C:0x0800    7F0F     MOV      R7,#0x0F


C:0x0802    7ECA     MOV      R6,#0xCA


C:0x0804    7D51     MOV      R5,#0x51


C:0x0806    DDFE     DJNZ     R5,C:0806


C:0x0808    DEFA     DJNZ     R6,C:0804


C:0x080A    DFF6     DJNZ     R7,C:0802


C:0x080C    22       RET     


计算分析:


程序共有三层循环


一层循环n:R5*2 = 81*2 = 162us                  DJNZ  2us


二层循环m:R6*(n+3) = 202*165 = 33330us          DJNZ  2us + R5赋值 1us = 3us


三层循环: R7*(m+3) = 15*33333 = 499995us        DJNZ  2us + R6赋值 1us = 3us


循环外:   5us            子程序调用 2us + 子程序返回 2us + R7赋值 1us  = 5us


延时总时间 = 三层循环 + 循环外 = 499995+5 = 500000us =500ms


计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5


 


    二. 200ms延时子程序


void delay200ms(void)


{


    unsigned char i,j,k;


    for(i=5;i>0;i--)


    for(j=132;j>0;j--)


    for(k=150;k>0;k--);


}


 


    三. 10ms延时子程序


void delay10ms(void)


{


    unsigned char i,j,k;


    for(i=5;i>0;i--)


    for(j=4;j>0;j--)


    for(k=248;k>0;k--);


}


 


    四. 1s延时子程序


void delay1s(void)


{


    unsigned char h,i,j,k;


    for(h=5;h>0;h--)


    for(i=4;i>0;i--)


    for(j=116;j>0;j--)


    for(k=214;k>0;k--);


}


以上的这先希望对大家有帮组,如有不足之处请指出,如有更好的方法也可以告诉我,大家一起分享。

文章评论2条评论)

登录后参与讨论

用户1329008 2011-12-29 08:40

谢谢诶,要写个精确延时子程序

用户1558275 2011-3-27 19:09

分析的很清楚和祥细。请问你是直接在KEIL中查看反汇编代码还是使用了其它的反汇编软件?为什么我在KEIL中看到的与上述不一样。
相关推荐阅读
用户6646 2010-06-09 16:44
Linux C中令人讨厌的段错误
作者:孙晓明,华清远见嵌入式学院讲师同学们在做练习的时候,编译完程序,执行的时候,有时会莫名的出现 “Segment fault”,即段错误,段错误是让许多C程序员都头疼的提示,因为对于这种模糊的提示...
用户6646 2010-06-09 13:06
VC6 显示行号 (无限制注册版)
make编译时出现错误, 会提示哪一行。可惜vc中不能显示行号,很是郁闷。这个插件可以显示行号,呵呵,很有用。VC显示行号插件说明-----------------------------------...
用户6646 2010-05-22 10:07
删除 nero search 的有效方法
不知道从什么时候开始,Nero多出来一个绑定的Nero Search,虽然可以不然它显示,可是他仍然会在后台占用资源。可以用以下方法解决:开始->运行,依次输入下列文字回车、确定即可(每次输一行...
用户6646 2010-04-03 08:46
2007年5月22日完成的全电控小电视(版本V2.0)
基础功能部分写了4000多行汇编,加上遥控红外部分达到了6000多行,大体介绍如下:1. 内置开关电源转换,11-37V供电;2. 全轻触操作,无机械可调器件,PWM调节亮度/色彩/背光;3.按钮有:...
用户6646 2010-03-17 09:41
三极管HFE与β的关系
hfe是三极管H参数,全称“共发射极低频小信号输出交流短路电流放大系数”,在等效四端网络中又叫“h21”。β是Ic与Ib函数关系的普遍表达式,尤其特指在晶体管基区中电流的分配关系。无论在教科书还是在应...
用户6646 2010-03-17 09:35
三极管饱和(2)
from:http://blog.ednchina.com/xcbao/10816/category.aspx本图片来自于<模拟集成电路的分析与设计>,用来表现三极管饱和时的carriers的分布。但...
我要评论
2
10
关闭 站长推荐上一条 /2 下一条