3525|0

10

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

单片机c语言精确延时 [复制链接]

51单片机 Keil C 延时程序的简单研究 (晶振12MHz,一个机器周期1us.)
void delay(void)
{
unsigned char i,j,k;
for(i=15;i>0;i--)
for(j=202;j>0;j--)
for(k=81;k>0;k--);
}
以上就是利用C51语言编写的一个延时函数,下面这段代码则是利用keil软件翻译的一段汇编语言程序段,大家可以对照着看。
机器周期数
C:0x0800 7F0F MOV R7,#0x0F 1
C:0x0802 7ECA MOV R6,#0xCA 1
C:0x0804 7D51 MOV R5,#0x51 1
C:0x0806 DDFE DJNZ R5,C:0806 2
C:0x0808 DEFA DJNZ R6,C:0804 2
C:0x080A DFF6 DJNZ R7,C:0802 2
C:0x080C 22 RET 2
通过上面的汇编语言程序段(0x0F=15,0xCA=202,0x51=81 ),我们可以计算出该延时子程序的具体延时时间:
Td=[(2×81+1)×202+202×2+1]×15+15×2+1+2
=(163×202+405)×15+35
=33331×15+33
=499978us=499.978ms
通过与C语言相比较,我们可以得出一个公式(对于C51,这个公式中的格式就跟上面的一样,数据类型必须是unsigned char,而且是三重循环,延时函数不带任何形参):
Td=[2×j×k+3×j+3]×i+3.....................①
下面是调用了上面的延时函数的C51主函数,紧跟其后的汇编语言是利用keil软件翻译的一段汇编语言程序段。
void main(void)
{
p10=1;
while(1)
{
p10=~p10;
delay();
}
机器周期数
C:0x0819 D290 SETB p10(0x90.0) 1
C:0x081B B290 CPL p10(0x90.0) 1
C:0x081D 120800 LCALL delay(C:0800) 2
C:0x0820 80F9 SJMP C:081B 2
倘若我们需要一个带有形参的延时函数,方便在程序中根据不同的情形调用,延时时间不一致,我们的延时时间又如何计算呢?下面我们来看看这个延时函数,跟上面的一样,只是把延时函数加了个形参,我们用同样的方法来计算它的延时时间。
void delay(unsigned char i)
{
unsigned char j,k;
for(;i>0;i--)
for(j=202;j>0;j--)
for(k=81;k>0;k--);
}
机器周期数
C:0x800 EF MOV A,R7
C:0x0801 D3 SETB C
C:0x0802 9400 SUBB A,#0x00
C:0x0804 400B JC C:0811
C:0x0806 7ECA MOV R6,#0xCA
C:0x0808 7D51 MOV R5,#0x51
C:0x080A DDFE DJNZ R5,C:080A
C:0x080C DEFA DJNZ R6,C:0808
C:0x080E 1F DEC R7
C:0x080F 80EF SJMP delay(C:0800)
C:0x0811 22 RET
我们看看,R7的值是多少呢?在下面,主函数里面,赋值为0x0F,就是15。通过上面这段汇编程序段,我们用同样的方法来计算一下它的延时时间为(机器周期数请自己查阅书籍):
Td=[2×202×81+3×202+8]×15+3
=[32724+614]×15+3
=33338×15+3
=500073us=500.073ms
由此,我们可以得出一个公式为:
Td=[2×j×k+3×j+8]×i+3.....................②
下面是调用了void delay(unsigned char i)延时函数的main()函数机器汇编代码。
void main(void)
{
p10=1;
14: while(1)
{
p10=~p10;
delay(15);
}
C:0x081E D290 SETB p10(0x90.0)
C:0x0820 B290 CPL p10(0x90.0)
C:0x0822 7F0F MOV R7,#0x0F
C:0x0824 120800 LCALL delay(C:0800)
C:0x0827 80F7 SJMP C:0820
两种不同的写法,公式①、②造成的时间误差有1个毫秒多,在许多要求精确延时的地方,我们就不得不注意这1个毫秒会造成什么样的后果。大家有兴趣,可以用同样的方式去验证和计算unsigned int型以及使用while语句和for语句组合起来的精确延时时间的计算。注意,其中for语句里面的循环控制语句,i>0,j>0,k>0,如果你把他们改写成i>=0,j>=0,k>=0,效果就不一样了,延时时间变的更长。
此帖出自单片机论坛

赞赏

1

查看全部赞赏

点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表