用汇编语言写可以精确计算,但有时想拼出整数的ms或10ms也不容易,计算方法如下图说明:
而C语言靠经验和实验得来的,如下面程序
如果不准(与晶振频率有关),调K的值,,软件仿真查看,直到大致准确,想更精确用定时器
void delay(unsigned char i) //延时程序
{
unsigned char i,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
c语言定义延时函数主要通过无意义指令的执行来达到延时的目的。下面给出一个经典的延时函数。
// 定义一个延时xms毫秒的延时函数
void delay(unsigned int xms) // xms代表需要延时的毫秒数
{
unsigned int x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}
你是用的uvision吧?我用的uvision4,把程序编好运行,然后进行调试(在此要设置两个断点就是一个在Delay延时函数之前,一个断点设在延时之后),然后你会在左边register栏会看见一个 sec:000014182 这个就是软件运行到断点处所用时间,然后再运行一次(这次就是运行完延时函数所用时间)。你把两次的时间做差值就是延时函数延时时间。再附图两张。
如果采用12mhz的晶振,一条语句运行一次约为1us,你这个函数延时应该是zms,delay(10)就是10
ms,不是很精确。
如果要写精确的延时函数,就要采用单片机中的定时器,很多单片机的书中都有讲到,可以去查相关资料。单片机中做延时,如果是时间比较短的情况,和单片机的机器周期时间,或单片机运行单个命令的时间是同一个单位时间的话,那么用循环运行一些没有动作的命令来延时,算每个命令的时间是多少,循环了多少次,那延时时间就可以算出来的了。
另外一种延时,时间相对机器周期的单位时间来说比较大,好像要MS,S 以上,那么可以用单片机的定时器来做,那就比较准确的时间的了,
定义一个延时xms毫秒的延时函数
void delay(unsigned int xms) // xms代表需要延时的毫秒数
{
unsigned int x,y;
for(x=xms;x》0;x--)
for(y=110;y》0;y--);
}
使用:
void Delay10us(uchar Ms)
{
uchar data i;
for(;Ms》0;Ms--)
for(i=26;i》0;i--);
}
i=[(延时值-175)12/Ms-15]/4
扩展资料1、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。
2、在延时子程序设计时,采用dowhile,结构做循环体要比for结构做循环体好。
3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。
;晶振24MDELAY1s: ;子程序
mov A,R4
jz enddelay
MOV R5,#10H ; ∵ 1s=200000005us
MOV R6,#43H ; ∴ 2000000/2=1000000
MOV R7,#40H ; 1000000用16进制表示为: 0f4240
; 所以 R5=0fH+1=10H
; R6=042H+1=043H
; R7=40H
loop: DJNZ R7,$ ; 延时时间≈2×[(R5-1)×256+R6-1]×256+R7
DJNZ R6,loop ; 当R5、R6等于0,相当于256参与运算
DJNZ R5,loop ; 当R5、R6等于0,相当于256参与运算
DJNZ R4,DELAY1s
enddelay: RET
上面是延时子程序,基础延时是1s,调用前给R4赋值,R4的值就是延时的秒数,比如:
mov R4,#3 ;表示延时3秒
lcall DELAY1s
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)