(玩电子) 电子技术学习与研讨
当时方位:单片机教程网 >> MCU规划实例 >> 阅览文章

用单片机C言语准确延时(守时)的办法

作者:51hei   来历:原创   点击数:x  更新时刻:2009年09月29日   【字体:

  最近在忙着单片机的项目,偶然停下来小结了一下最近的收成,仍是有不少可贵的收益的。

  本人在空闲的时分对单片机C言语下的各类延时程序做了下总结。因为单片机C言语下运用软件延时不容易做到准确的守时,所以许多人在编写延时子程序的时分不能好好的掌握延时的具体时刻。C言语下,延时程序主要有以下几种:

一:

void delay(unsigned char k)
{

 unsigned char i,k;  //界说变量
 for(i=0;i<k;i++);      //for循环句子

}

该程序在Keil环境下,会先将C言语转化成汇编言语,那么咱们就能够依据汇编言语来核算出准确的时刻,转化具体步骤如下:

 CLR A   ;指令1
 MOV R7,A ;指令2  
LOOP:
   INC R7  ;指令3
   CJNE  R7,k,LOOP    ;指令4

这儿,指令1,指令2和指令3各耗费1个机器周期,指令4耗费两个机器周期(可查此表得知:http://www.62pa.com/mcuteach/1312.html),而在12M的晶振下一个机器周期是1us,在这个过程中,指令1和指令2别离履行1次,即耗费1+1us,而指令3和指令4别离履行了k次,那么这样加起来,这个延时子程序所耗费的具体时刻便是t=1+1+(1+2)*k=3k+2us。

呵呵,这样说来,假如咱们界说的k为100的话,这个延时子程序的准确时刻便是302us。  

二:

void delay(unsigned char i)
{
while(--i)
{;}
} 

相同的道理,将其反汇编,能够看到,只要一条句子:DJNZ  i,$;

该句子耗费2us,一共履行i次,所以一共耗费时刻t=i*2us。

三:

下面的将形参换为整形int,这样的话,反汇编所履行的句子彻底不同,用个具体的数字做比如:

void delay()
{
 unsigned int i=10000;
 while(--i)
;
}

反汇编后:

     4:         unsigned int i=10000;

C:0x0003    7F10     MOV      R7,#0x10
C:0x0005    7E27     MOV      R6,#0x27

     5:         while(--i)
     6: ;
C:0x0007    EF       MOV      A,R7
C:0x0008    1F       DEC      R7
C:0x0009    7001     JNZ      C:000C
C:0x000B    1E       DEC      R6
C:0x000C    14       DEC      A
C:0x000D    4E       ORL      A,R6
C:0x000E    70F7     JNZ      C:0007

具体核算如下

1.R7通过10H(16)次循环减为0:
t1=10H*(1+1+2+1+1+2)
2.R6通过27H*256次循环减为0:
t2=27H*256*(1+1+2+1+1+2)+27H*1
3.最终R7的是变为255,因而还要多出255次的循环:
t3=255*(1+1+2+1+1+2)
4.加上之前耗费的2us,总耗费时刻:
T=2+10H*(1+1+2+1+1+2)+27H*256*(1+1+2+1+1+2)+27H*1+255*(1+1+2+1+1+2)
=2+16*7+39*256*7+39*1+255*7
=71826us
大约为72ms吧
假如界说一个unsigned int i,那么延时核算公式为T=2+(i%256)*7+(i/256)*256*7+i/256+255*7

关于其他类型的延时程序都能够依照这个办法对时刻进行较为准确的核算。

假如你懒得核算我还给我们引荐一个简略的办法:便是用keil的软件仿真功能来仿真出C句子履行的时刻,具体办法能够看这儿:http://www.62pa.com/bbs/dpj-4711-1.html

昨日熬夜收拾的,从这个程序中能够看出单片机C言语和汇编言语的一些差异,期望对我们有协助!

casino
宣布谈论】【告知老友】【保藏此文】【封闭窗口

文章谈论

相关文章