C51精确延时程序_第1页
C51精确延时程序_第2页
C51精确延时程序_第3页
C51精确延时程序_第4页
C51精确延时程序_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C51精确延时程序默认分类2008-05-2621:08:54阅读77评论0字号:大中小订阅有个好帖,从精度考虑,它得研究结果是:voiddelay2(unsignedchari)while(-i);为最佳方法分析:假设外挂12M(之后都是在这基础上讨论)我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay2(0):延时518us518-2*256=6delay2(1):延时7us(原帖写5us是错的,A_A)delay2(10):延时25us25-20=5delay2(20):延时45us45-40=5delay2(100):延时205us205-200=5delay2(

2、200):延时405us405-400=5见上可得可调度为2us,而最大误差为6us精度是很高了!但这个程序的最大延时是为518us显然不能满足实际需要,因为很多时候需要延迟比较长的时间那么,接下来讨论将t分配为两个字节,即uint型的时候,会出现什么情况voiddelay8(uintt)while(-t);我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay8(0):延时524551us524551-8*65536=263delay8(1):延时15usdelay8(10):延时85us85-80=5delay8(100):延时806us806-800=6delay8(1

3、000):延时8009us8009-8000=9delay8(10000):延时80045us80045-8000=45delay8(65535):延时524542us524542-524280=262如果把这个程序的可调度看为8us,那么最大误差为263us,但这个延时程序还是不能满足要求的,因为延时最大为524.551ms那么用ulongt呢?一定很恐怖,不用看编译后的汇编代码了那么如何得到比较小的可调度,可调范围大,并占用比较少得RAM呢?请看下面的程序:/*程序名称:50us延时注意事项:基于1MIPS,AT89系列对应12M晶振,W77W78系列对应3M晶振例子提示:调用delay_

4、50us(20),得到1ms延时全局变量:无返回:无*/voiddelay_50us(uintt)ucharj;for(;t0;t-)for(j=19;j0;j-)5我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay_50us(1):延时63us63-50=13delay_50us(10):延时513us503-500=13delay_50us(100):延时5013us5013-5000=13delay_50us(1000):延时50022us50022-50000=22赫赫,延时50ms,误差仅仅22us,作为C语言已经是可以接受了再说要求再精确的话,就算是用汇编也得

5、改用定时器了/*程序名称:50ms延时注意事项:基于1MIPS,AT89系列对应12M晶振,W77W78系列对应3M晶振例子提示:调用delay_50ms(20),得到1s延时全局变量:无返回:无*/voiddelay_50ms(uintt)uintj;/*可以在此加少许延时补偿,以祢补大数值传递时(如delay_50ms(1000)造成的误差,但付出的代价是造成传递小数值(delay_50ms(1)造成更大的误差因为实际应用更多时候是传递小数值,所以补建议加补偿!*/for(;t0;t-)for(j=6245;j0;j-)我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:dela

6、y_50ms(1):延时5001010usdelay_50ms(10):延时49998317usdelay_50ms(100):延时4999713287usdelay_50ms(1000):延时49970222.978ms赫赫,延时50s,误差仅仅2.978ms,可以接受!上面程序没有才用long,也没采用3层以上的循环,而是将延时分拆为两个程序以提高精度应该是比较好的做法了实现延时通常有两种方法:一种是硬件延时,要用到定时器计数器,这种方法可以提高的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。1使用定时器/计数器实现精确延时单片机系统一般常选用、或晶振。第一种更

7、容易产生各种标准的波特率,后两种的一个机器周期分别为卩和卩s便于精确延时。本程序中假设使用频率为的晶振。最长的延时时间可达6s若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用个机器周期)。在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,编写的中断服务程序编译后会自动加上、和语句,执行时占用了个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去

8、以达到最小误差的目的。2软件延时与时间计算在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。2.1短暂延时可以在文件中通过使用带语句的函数实现,定义一系列不同的延时函数,如、)等存放在一个自定义的文件中,需要时在主程序中直接调用。如延时卩的延时函数可编写如下:函数中共用了个语句,每个语句执行时间为卩s主函数调用时,先执行一个指令(卩),然后执行个语句(卩),最后执行了一个指令(卩),所以执行上述函数时共需要Hs可以把这一函数当作基本延时函数,在其他函数中调用,即嵌套调用4,以实现较长时间的延时;但需要注意,如在中直接调用次函数,得到的延时时

9、间将是卩s而不是Hs这是因为执行时,先执行了一次指令(卩),然后开始执行第一个)执行完最后一个时,直接返回到主程序。依此类推,如果是两层嵌套调用,如在中两次调用,则也要先执行一次指令(卩)然后执行两次函数(卩),所以,实际延时时间为Hs简言之,只有最内层的函数执行指令。该指令直接返回到上级函数或主函数。如在卩中直接调用次)此时的延时时间为IAs通过修改基本延时函数和适当的组合调用,上述方法可以实现不同时间的延时。在中嵌套汇编程序段实现延时在中通过预处理指令和可以嵌套汇编语言语句。用户编写的汇编语言紧跟在之后,在之前结束。如:汇编语言程序段延时函数可设置入口参数,可将参数定义为、或型。才根据参数

10、与返回值的传递规则,这时参数和函数返回值位于7、中。在应用时应注意以下几点:不允许嵌套使用;在程序的开头应加上预处理指令m在该指令之前只能有注释或其他预处理指令;当使用语句时,编译系统并不输出目标模块,而只输出汇编源文件;只能用小写字母,如果把写成大写,编译系统就把它作为普通变量;、和只能在函数内使用。将汇编语言与结合起来,充分发挥各自的优势,无疑是单片机开发人员的最佳选择。2.3使用示波器确定延时时间利用示波器来测定延时程序执行时间。方法如下:编写一个实现延时的函数,在该函数的开始置某个口线如为高电平,在函数的最后清为低电平。在主程序中循环调用该延时函数,通过示波器测量引脚上的高电平时间即可

11、确定延时函数的执行时间。方法如下:把接入示波器,运行上面的程序,可以看到输出的波形为周期是的方波。其中,高电平为s低电平为s即循环结构“;的执行时间为。通过改变循环次数,可得到不同时间的延时。当然,也可以不用循环而用别的语句实现延时。这里讨论的只是确定延时的方法。使用反汇编工具计算延时时间用中的反汇编工具计算延时时间,在反汇编窗口中可用源程序和汇编程序的混合代码或汇编代码显示目标应用程序。为了说明这种方法,还使用”。在程序中加入这一循环结构,首先选择,然后单击按钮进入程序调试窗口,最后打开d找出与这部分循环结构相对应的汇编代码,具体如下:可以看出,0一共条语句,分析语句可以发现并不是每条语句都

12、执行次。核心循环只有共条语句7总共个机器周期,第次循环先执行“R和“6”两条语句,需要2个机器周期,每循环1次需要8个机器周期,但最后次循环需要个机器周期。次核心循环语句消耗(X)个机器周期,当系统采用时,精度为卩s当采用循环体时,的值存放在中。相对应的汇编代码如下:循环语句执行的时间为()+个机器周期,即这种循环结构的延时精度为卩通过实验发现,如将改为l经过反汇编后得到如下代码:可以看出,这时代码只有1句,共占用2个机器周期,精度达到卩s循环体耗时y个机器周期;但这时应该注意,初始值不能为。注意:计算时间时还应加上函数调用和函数返回各2个机器周期时间。谈谈51单片机延时子程序延时程序在单片机

13、编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器周期和指令周期的区别,不知道延时程序指令的用法,本文就此问题从延时程序的基本概念、机器周期和指令周期的区别和联系、相关指令的用法等用图解法的形式详尽的回答读者我们知道程序设计是单片机开发最重要的工作,而程序在执行过程中常常需要完成延时的功能。例如在交通灯的控制程序中,需要控制红灯亮的时间持续30秒,就可以通过延时程序来完成。延时程序是如何实现的呢?下面让我们先来了解一些相关的概念。一、机器周期和指令周期1机器周期是指单片机完成一个基本操作所花费的时间,一般使用微秒来计量单片机的运行速度,51单片机的一个机器周期包括12个时

14、钟振荡周期,也就是说如果51单片机采用12MHz晶振,那么执行一个机器周期就只需要1ps;如果采用的是6MHz的晶振,那么执行一个机器周期就需要2pso2指令周期是指单片机执行一条指令所需要的时间,一般利用单片机的机器周期来计量指令周期。在51单片机里有单周期指令(执行这条指令只需一个机器周期),双周期指令(执行这条指令只需要两个机器周期),四周期指令(执行这条指令需要四个机器周期)。除了乘、除两条指令是四周期指令,其余均为单周期或双周期指令。也就是说,如果51单片机采用的是12MHz晶振,那么它执行一条指令一般只需12微秒的时间;如果采用的是6MH晶振,执行一条指令一般就需24微秒的时间。现

15、在的单片机有很多种型号,但在每个型号的单片机器件手册中都会详细说明执行各种指令所需的机器周期,了解以上概念后,那么可以依据单片机器件手册中的指令执行周期和单片机所用晶振频率来完成需要精确延时时间的延时程序。二、延时指令在单片机编程里面并没有真正的延时指令,从上面的概念中我们知道单片机每执行一条指令都需要一定的时间,所以要达到延时的效果,只须让单片机不断地执行没有具体实际意义的指令,从而达到了延时的效果。1数据传送指令MOV数据传送指令功能是将数据从一个地方复制、拷贝到另一个地方。女口:MOVR7,#80H;将数据80H送到寄存器R7,这时寄存器R7里面存放着80H,就单这条指令而言并没有任何实

16、际意义,而执行该指令则需要一个机器周期。2空操作指令NOP空操作指令功能只是让单片机执行没有意义的操作,消耗一个机器周期。3循环转移指令DJNZ循环转移指令功能是将第一个数进行减1并判断是否为0,不为0则转移到指定地点;为0则往下执行。女如:DJNZR7,KK;将寄存器R7的内容减1并判断寄存器R7里的内容减完1后是否为0,如果不为0则转移到地址标号为KK的地方;如果为0则执行下一条指令。这条指令需要2个机器周期。利用以上三条指令的组合就可以比较精确地编写出所需要的延时程序。三、1秒延时子程序、流程图及时间计算(以单片机晶振为12MHz为例,1个机器周期需要1ps)了解了以上的内容,现在让我们

17、来看看程序总共所需时间:1+10+2560+330240+660480+5120+20+2=998433ps1S在这里运行这段程序共需998433ps,还差1567ps才达到1S的,所以想要达到完美的1S延时,需要在返回指令RET前再添加一些指令让它把1567ps的延时完成。有兴趣的读者可以自己试着添加完成。最后补充一点,编写程序时一般将延时程序编写成独立的子程序,而所谓子程序也就是一个实现某个功能的小模块。这样在主程序中就可以方便地反复调用编写好的延时子程序。小提示:循环转移指令(DJNZ)除了可以给定地址标号让其跳转外,还可以将地址标号改成$,这样程序就跳回本指令执行。例如:DJNZR7,

18、$;R7内容减1不为0,则再次执行本指令;为0则往下执行,当R7的值改为10时,则执行完该条程序所需的时间为2*10=20ps051单片机汇编延时程序算法详解将以12MHZ晶振为例,详细讲解MCS-51单片机中汇编程序延时的精确算法。指令周期、机器周期与时钟周期指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。时钟周期:也称为振荡周期,一个时钟周期=晶振的倒数。MCS-51单片机的一个机器周期=6个状态周期=12个时钟周期。MCS-51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即1

19、2个时钟周期,所以一条单周期指令被执行所占时间为12*(1/12000000)=1ps0程序分析例150ms延时子程序:DEL:MOVR7,#200DEL1:MOVR6,#125DEL2:DJNZR6,DEL2DJNZR7,DEL1RET精确延时时间为:1+(1*200)+(2*125*200)+(2*200)+2=(2*125+3)*200+3=50603ps=50ms由整理出公式(只限上述写法)延时时间=(2*内循环+3)*外循环+3详解:DEL这个子程序共有五条指令,现在分别就每一条指令被执行的次数和所耗时间进行分析。第一句:MOVR7,#200在整个子程序中只被执行一次,且为单周期指令

20、,所以耗时1ps第二句:MOVR6,#125从看到只要R7-1不为0,就会返回到这句,共执行了R7次,共耗时200ps第三句:DJNZR6,DEL2只要R6-1不为0,就反复执行此句(内循环R6次),又受外循环R7控制,所以共执行R6*R7次,因是双周期指令,所以耗时2*R6*R7ps。例21秒延时子程序:DEL:MOVR7,#10DEL1:MOVR6,#200DEL2:MOVR5,#248DJNZR5,$DJNZR6,DEL2DJNZR7,DEL1RET对每条指令进行计算得出精确延时时间为:1+(1*10)+(1*200*10)+(2*248*200*10)+(2*200*10)+(2*10

21、)+2=(2*248+3)*200+3*10+3=998033ps=1s由整理得:延时时间=(2*第一层循环+3)*第二层循环+3*第三层循环+3此式适用三层循环以内的程序,也验证了例1中式(第三层循环相当于1)的成立。注意,要实现较长时间的延时,一般采用多重循环,有时会在程式序里加入NOP指令,这时公式不再适用,下面举例分析。例3仍以1秒延时为例DEL:MOVR7,#101指令周期1DEL1:MOVR6,#0FFH1指令周期10DEL2:MOVR5,#80H1指令周期255*10=2550KONG:NOP1指令周期128*255*10=326400DJNZR5,$2指令周期2*128*255

22、*10=652800DJNZR6,DEL22指令周期2*255*10=5110DJNZR7,DEL12指令周期2*10=20RET2延时时间=1+10+2550+326400+652800+5110+20+2=986893ps约为1s整理得:延时时间=(3*第一层循环+3)*第二层循环+3*第三层循环+3结论:针对初学者的困惑,对汇编程序的延时算法进行了分步讲解,并就几种不同写法分别总结出相应的计算公式,只要仔细阅读例1中的详解,并用例2、例3来加深理解,一定会掌握各种类型程序的算法并加以运用。单片机延时子程序1)延时为:20ms晶振12M1+(1+2*248+2)*4+1+1+1=20000

23、US=20MS用汇编.优点就是精确.缺点就是算有点复杂.DELAY20MS:MOVR7,#4D1:MOVR6,#248*DJNZR6,$DJNZR7,D1NOPNOPRET2)一些通过计算51汇编指令得出的软延时子程序*3涎时10uS*time10us:movr5,#05h;11usdjnzr5,$ret*3;延时50uS*time50us:movr5,#19h;51usdjnzr5,$ret*3;延时100uS*time100us:movr5,#31h;99.6us*djnzr5,$ret*3涎时200uS*time200us:;201usmovr5,#64hdjnzr5,$ret*;延时2

24、50uS*time250us:movr5,#7ch;249.6usdjnzr5,$ret*3;延时350uStime350us:movr5,#0afh;351us*time350us_1:djnzr5,time350us_1ret*涎时500uS*time350us:movr5,#0afh;351us*time350us:movr5,#0afh;351us*time500us:movtime500us_1:djnzr5,#0fah;501usr5,time500us_1time350us:movr5,#0afh;351us*time350us:movr5,#0afh;351us*ret*;延时

25、1mS*time1ms:movr5,#0fah;1001ustime1ms_1:nopnopdjnzr5,time1ms_1ret*3;延时2.5mStime2_5ms:movr5,#05h;2.496mstime2_5ms_1:movr6,#0f8h;497usdjnzr6,$djnzr5,time2_5ms_1ret*涎时10mS*time10ms:movr5,#14h;10.262mstime10ms_1:movr6,#0ffh;511usdjnzr6,$djnzr5,time10ms_1ret*;延时50mS*time50ms:movr5,#63h;49.996mstime50ms_1

26、:movr6,#0fbh;503usdjnzr6,$djnzr5,time50ms_1*ret*;延时100mS*time100ms:movr5,#0c3h;100.036mstime100ms_1:movr6,#0ffh;511usdjnzr6,$djnzr5,time100ms_1ret*;延时200mS*time200ms:movr5,#02h;250.351mstime200ms_1:movr6,#0f4h;125.173mstime200ms_2:movr7,#0ffh;511usdjnzr7,$djnzr6,time200ms_2djnzr5,time200ms_1ret3)涎时5

27、00mS*time500ms:time500ms_1:time500ms_2:djnzdjnzmovr5,#04hmovr6,#0f4hmovr7,#0ffhr7,$r6,time500ms_2;500.701ms;125.173ms;511us3)3)djnzr5,time500ms_1ret*涎时1S*time1s:movr5,#08h;1001.401mstime1s_1:movr6,#0f4h;125.173mstime1s_2:r7,#0ffh;511us12M晶振djnzr7,$djnzr6,time1s_2djnzr5,time1s_1retmov机器周期为1USNOP为单周期指

28、令JNZ为双周期指令.3)3);晶振12MHZ,延时1秒DELAY:MOV72H,#100LOOP3:MOV71H,#100LOOP1:MOV70H,#47LOOP0:DJNZ70H,LOOP0NOPDJNZ71H,LOOP1MOV70H,#46LOOP2:DJNZ70H,LOOP2NOPDJNZ72H,LOOP3MOV70H,#48LOOP4:DJNZ70H,LOOP44)涎时1分钟子程序,F=6MHz;程序已测过,延时时间60,000,000.0uSdelay60s:movr3,#228movr2,#253movr1,#219loop1:djnzr1,$djnzr2,loop1djnzr3,loop1nopret5)计算机反复执行一段程序以达到延时的目的称为软件延时,单片机程序中经常需要短时间的延时,但是相当一部分人对延时程序很模糊,对延时程序的算法不够了解,在这里我以12MH

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论