单片机的C语言延时程序.doc

上传人:自*** 文档编号:124916020 上传时间:2020-03-14 格式:DOC 页数:4 大小:30.51KB
返回 下载 相关 举报
单片机的C语言延时程序.doc_第1页
第1页 / 共4页
单片机的C语言延时程序.doc_第2页
第2页 / 共4页
单片机的C语言延时程序.doc_第3页
第3页 / 共4页
单片机的C语言延时程序.doc_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《单片机的C语言延时程序.doc》由会员分享,可在线阅读,更多相关《单片机的C语言延时程序.doc(4页珍藏版)》请在金锄头文库上搜索。

1、单片机C语言环境延时程序设计 东北电力学院(132012) 盛文利摘 要:讨论运用C语言的单片机开发中,对于时序要求苛刻的延时的开发过程。实例说明在高级语言中,严格控制时序的可能性和注意事项。关键词:单片机 C语言 编译器 现在单片机的开发中,C语言以其方便、灵活、逻辑性强、易于维护和可移植性好等强大优势,占据了单片机开发的主要地位。过去,由于单片机C语言本身存在的缺陷,加之单片机工程本身都不大,C语言在单片机中的应用没有被重视。在C语言环境下,我们只需关心程序的逻辑关系,实现细节由编译器完成,这给我们快速开发提供了条件,也大大减小了开发工作量。但同时实现细节就不被控制了,这个问题对于经常重视

2、实现细节的单片机,就必须得到解决。好在一般的C语言编译器都提供嵌入汇编、与汇编互调用和汇编级的代码察看等功能。现以KEIL C511下的一线总线器件程序开发为例,说明我的解决方法。1 一线总线协议器件一线总线协议(1 wire bus protocol)也叫做单总线协议,是单总线器件数据传输协议。因为数据(也可以包括电源)都由一条线来传输,没有辅助的数据同步信号,这时就只能由时序来解析协议内容。这样就只有依靠对时序的严格要求,来保障数据传输的准确性。单总线协议的信号主要有:初始化时序,包括复位脉冲和在线脉冲,是主机与器件的联络信号。然后是读、写时序。单总线器件完全依靠对线上的时序来做出响应,这

3、些有效的时序称作时隙,也有称作时间片的,是同一词汇的不同翻译2。初始化时序时间裕度大,容易实现。读写脉冲对时序要求相对严格,尤其在慢速的MCS-51下,指令的运行在微妙级,而读写时序在15微秒的后小部分,大约4微秒,不同批次的芯片会有少许差距。有的会允许你的时序有少许误差,有的则非常严格。2 C语言编译器 在用汇编语言编写的程序时,很容易控制时间,因为我们知道每条语句的执行时间,每段宏的执行时间,每段子程序加调用语句所消耗的时间。在单片机的C语言开发中,C语言编译器都对标准C作了针对单片机特点的扩展。但对于不同的单片机,不同的C语言编译器在将源程序翻译成目标机器语言时,会有不同的编译方法,在生

4、成目标代码时,会有所不同。开发人员必须研究它生成的汇编语言代码,来保证时间的准确性。这也许是除了使用嵌入汇编或直接编写汇编函数的唯一方法。其实在单片机的C编译器中,已经有足够的底层操作方面的扩展,所以这里只考虑纯C语言的方法。3. 延时程序设计我们以德国Keil公司的MCS-51C语言编译器为例,目前它已被公认为业界的标准。以下讨论均假设单片机时钟晶振为6兆的51芯片,以小模式下编译,这时MCS-51程序指令执行的最小单位是2微秒。如果使用非英特尔且内核优化过的单片机,应切换回普通模式,或仔细研究它的时序。以DS18B20为例,我们临时在程序中需要延时2微秒,那末可以用以下程序#include

5、 void somefunc(void) ;_nop_();如果要延时64微秒甚至640微妙,我们不可能在程序中重复上述_nop_(),虽然这并不会出错。可以利用它来构建延时程序,精确定时的问题就变为延时程序的精度问题。我们先讨论以上的空 操作延时。3.1 空操作延时及延时函数注意到DS18B20最小时隙除大于一微秒的外,最小的就是15微秒。而数据的读或写也包含在这15微秒中。由于定时器的延时要对定时器进行初始化,不易得到小的延时。只能用于复位脉冲,即在480至960微秒之间的延时,程序实现接近960微秒的延时;TH0 = -950/256;TL0 = -950%256;TMOD= TMOD|

6、0x01TR0 = 1;定时器启后,单片机可以作其他事情,如复位看门狗,或LED扫描。而调用的短延时函数必需精确的受到控制,先作一个几微秒的延时实验程序,以观察它实际的延时时间,又因为我们在汇编时代常用的延时指令为MOV R7, DDLYDJNZ R7,$以便产生最小4微秒的延时,仿造的C程序如下void delay1(ndly)for(;ndly0;ndly-) ;生成的汇编代码却与DJNZ无关,是如下形式,其中无关的编译注释已删除RSEG ?PR?_delay1?DLY2_delay1:USING0?C0006:MOV A,R7 ;2usSETB C ;2usSUBB A,#00H ;2u

7、sJC ?C0009 ;2usDEC R7 ;2usSJMP ?C0006 ;4us?C0009:RET ;4us; END OF _delay1延时至少18微秒,无法用于读写时隙。改用如下程序void delay2(unsigned char vd) for (vd=0; vd10;vd+) ;生成的汇编代码如下RSEG ?PR?_delay2?DLY2_delay2:USING0CLR A ;2usMOV R7,A ;2us?C0002:INC R7 ;2usCJNE R7,#0AH,?C0002 ;4us?C0005:RET ;4us; END OF _delay2以上代码调用一次也有1

8、4微秒之多,还是无法使用。也就是说采用for形式的语句,生成的汇编代码都是先减,再比较,还是与DJNZ无关,也就不能产生短延时。3.2短延时程序编写首先想到的是用汇编语言函数,或嵌入汇编的方法,例如汇编语言函数实现NAMEDLY?PR?_delay3?DLY SEGMENT CODEPUBLIC_delay3RSEG ?PR?_delay3?DLY_delay3: DJNZ R7, $ ;4us RET ;4usEND或嵌入汇编的方法,void delay4(unsigned char vd)#pragma asm djnz R7, $ ; #pragma endasm编译后的形式?PR?_d

9、elay4?DLY SEGMENT CODE ?DT?_delay4?DLY SEGMENT DATA OVERLAYABLE PUBLIC_delay4RSEG ?DT?_delay4?DLY2?_delay4?BYTE:vd?040: DS 1RSEG ?PR?_delay4?DLY2_delay4:MOV vd?040,R7 ;2us djnz R7, $ ;RET ; END OF _delay4注意这里用于参数传递的R7,被复制保存起来了,这样在调用时,比汇编书写的函数多出2微秒。 除此之外,我们还是可以编出全C的类似函数void delay5(unsigned char vd) d

10、o vd-; while(vd);编译后RSEG ?PR?_delay5?DLY3_delay5:USING0?C0003:DJNZ R7,?C0003RET 看来DO_WHILE是和DJNZ相对应编译的。4 调用时间和某些细节除了直接插入_nop_()语句的短时间延时,在稍长的时间多变的延时程序中,往往需要调用上节讨论的延时函数来完成延时,其中以汇编语言函数和DO_WHILE最易控制,以为他们只有一条延时指令 DJNZ R7, $这时,一定注意在函数传递的参数(通过R7付值)要2微秒,调用函数时执行的LCALL语句的4微秒,在函数返回时,RET指令的4微秒,还要至少执行DJNZ指令(R7为0

11、,djnz后R7=256)4微秒,所以至少为14微秒,这应该是函数调用延时的极限状态。另外还要注意对于连续调用的函数例如:; void delay 1(void); void delay2 (void); ;生成的汇编语言代码不是lcall delay1;lcall delay2;他被编译器优化,在调用delay1进入并执行该函数,返回前直接跳入delay2执行,类似于delay1:ljmp delay 2;由delay 2执行RET返回,这样连续调用两个函数时,就变成一次调用加跳转,结果会省去2微秒。解决了延时问题,再根据参考文献2,可写出读字节程序unsigned char read_by

12、te(void) unsigned char i; unsigned char value = 0; for (i=0;i=1; /2us D0 = 0;/ pull DQ low to start timeslot _nop_(); /2us _nop_(); /2us _nop_(); /2usD0 = 1; / then return high _nop_(); /2us _nop_(); /2us if(D0) value|=0x80; _nop_(); /2us delay(10);/ wait for rest of timeslot return(value);写一字节的程序vo

13、id write_byte(unsigned char val) unsigned char i; for (i=0; i1; delay(10) ; /because the write time must just fit for, D0 = 1; delay(2); 完整的18B20数据采集程序,再附件中,(可放在网上),其中包含了CRC校验。5 结论在现代竞争激烈的商品经济环境下,高级语言的运用大大提高了开发效率。在C等高级语言编写这类时间要求严格的程序时,分析最终的目标汇编代码是无法避免的。在现代带有集成开发环境的编译器中,有软件仿真,或是有硬件调试功能,都给精确定时程序的开发带来方便。充分发挥软件工具的潜力,才能真正在各种环境下发挥高级语言带来的最大好处效率。参考文献1 Keil Software Keil uVision2 ReferenceKeil Electronik GmbH/Keil Software,Inc19952 DALLAS MAXIM产品资料光盘 6.0版2002年 作者简介:作者我(盛文利)1964年出生1983年考入成都电讯工程学院,1987年毕业。1991年调入东北电力学院应用电子技术实验室。现任职称工程师。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > IT计算机/网络 > 计算机应用/办公自动化

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号