分类:
2008-09-27 14:04:25
用C语言写延时程序可谓很简单,用一个for循环获一个while语句就行。但延时多少呢?似乎很笼统,一直以来我也是这样大概的用。
今天有空,来认真的看下C51延时程序。首先说下延时程序应怎样写,计数循环是程序中十分常见的流程控制结构。在C语言中,常用下面累加计数的循环形式:
For(loop=1;loop<=limit;loop++)
这中累加计数的方法符合一般的自然思维方式,所以下面这种递减计数方法很少用:
For(loop= limit;loop!=0;loop--)
这两种循环形式在逻辑上没有效率的差异,但是映射到具体的体系结构中时,就产生了很大的不同,如下:
EXT1:
void delay(uchar n)
{ uchar i;
for(i=n;i!=0;i--)
;
}
汇编后:
C:0x000F EF MOV A,R7
C:0x0010 6003 JZ C:0015
C:0x0012 1F DEC R7
C:0x0013 80FA SJMP delay(C:000F)
C:0x0015 22 RET
EXT2:
void delay(uchar n)
{ uchar i;
for(i=1;i<=n;i++)
;
}
汇编后:
C:0x000F 7E01 MOV R6,#0x01
C:0x0011 EE MOV A,R6
C:0x0012 D3 SETB C
C:0x0013 9F SUBB A,R7
C:0x0014 5003 JNC C:0019
C:0x0016 0E INC R6
C:0x0017 80F8 SJMP C:0011
C:0x0019 22 RET
可看到实现相同功能的两段程序,汇编后却有很大的不同,EXT2的写法比EXT1多出了3行。而这还只是比较简单的延时程序,如果复杂点的程序会多出更多的代码,所以在单片机体系结构下编程,建议采用第一种递减的方式来设置循环条件。
下面来看下C程序延时准确性的问题。仍然看EXT1
void delay(uchar n)
{ uchar i;
for(i=n;i!=0;i--)
;
}
汇编后:
C:0x000F EF MOV A,R7 1T
C:0x0010 6003 JZ C:0015 1T
C:0x0012 1F DEC R7 1T
C:0x0013 80FA SJMP delay(C:000F) 2T
C:0x0015 22 RET 2T
如单片机外部晶振为12MHz,则1T=1us,执行此程序的时间(即延时)为:
(5R7+4)us,寄存器R7为参数n的值。