版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C51中精确的延时与计算的实现C51由于其可读性和可移植性很强,在单片机中得到广泛的应用,但在某些时候由于C51编写的程序对在有精确时间要求下,可能就得要用汇编语言来编写,但在C51是否也能实现时间的精确控制呢?答案是肯定的。在C51中要实现对时间的精确延时有以下几种方法其一:对于延时很短的,要求在us级的,采用“_nop_函数,这个函数相当汇编NOP旨令,延时几微秒,就插入个这样的函数。其二:对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。在选择C51中循环语句时,要注意以下几个问题第一、定义的C51中循环变量,尽量采用无符号字符型变量。第二、在FORW环语句中,尽量采用
2、变量减减来做循环。第三、在do,while,while语句中,循环体内变量也采用减减方法。这因为在C51编译器中,对不同的循环方法,采用不同的指令来完成的。下面举例说明:unsignedcharI;for(i=0;i<255;i+);unsignedcharI;for(i=255;i>0;i-);其中,第二个循环语句C51编译后,就用DJNZ指令来完成,相当于如下指令:MOV09H,00FFHLOOPDJNZ09H,LOOP指令相当简洁,也很好计算精确的延时时间。同样对do,while,while循环语句中,也是如此例:unsignedcharn;n=255;don-while(n
3、);或n=255;while(n)n-;这两个循环语句经过C51编译之后,形成DJN次完成的方法,故其精确时间的计算也很方便。其三:对于要求精确延时时间更长,这时就要采用循环嵌套的方法来实现,因此,循环嵌套的方法常用于达到ms级的延时。对于循环语句同样可以采用for,do,while,while结构来完成,每个循环体内的变量仍然采用无符号字符变量。unsignedchari,jfor(i=255;i>0;i-)for(j=255;j>0;j-);或unsignedchari,ji=255;doj=255;doj-while(j);i-;while(i);或unsignedchari
4、,ji=255;while(i)j=255;while(j)j-;i-;DJNZ指令嵌套实现循环的,由C51编译器用下面的指令组合来完成的R6,00FFHR6,LOOP1这三种方法都是用MOVR7,00FFHLOOP2MOVLOOP1DJNZDJNZR7,LOOP2这些指令的组合在汇编语言中采用DJNZ指令来做延时用,因此它的时间精确计算也是很简单,假上面变量i的初值为m变量j的初值为n,则总延时时间为:mx(nXT+T),其中T为DJNZ指令执行时间。同样对于更长时间的延时,可以采用多重循环来完成。只要在程序设计循环语句时注意以上几个问题。下面给出有关在C51中延时子程序设计时要注意的问题1
5、、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。2、在延时子程序设计时,采用do,while,结构做循环体要比for结构做循环体好。3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。unsignedchardelay(unsignedchari,unsignedcharj,unsignedchark)unsignedcharb,c;b=j;c=k;dododok-;while(k);k=c;j-;while(j);j=b;i-;while(i);这精确延时子程序就被C51编译为有下面的
6、指令组合完成delay延时子程序如下:MOVR6,05HMOVR4,03HC0012:DJNZR3,C0012MOVR3,04HDJNZR5,C0012MOVR5,06HDJNZR7,C0012RET假设参数变量i的初值为m,参数变量j的初值为n,参数变量k的初值为l,则总延时时间为:lx(nx(mxT+2T)+2T)+3T,其中T为DJNZ和MOV旨令执行的时间。当m=n=l时,精确延时为9T,最短;当m=n=l=256时,精确延时到16908803T,最长。采用软件定时的计算方法作者:不详文章来源:中国电子技术信息网点击数:更新时间:2003-3-7利用指令执行周期设定,以下为一段延时程序
7、:指令周期MOV1DJNZ2NOP1采用循环方式定时,有程序:MOVR5,#TIME2;周期1LOOP1:MOVR6,#TIME1;1LOOP2:NOP;1NOP;1DJNZR6,LOOP2;2DJNZR5,LOOP1;2定时数=(TIME1*4+2+1)*TIM2*2+4有个好帖,从精度考虑,它得研究结果是:voiddelay2(unsignedchari)(while(-i);)为最佳方法。分析:假设外挂12M(之后都是在这基础上讨论)我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay2(0):延日518us518-2*256=6delay2(1):延日77us(原帖
8、写5us是错的,A_A)delay2(10):延时25us25-20=5delay2(20):延时45us45-40=5delay2(100):延时205us205-200=5delay2(200):延时405us405-400=5见上可得可调度为2us,而最大误差为6us。精度是很高了!但这个程序的最大延时是为518us显然不能满足实际需要,因为很多时候需要延迟比较长的时间。那么,接下来讨论将t分配为两个字节,即uint型的时候,会出现什么情况。voiddelay8(uintt)(while(-t);)我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay8(0):延日52
9、4551us524551-8*65536=263delay8(1):延日115usdelay8(10):延时85us85-80=5delay8(100):延时806us806-800=6delay8(1000):延日8009us8009-8000=9delay8(10000):延时80045us80045-8000=45delay8(65535):延时524542us524542-524280=262如果把这个程序的可调度看为8us,那么最大误差为263us,但这个延时程序还是不能满足要求的,因为延时最大为524.551ms。那么用ulongt呢?一定很恐怖,不用看编译后的汇编代码了。那么如何
10、得到比较小的可调度,可调范围大,并占用比较少得RAM?请看下面的程序:/*程序名称:50us延时注意事项:基于1MIPS,AT89系列对应12M晶振,W77W78系歹呕应3M晶振例子提示:调用delay_50us(20),得到1ms延时全局变量:无返回:无*/voiddelay_50us(uintt)ucharj;for(;t>0;t-)for(j=19;j>0;j-);我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay_50us(1):延时63us63-50=13delay_50us(10):延日513us503-500=13delay_50us(100):
11、延时5013us5013-5000=13delay_50us(1000):延时50022us50022-50000=22赫赫,延时50ms,误差仅仅22us,作为C语言已经是可以接受了。再说要求再精确的话,就算是用汇编也得改用定时器了。/*程序名称:50ms延时注意事项:基于1MIPS,AT89系列对应12M晶振,W77W78系歹呕应3M晶振例子提示:调用delay_50ms(20),得到1s延时全局变量:无返回:无*/voiddelay_50ms(uintt)uintj;delay_50ms(1000)造成的误差,/*可以在此加少许延时补偿,以祢补大数值传递时(如但付出的代价是造成传递小数值
12、(delay_50ms(1)造成更大的误差。因为实际应用更多时候是传递小数值,所以补建议加补偿!*/for(;t>0;t-)for(j=6245;j>0;j-)J我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:delay_50ms:延时5001010usdelay_50ms(10):延日49998317usdelay_50ms(100):延时4999713287usdelay_50ms(1000):延时49970222.978ms赫赫,延时50s,误差仅仅2.978ms,可以接受!上面程序没有才用long,也没采用3层以上的循环,而是将延时分拆为两个程序以提高精度。应
13、该是比较好的做法了KeilC51程序设计中几种精确延时方法(转载)文章发表于:2009-03-0615:59摘要实际的单片机应用系统开发过程中,由于程序功能的需要,经常编写各种延时程序,延时时间从数微秒到数秒不等,对于许多C51开发者特别是初学者编制非常精确的延时程序有一定难度。本文从实际应用出发,讨论几种实用的编制精确延时程序和计算程序执行时间的方法,并给出各种方法使用的详细步骤,以便读者能够很好地掌握理解。关键词KeilC51精确延时程序执行时间引言单片机因具有体积小、功能强、成本低以及便于实现分布式控制而有非常广泛的应用领域1。单片机开发者在编制各种应用程序时经常会遇到实现精确延时的问题
14、,比如按键去抖、数据传输等操作都要在程序中插入一段或几段延时,时间从几十微秒到几秒。有时还要求有很高的精度,如使用单总线芯片DS18B20时,允许误差范围在十几微秒以内2,否则,芯片无法工作。用51汇编语言写程序时,这种问题很容易得到解决,而目前开发嵌入式系统软件的主流工具为C语言,用C51写延时程序时需要一些技巧3。因此,在多年单片机开发经验的基础上,介绍几种实用的编制精确延时程序和计算程序执行时间的方法。实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。1使用定时器/计数器实现精确
15、延时单片机系统一般常选用11.0592MHz12MHz或6MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1s和2s,便于精确延时。本程序中假设使用频率为12MHz的晶振。最长的延时时间可达216=65536科s。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动力口上PUSHACCPUSHP
16、SWPOPPS怖口POPACC句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。2软件延时与时间计算在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。2.1 短暂延时可以在C文件中通过使用带_NOP_()语句的函数实现,定义一系列不同的延时函数,如Delay10us()、Delay25us()、Delay40us()等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10s的延时函数可编写如下:voidDelay10u
17、s()_NOP_();_NOP_();_NOP_();_NOP_();_NOP_();_NOP_();Delay10us()函数中共用了6个_NOP_()语句,每个语句执行时间为1科s。主函数调用Delay10us()时,先执行一个LCALL指令(2s),然后执行6个_NOP_()语句(6Ws),最后执行了一个RET指令(2s),所以执行上述函数时共需要10So可以把这一函数当作基本延时函数,在其他函数中调用,即嵌套调用4,以实现较长时间的延时;但需要注意,如在Delay40us()中直接调用4次Delay10us()函数,得到的延时时间将是42ss,而不是40So这是因为执行Delay40u
18、s()时,先执行了一次LCALL指令(2Ws),然后开始执行第一个Delay10us(),执行完最后一个Delay10us()时,直接返回到主程序。依此类推,如果是两层嵌套调用,如在Delay80us()中两次调用Delay40us(),则也要先执行一次LCALL指令(2s),然后执行两次Delay40us()函数(84s),所以,实际延时时间为86ss。简言之,只有最内层的函数执行RET指令。该指令直接返回到上级函数或主函数。如在Delay80s()中直接调用8次Delay10us(),此时的延时时间为82科s。通过修改基本延时函数和适当的组合调用,上述方法可以实现不同时间的延时。2.2 在
19、C51中嵌套汇编程序段实现延时在C51中通过预处理指令#pragmaasmn#pragmaendasm可以嵌套汇编语言语句。用户编写的汇编语言紧跟在#pragmaasm之后,在#pragmaendasm之前结束。如:#pragmaasm,汇编语言程序段#pragmaendasm延时函数可设置入口参数,可将参数定义为unsignedchar、int或long型。根据参数与返回值的传递规则,这时参数和函数返回值位于R7、R7R6R7R6R升。在应用时应注意以下几点: #pragmaasm、#pragmaendasm不允许嵌套使用; 在程序的开头应加上预处理指令#pragmaasm,在该指令之前只能
20、有注释或其他预处理指令; 当使用asm语句时,编译系统并不输出目标模块,而只输出汇编源文件; asm只能用小写字母,如果把asm写成大写,编译系统就把它作为普通变量; #pragmaasm、#pragmaendasm和asm只能在函数内使用。将汇编语言与C51结合起来,充分发挥各自的优势,无疑是单片机开发人员的最佳选择。2.3 使用示波器确定延时时间熟悉硬件的开发人员,也可以利用示波器来测定延时程序执行时间。方法如下:编写一个实现延时的函数,在该函数的开始置某个I/O口线如P1.0为高电通过示波器测量P1.0平,在函数的最后清P1.0为低电平。在主程序中循环调用该延时函引脚上的高电平时间即可确
21、定延时函数的执行时间。方法如下:sbitT_point=P1A0;voidDlylms(void)unsignedinti,j;while(1)T_point=1;for(i=0;i<2;i+)for(j=0;j<124;j+);)T_point=0;for(i=0;i<1;i+)for(j=0;j<124;j+);voidmain(void)Dly1ms();把P1.0接入示波器,运行上面的程序,可以看到P1.0输出的波形为周期是3ms的方波。其中,高电平为2ms,低电平为1ms,即for循环结构“for(j=0;j<124;j+);”的执行时间为1ms。通过改
22、变循环次数,可得到不同时间的延时。当然,也可以不用for循环而用别的语句实现延时。这里讨论的只是确定延时的方法。2.4使用反汇编工具计算延时时间对于不熟悉示波器白开发人员可用KeilC51中的反汇编工具计算延时时间,在反汇编窗口中可用源程序和汇编程序的混合代码或汇编代码显示目标应用程序。为了说明这种方法,还使用“for(i=0;i<DlyT;i+);。在程序中加入这一循环结构,首先选择buildtaget,然后单击start/stopdebugsession按钮进入程序调试窗口,最后打开Disassemblywindow,找出与这部分循环结构相对应的汇编代码,具体如下:C:0x000FE
23、4CLRA/1TC:0x0010FEMOVR6,A/1TC:0x0011EEMOVA,R6/1TC:0x0012C3CLRC/1TC:0x00139FSUBBA,DlyT/1TC:0x00145003JNCC:0019/2TC:0x00160EINCR6/1TC:0x001780F8SJMPC:0011/2T可以看出,0x000F0x0017一共8条语句,分析语句可以发现并不是每条语句都执行DlyT次。核心循环只有0x00110x0017共6条语句,总共8个机器周期,第1次循环先执行CLRA和MOW6,A”两条语句,需要2个机器周期,每循环1次需要8个机器周期,但最后1次循环需要5个机器周期。
24、DlyT次核心循环语句消耗(2+DlyTX8+5)个机器周期,当系统采用12MHz时,精度为7科s。当采用while(DlyT-)循环体时,DlyT的值存放在R7中。相对应的汇编代码如下:C:0x000FAE07MOVR6,R7/1TC:0x00111FDECR7/1TC:0x0012EEMOVA,R6/1TC:0x001370FAJNZC:000F/2T循环语句执行的时间为(DlyT+1)X5个机器周期,即这种循环结构的延时精度为5so通过实验发现,如将while(DlyT-)改为while(-DlyT),经过反汇编后得到如下代码:C:0x0014DFFEDJNZR7,C:0014/2T可以
25、看出,这时代码只有1句,共占用2个机器周期,精度达到2s,循环体耗时DlyTX2个机器周期;但这时应该注意,DlyT初始值不能为0。这3种循环结构的延时与循环次数的关系如表1所列。表1循环次数与延时时间关系单位:s注意:计算时间时还应加上函数调用和函数返回各2个机器周期时间。2.5使用性能分析器计算延时时间很多C程序员可能对汇编语言不太熟悉,特别是每个指令执行的时间是很难记忆的,因此,再给出一种使用KeilC51的性能分析器计算延时时间的方法。这里还以前面介绍的for(i=0;i<124;i+)结构为例。使用这种方法时,必须先设置系统所用的晶振频率,选择Optionsfortarget中的target选项,在Xtal(MHz)中填入所用晶振的频率。将程序编译后,分别在_point=1和T_point=0处设置两个运行断点。选择start/stopdebugsession按钮进入程序调试窗口,分别打开PeRFor
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年旅游景点电力供应施工合同3篇
- 2024年建筑工程环境检测合同
- 中国计量大学《智能控制终端技术》2022-2023学年第一学期期末试卷
- 2024年度版权质押合同with质押权利及解除条件3篇
- 2024年医疗单位正式员工协议样本版B版
- 2024年医疗健康数据共享与分析平台建设合同
- 2024年投资合作合同:谈判策略与合同订立
- 2024年修订版建筑项目协议样本版B版
- 2024年度教育行业协同发展协议版B版
- 2024年民用建筑项目设计协议准则版B版
- 【教学创新大赛】《管理学》教学创新成果报告
- 国家开放大学《Python语言基础》形考任务3参考答案
- 事业单位面试题-人际关系类
- 部编版小学语文一年级上册八单元整体解读
- 健康指南肾囊肿患者应该如何进行有效的治疗
- 生活区公共服务设施布局规划优化
- DB21-T 2780.1-2017辽东落叶松二元立木材积表 第1 部分 日本落叶松
- 项目亏损分析报告
- 地源热泵施工流程课件
- 改善与客户需求的沟通技巧
- 《地球是怎样形成的》课件
评论
0/150
提交评论