原创 89C51软件延迟时间计算分析

2008-9-29 20:03 4886 6 8 分类: MCU/ 嵌入式

https://static.assets-stash.eet-china.com/album/old-resources/2008/9/29/29825a26-88a1-47de-8bbb-9a88564268b7.rarC51软件延迟时间计算分析


以下是测试实验:



★其实用for()循环就可以实验C51精确定时没有必要用while()?
? 有时候for()比while()好,但是又有时候相反(*^_^*)

只可惜不能传递参数!!!
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--);
}


▲实验记录:
i=5,j=132,k=150
0.000 389 00
0.200 391 00 0.200 002 00
(1+1)+[(2*150+1+2)*132+1+2]*5+2+1+2=200 002 us


▲产生的汇编代码为:
?
? ; FUNCTION delay (BEGIN)
;---- Variable 'i' assigned to Register 'R7' ----
0000 7F05 MOV R7,#05H 1'
0002 ?C0001:
;---- Variable 'j' assigned to Register 'R6' ----
0002 7E84 MOV R6,#084H 1'
0004 ?C0004:
;---- Variable 'k' assigned to Register 'R5' ----
0004 7D96 MOV R5,#096H 1'
0006 ?C0007:
0006 DDFE DJNZ R5,?C0007 2'
0008 ?C0006:
0008 DEFA DJNZ R6,?C0004 2'
000A ?C0003:
000A DFF6 DJNZ R7,?C0001 2'
000C ?C0010:
000C 22 RET 2'
? ; FUNCTION delay (END)


▲延迟时间计算:
?Delay_Time=[(2k+1+2)*j+1+2]*i+2+1+2
?即:?
?【Delay_Time=[(2k+3)*j+3]*i+5】



▲程序代码:
void delay__ms(void) //x,y,z位固定值,故不能接受参数
{
?unsigned char i,j,k;
?for(i=x;i>0;i--)
?for(j=y;j>0;j--)
?for(k=z;k>0;k--);
}
【Delay_Time=[(2z+3)*y+3]*x+5】


——————————————————————————-


〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
File: 关于while(--n)的优化设计 〓
Time: 12:25-9:56 8:02- 〓
Date: 08-7-26-27 〓
Note: MOV Direct,#Data 为两个机器周期 〓
?MOV Rn,Direct 为两个机器周期 〓
〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

▲测试代码:
void delay_us(unsigned char)
{
?while(--n);
}

▲测试记录:
n=1
0.000 398 00
0.000 407 00
0.000 415 00 0.000 008 00
1+2+2*1+2+1=8

n=2
0.000 400 00
0.000 411 00
0.000 421 00 0.000 010 00
1+2+2*2+2+1=10


n=3
0.000 402 00
0.000 415 00
0.000 427 00 0.000 012 00
1+2+2*3+2+1=12

n=255
0.000 906 00
0.001 423 00
0.001 939 00 0.000 516 00
1+2+2*255+2+1=516


▲Keil C编译成汇编代码:
MOV 0x80,#00H
MOV R7,#255 1'
LCALL delay_us 2'
delay_us:
?DJNZ R7,$ 2' 2*255
?RET 2'


▲测试结论:
延迟时间=1+2+2*n+2
即Time=2*n+5 误差:-1us

当n=255时,Time_Max=2*255+5=515 us



▲软件改进:
延迟时间Time=2*n+6 误差:0us
void delay_us(unsigned char)
{
?while(--n);
?_nop_();
}

Delay_Max=516 us
Delay_Min=8 us
?

▲改进后测试:
n=100
0.000 907 00
0.001 425 00
0.001 942 00 0.000 517 00
2*255+6+1=517 零误差



▲双重循环▲
void delay(unsigned char n)
{
?do{unsigned char m="47";while(--m);}while(--n);
}

n=10
0.001 376 00
0.002 363 00
0.003 349 00 0.000 986 00
1+1+2+(47*2+2)*10+10*2+2=986

n=5
0.000 886 00
0.001 383 00
0.001 879 00 0.000 496 00
1+1+2+(47*2+2)*5+5*2+2=496



▲得出结论:
延迟时间: Time="1"+1+2+(m*2+2)*n+n*2+2
? 由于MOV P1,A 1'
? 【即: Time=(m*2+2)*n+n*2+5】


▲结论验证:
n=20,则Time=(47*2+2)*20+20*2+6=1966

n=20
0.002 356 00
0.004 323 00
0.006 289 00 0.001 966 00 OK!验证通过



▲双重循环程序C51代码:

void delay(unsigned char m, unsigned char n)
{
?unsigned char tempm,tempn=n;
?do{tempm=m;while(--tempm);}while(--tempn);
}



▲生成的A51代码为:
? ; FUNCTION _delay (BEGIN)
;---- Variable 'n' assigned to Register 'R5' ----
;---- Variable 'm' assigned to Register 'R7' ----
;---- Variable 'tempn' assigned to Register 'R5' ----
0000 ?C0003:
;---- Variable 'tempm' assigned to Register 'R6' ----
0000 AE07 MOV R6,0x07 1'
0002 ?C0004:
0002 DEFE DJNZ R6,?C0004 2'
0004 ?C0001:
0004 DDFA DJNZ R5,?C0003 2'
0006 22 RET 2'
? ; FUNCTION _delay (END)

? ; FUNCTION main (BEGIN)
0000 E4 CLR A 1'
0001 F580 MOV P0,A 1'
0003 7D0A MOV R5,#0AH 1'
0005 7F2F MOV R7,#02FH 1'
0007 120000 R LCALL _delay 2'
000A 7580FF MOV P0,#0FFH 2'
000D 22 RET 2'
? ; FUNCTION main (END)



▲测试记录:
m=47,n=10
0.000 389 00
0.001 377 00 0.000 988 00
1+1+1+1+2+(2*47+2)*10+10*2+2=988



▲实验结论:
延迟时间:
?Time=1+1+2+(2*m+2)*n+n*2+2
?即:【Time=(2*m+2)*n+n*2+6】



▲结论验证:
C51代码:
void delay(unsigned char m, unsigned char n)
{
?unsigned char tempm,tempn=n;
?do{tempm=m;while(--tempm);}while(--tempn);
}

令m=10,n=10
则Time=(20+2)*10+10*2+6=246

m=10,n=10
0.000 389 00
0.000 637 00 0.000 248 00
? 246+1+1=248 OK!测试通过



〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

★最后,实验总结:

【C51代码:】
void delay(unsigned char m, unsigned char n)
{
?unsigned char tempm,tempn=n;
?do{tempm=m;while(--tempm);}while(--tempn);
}
延迟时间为:【Time=(2*m+2)*n+n*2+6】

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓




——————————————————————————————————-


〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
File: 关于while(--n)的优化设计 〓
Time: 10:02 〓
Date: 08-7-29 〓
Note: MOV Direct,#Data 为两个机器周期 〓
?MOV Rn,Direct 为两个机器周期 〓
〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓




◆实验目的:
?用while实现三层循环,以达到更长的延迟时间.





◆测试代码:?
void delay(unsigned char x, unsigned char y, unsigned char z)
{
? unsigned char tempx,tempy,tempz=z;
? do{tempy=y;do{tempx=x;while(--tempx);}while(--tempy);}while(--tempz);
}




◆汇编代码:
ASSEMBLY LISTING OF GENERATED OBJECT CODE

? ; FUNCTION _delay (BEGIN)
;---- Variable 'x' assigned to Register 'R7' ----
;---- Variable 'z' assigned to Register 'R3' ----
;---- Variable 'y' assigned to Register 'R5' ----
;---- Variable 'tempz' assigned to Register 'R3' ----
0000 ?C0003:
;---- Variable 'tempy' assigned to Register 'R6' ----
0000 AE05 MOV R6,AR5(y) 2'
0002 ?C0006:
;---- Variable 'tempx' assigned to Register 'R4' ----
0002 AC07 MOV R4,AR7(x) 2'
0004 ?C0007:
0004 DCFE DJNZ R4,?C0007 2'
0006 ?C0004:
0006 DEFA DJNZ R6,?C0006 2'
0008 DBF6 DJNZ R3,?C0003 2'
000A 22 RET 2'
? ; FUNCTION _delay (END)

? ; FUNCTION main (BEGIN)
0000 E4 CLR A 1'
0001 F580 MOV P0,A 1'
0003 7B01 MOV R3,#01H 1'
0005 7D47 MOV R5,#047H 1'
0007 7F05 MOV R7,#05H 1'
0009 120000 R LCALL _delay 2'
000C 7580FF MOV P0,#0FFH 2'
000F 22 RET 2'
? ; FUNCTION main (END)





◆实验记录:
x=5,y=71,z=1
0.000 389 00
0.001 396 00 0.001 007 00
◆推论公式:
[(2*x+2)*y+2*y+2]*z+2*z+2+5+2=0.001 007 00




◆结论验证:
x=10,y=60,z=5
0.000 389 00
0.007 618 00 0.007 229 00
[(2*x+2)*y+2*y+2]*z+2*z+2+5+2=0.007 229 00 OK!测试通过



◆实验结论:
延迟时间为:Delay_Time=[(2*x+2)*y+2*y+2]*z+2*z+2+5+2
? =[(2*x+2)*y+2*y+2]*z+2*z+7
? =2*x*y*z+4*y*z+4*z+7

?即:【Delay_Time=2xyz+4yz+4z+7】



——————————————————————————————————-


呵呵~


就这么多咯~


还有汇编的源程序就不一一上传咯~


相互学习~



?

文章评论2条评论)

登录后参与讨论

用户149863 2009-5-9 09:15

12MHz 你也可以自己改程序

用户187755 2009-5-6 17:42

你的时钟频率是好多哦?
相关推荐阅读
用户149863 2010-05-22 22:40
LCD简单菜单显示
LCD简单菜单显示显示器件为图形型LCD12864(主控芯片KS0108)什么都不带!包含以下文件:LCD菜单(测试)LCD菜单(简单)LCD菜单(界面)LCD菜单(遥控器)希望对大家有用^_^感兴趣...
用户149863 2010-05-22 14:33
LCD12864(KS0108)液晶演示程序
LCD12864(KS0108)液晶演示程序LCD12864(KS0108)液晶演示程序视频: LCD12864演示程序(什么都不带的液晶) 视频演示网址:http://v.youku.com/v_s...
用户149863 2009-10-22 18:27
AVR代码
AVR单片机程序代码集,给需要的朋友们参考呵呵,都是自己一边学一边写的,一个一个字符从键盘敲出来的^_^希望对大家有用:-)呵呵,编译软件为:  ICCAVR V6.31A版本一共七个压缩包,呵呵,分...
用户149863 2009-10-22 15:18
VGA相关资料
VGA相关资料呵呵^_^如果你想玩的就请下载,有很多东西,都是花了我好几个夜晚才搜到的都是网上的资料:-)有兴趣的可以做做哦 包含以下文件夹:├─VGA+2051│  │  共享-----国外优秀电子...
用户149863 2009-10-10 14:46
PS/2 键盘与单片机
程序打包PS/2 键盘与单片机接口用LCD1602显示调试成功所以拿出来给大家分享,希望对大家有用,呵呵^_^用PS/2键盘做系统输入部分蛮方便的哦!可以使用Backspace/Esc/Tab/Cap...
用户149863 2009-08-17 19:54
AVR端口操作宏定义,便于移植
AVR端口操作宏定义头文件(ICCAVRIO.H),便于移植(ICCAVR编译环境) 压缩包里面有网上的相关资料,把它看完,相信你会更加了解红宏定义的^_^还有头文件在ICCAVRIO.H在Inclu...
我要评论
2
6
关闭 站长推荐上一条 /2 下一条