版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、有个好帖,从精度考虑,它得研究结果是: void delay2(unsigned char i) while(-i); 为最佳方法。分析:假设外挂12M(之后都是在这基础上讨论)我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay2(0):延时
2、518us 518-2*256=6delay2(1):延时7us(原帖写“5us”是错的,_)delay2(10):延时25us 25-20=5delay2(20):延时45us 45-40=5delay2(100):延时205us&
3、#160; 205-200=5delay2(200):延时405us 405-400=5见上可得可调度为2us,而最大误差为6us。精度是很高了!但这个程序的最大延时是为518us 显然不能满足实际需要,因为很多时候需要延迟比较长的时间。那么,接下来讨论将t分配为两个字节,即uint型的时候,会出现什么情况。void delay8(uint t) while
4、(-t);我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay8(0):延时524551us 524551-8*65536=263delay8(1):延时15usdelay8(10):延时85us 85-80=5 delay8(100):延时806us
5、; 806-800=6delay8(1000):延时8009us 8009-8000=9delay8(10000):延时80045us 80045-8000=45delay8(65535):延时524542us 524542-524280=262如果把这个程序的可调度看为8us,那么最大误差为263us,但这个延时程序
6、还是不能满足要求的,因为延时最大为524.551ms。那么用ulong t呢?一定很恐怖,不用看编译后的汇编代码了。那么如何得到比较小的可调度,可调范围大,并占用比较少得RAM呢?请看下面的程序:/*-程序名称:50us 延时注意事项:基于1MIPS,AT89系列对应12M晶振,W77、W78系列对应3M晶振例子提示:调用delay_50us(20),得到1ms延时全局变量:无返回: 无-*/void delay_50us(uint t) uchar j;
7、;for(;t>0;t-) for(j=19;j>0;j-) 我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay_50us(1):延时63us 63-50=13delay_50us(10):延时513us
8、0; 503-500=13 delay_50us(100):延时5013us 5013-5000=13delay_50us(1000):延时50022us 50022-50000=22赫赫,延时50ms,误差仅仅22us,作为C语言已经是可以接受了。再说要求再精确的话,就算是用汇编也得改用定时器了。/*-程序名称:50ms 延时注意事项:基于1MIPS,A
9、T89系列对应12M晶振,W77、W78系列对应3M晶振例子提示:调用delay_50ms(20),得到1s延时全局变量:无返回: 无-*/void delay_50ms(uint t) uint j; /*可以在此加少许延时补偿,以祢补大数值传递时(如delay_50ms(1000))造成的误差,但付出的代价是造成传递小数值(delay_50ms(1))造成更大的误差。因为实际应用更多时候是传递小数值,所以补建议加补偿!*/ for(;t>0;t-)
10、0; for(j=6245;j>0;j-) 我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay_50ms(1):延时50 010 10usdelay_50ms(10):延时499 983
11、17usdelay_50ms(100):延时4 999 713 287usdelay_50ms(1000):延时4 997 022 2.978ms赫赫,延时50s,误差仅仅2.978ms,可以接受!上面程序没有才用long,也没采用3层以上的循环,而是将延时分拆为两个程序以提高精度。应该是比较好的做法了· 问题内容:怎样用c语言写延时程序 · 原讨论链接: · 所属论坛:单片机/工控
12、 审核组:硬件/嵌入开发 · 提问者:zharrisl 解决者:hiflower · 感谢:icesnows shimd0604 sclarkca810619 flowercity icesnows tony1976 tony1976 eastred winp2003 hu_an_xiong 517517 hiflower tyj_3 · 关键字:函数 语句 硬件/嵌入开发 单片机 指令 汇编 void 循环 定时 周期 单片机/工控 · 答案: 要求是秒级的,同时说明下原理 - 空循环就行了 如while(i-)
13、;根据i的不同决定了延时长短 不过C的延时不是非常准确,你得根据反汇编,看汇编语句的数量和指令周期来计算时间 - 楼上的说得很对,用C语言编写单片机程序时,一般开发界面(如科尔KEILE)都提供了C - 汇编的代码转换,参照转换后的汇编语言就可以精确延时了 - 你可以数指令,然后按着MCU的MIPS算时间,结果应该比较精确:) - void mDelay(unsigned int Delay) /Delay = 1000 时间为1S
14、 unsigned int i; for(;Delay>0;Delay-) for(i=0;i<124;i+) - 数 一次循环的汇编指令,再乘以指令周期就知道一次循环的时间了啊,然后用1秒一除,不就知道循环次数了么 - 秒级的本
15、身精度要求就不高嘛 很容易控制啊 多套用几个for语句 或者在for语句里引用n个更低量级的(如100ms级)的延时函数即可 要精确就计算汇编代码执行长度 - to flowercity(Love Program,Love Living): 你的函数没有什么参考价值 延时时间和指令周期以及编译出来的代码类型有关系的 不是所谓 /Delay = 1000 时间为1S 就是一定的. 那只是针对你现在的系统. 用的晶振不同,执行CPU指令周期和时钟周期比率不同 结果都不同 - 秒级的,用定时器比较好吧。 - void waitms
16、(int i) char m; for( i i-) for(m = 203; m m-) _nop_(); _nop_(); _nop_(); _nop_();
17、60; _nop_(); _nop_(); _nop_(); 延时1ms的函数 时钟频率12MHz - 空操作,不过不好做到很准确 - 秒级延时,用指令的话,你要求延时的精确度是多少,高的话最好用定时器,而且你延时这么长,你的CPU不是就一直占用了,浪费呀。 - 与定时器中断服务程序配合实现延时。 unsigned int sleepTime; unsinged char inSleep&
18、#160;= 0; void sleepService(void) if (inSleep) sleepTime-; if (sleepTime = 0) inSleep = 0; void isr_timer(void) /假定定时器中断1ms 中断一次。 . sleepService(); . void
19、60;sleep(unsigned int ms) /延时子程序 sleepTime = ms; inSleep = 1; while(inSleep); void main(void) . sleep(1000); /延时 1秒 . - >>要求是秒级的 这么长的延时,单片机中一般采取不占CP
20、U时间的延时,利用定时器来实现延时, 如果非得用循环延时,在C中也通常嵌入汇编实现,这样误差比较小 在论坛上看到不少不错的延时程序,整理如下共同分享:精确延时计算公式:延时时间=(2*第一层循环+3)*第二层循环+3*第三层循环+5;延时5秒左右DELAY5S:PUSH 04H PUSH
21、; 05H PUSH 06H MOV
22、0; R4,#50 DELAY5S_0:MOV R5,#200
23、; DELAY5S_1:MOV R6,#245 DJNZ R6,$
24、160; DJNZ R5,DELAY5S_1 DJNZ R4,DELAY5S_0 &
25、#160; POP 06H
26、60; POP 05H POP 04H
27、0; RET
28、; ;513微秒延时程序DELAY: MOV R2,#0FEHDELAY1: DJNZ R2,DELAY1 RET ;10毫秒延时程序DL10MS: MOV R3,#14HDL10MS1:LCALL DELAY DJNZ
29、; R3,DL10MS1 RET;0.1s延时程序12mhzDELAY: MOV R6,#250DL1: MOV R7,#200DL2: DJNZ R6,DL2 DJNZ R7,DL1 RET;延时1046549微秒(12mhz);具体的计算公式是:;(r7*2+1)+2)*r6+1)+2)*r5+1+4 = (r7*2+3)*r6+3)*r5+5DEL : MOV R5,#08HDEL1: MOV R6,#0FFHDEL2: MOV R7,#
30、0FFH DJNZ R7,$ DJNZ R6,DEL2 DJNZ R5,DEL1 RET;1秒延时子程序是以12MHz晶振Delay1S:mov r1,#50del0: mov r2,#91 del1:&
31、#160; mov r3,#100 djnz r3,$ djnz r2,del1 djnz r1,del0 Ret;1秒延时子程序是以12MHz晶振为例算指令周期耗时KK: MOV R5,#10 ;
32、1指令周期1K1: MOV R6,#0FFH ;1指令周期10K2: MOV R7,#80H ;1指令周期256*10=2560K3: NOP ;1指令周期128*256*10=327680 DJNZ R7,K3 ;2指令周期2*128*256*10=655360 D
33、JNZ R6,K2 ;2指令周期2*256*10=5120 DJNZ R5,K1 ;2指令周期2*10=20 RET ;2指令周期21+10+2560+327680+655360+5120+20+2=990753;约等于1秒1秒=1000000微秒;这个算下来也只有0.998抄T_0: MOV R7,#10;D1:
34、 MOV R6,#200;D2: MOV R5,#248; DJNZ R5,$ DJNZ R6,D2; DJNZ R7,D1; RET ;这样算下来应该是1.000011秒T_0: MOV R7,#10;D1: MOV R6,#200;D2: NOP MOV R5,#248; DJNZ&
35、#160; R5,$ DJNZ R6,D2; DJNZ R7,D1; RETDELAY_2S: ;10MS(11.0592mhz) MOV R3,#200 JMP DELAY10MSDELAY_100MS: ;100MS(11.0592mhz) MOV R3,#10 JMP DELAY10MSDELAY_10MS: MOV R3,#1DELAY10MS:
36、 ;去抖动10MS(11.0592mhz) MOV R4,#20DELAY10MSA: MOV R5,#247 DJNZ R5,$ DJNZ R4,DELAY10MSA DJNZ R3,DELAY10MS RET DELAY_500MS: ;500500MS MOV R2,#208
37、0;JMP DELAY_MSDELAY_175MS: ;175MS MOV R2,#73 JMP DELAY_MSdelaY_120MS: ;120MS MOV R2,#50 JMP DELAY_MSdelay_60ms: ;60ms MOV R2,#25 JMP DELAY_MSdelay_30ms: ;30ms MOV R2,#12 JMP DELAY_MSDELAY_5MS: ;5MS
38、60;MOV R2,#2;=DELAY_MS: CALL DELAY2400 DJNZ R2,DELAY_MSRET;=DELAY2400: ;10x244+4=2447 /1.024=2390 MOV R0,#244 ;1DELAY24001: MUL AB ;4 MUL AB ;4 DJNZ R0,DELAY24001 ;2 RETDELAY: ;延时子程序(1秒)MOV R0,#0AHDELAY1: MOV R1,#00HDELAY2: MOV R
39、2,#0B2HDJNZ R2,$DJNZ R1,DELAY2DJNZ R0,DELAY1RETMOV R2,#10 ;延时1秒LCALL DELAYMOV R2,#50 ;延时5秒LCALL DELAYDELAY: ;延时子程序PUSH R2PUSH R1PUSH R0DELAY1: MOV R1,#00HDELAY2: MOV R0,#0B2HDJNZ R0,$DJNZ R1,DELAY2 ;延时 100 mSDJNZ R2,DELAY1POP R0POP R1POP R2RET 1:DEL: MOV R7,
40、#200 DEL1: MOV R6, #123 NOP
41、160; DEL2: DJNZ R6, DEL2 DJNZ R7, DEL1
42、0; RET是50.001ms 算法是:0.001ms+200*0.001ms+200*0.001ms+200*123*0.002ms+200*0.002ms;(123*2+4)*200+12: DEL: MOV R7, #200 DEL1: MOV R6, #123 DEL2:NOP DJNZ R6,DEL2 &
43、#160; DJNZ R7,DEL1RETD500MS: PUSH PSWSETB RS0MOV R7,#200D51: MOV R6,#250D52: NOPNOPNOPNOPDJNZ R6,D52DJNZ R7,D51POP PSWRET DELAY: ;延时1毫秒PUSH PSWSETB RS0MOV R7,#50D1: MOV R6,#10D2: DJNZ R6,$DJNZ R7,D1POP PSWRET ORG 0 LJMP
44、160; MAIN ORG 000BH LJMP CTC0 MAIN: MOV SP, #50H CLR E
45、A MOV TMOD, #01H MOV TH0,#3CH MOV TL0,#0B0H
46、; MOV R4, #10 SETB ET0 SETB EA SETB TR0
47、60; SJMP $ ; CTC0: MOV TH0, #3CH MOV TL0, #0B0H DJNZ R4, LP
48、 CPL P1.0 MOV R4, #10 LP: RETI END汇编延时程序算法详解来源:嵌入式技术网作者:姜会敏时间:2008-01-01发布人:林逸摘要 计算机反复执行一段程序以达到延时的目的称为软件延时,单片机应用程序中经
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度装饰装修工程安装合同
- 2024年工程材料供应与验收合同
- 公司员工检讨书
- 2024年度新能源发电设备采购与销售合同
- 2024年度W公司环保服务合同协议书
- 2024年建筑公司员工聘用合同
- 2024年度网络通讯工程安全文明施工管理协议
- 2024年大型油田勘探开发合作合同(海外)
- 2024年度某航空公司飞机采购合同
- 2024年度区块链应用合作协议
- 暖通工程师面试试题(含答案)
- 行政服务中心窗口工作人员手册
- 最新患者用药情况监测
- 试桩施工方案 (完整版)
- ESTIC-AU40使用说明书(中文100版)(共138页)
- 河北省2012土建定额说明及计算规则(含定额总说明)解读
- 中工商计算公式汇总.doc
- 深圳市建筑装饰工程消耗量标准(第三版)2003
- 《初中英语课堂教学学困生转化个案研究》开题报告
- 恒温箱PLC控制系统毕业设计
- 176033山西《装饰工程预算定额》定额说明及计算规则
评论
0/150
提交评论