众所周知,c51在编程时很难把握程序运转的时刻,所以编写延时程序时很难做到很精确,处理的方法有刺进汇编句子,但总觉得汇编用起来不是那么随手,还能够用定时器来做,但仅仅一个很小的延时程序罢了,不用借题发挥。其实方法仍是有的,下面介绍一下常用的几种延时程序。
1、us级延时程序
常用的一个函数如下:
void delayus(unsigned char x)
{ while(–x) ;
}
生成的汇编代码为:
C:0x001C 7F0A MOV R7,#0x0A //2us
C:0x001E 12003E LCALL delayus(C:003E) // 2us
C:0x003E DFFE DJNZ R7,delayus(C:003E) //2x us
C:0x0040 22 RET // 1us
所以调用一次函数延时时刻为 ( 2x+5 )us ,能够用来延时大于5us的时刻。
留意的是x要是unsigned char 类型,且 –x 不能写成x– ,不然汇编代码会有一大串:C:0x001C 7F02 MOV R7,#0x02
C:0x001E 120032 LCALL delayus(C:0032)
C:0x0032 AE07 MOV R6,0x07
C:0x0034 1F DEC R7
C:0x0035 EE MOV A,R6
C:0x0036 70FA JNZ delayus(C:0032)
C:0x0038 22 RET
由于汇编中的DJNZ 句子是先减再三判别的,和-xx的算法共同,所以–x和x–相差了许多。上述函数只合适x的规模是0-255,假设需求延时大于255*2+5us,则能够接连调用几回函数。
2、ms的延时程序
常用的一个函数:
void delayms(unsigned int x)
{
unsigned char i;
while(x–)
{
for(i=0;i《125;i++){;}
}
}
咱们来看一下它的精度怎么
x us
1 1024
5 5076
10 10141
50 50661
100 101311
可见,精度不“精”,跟着x值的增大,延时差错越大,只合适在延时不要求很精确的当地运用。所以想到对程序进行一些批改,想到125是不是取的太大了,假设把它变为可变,不同的x值取值不同,就能够对延时时刻进行一些批改,把程序改为如下:
void delayms(unsigned int x,unsigned char y)
{
unsigned char j;
while(x–)
{
for(j=0;j }
}
对不同的延时时刻取不同的y值,发现一个“怪”现象,当取y=123时,延时时刻的差错是一个固定值:
x us
1 1017
2 2016
5 5016
10 10016
50 50016
100 100016
除了x=1外,其他的差错都为16us, 即不论x为多大都只要16us的差错,精度大幅度进步,能够满意大多数的需求!
来历;21ic