参阅了51单片机 Keil C 延时程序的简略研讨,自己也亲自测验和核算了一些已有的延时函数。
这儿假定单片机是时钟频率为12MHz,则一个机器周期为:1us.
参阅了51单片机 Keil C 延时程序的简略研讨后,咱们可知道, 在Keil C中取得最为精确的延时函数将是




反汇编代码如下:
履行DJNZ指令需求2个机器周期,RET指令相同需求2个机器周期,依据输入t,在不核算调用delay()所需时刻的情况下,详细时刻延时如下:
t | Delay Time (us) |
1 | 2×1+2 =4 |
2 | 2×2+2=6 |
N | 2×N+2=2(N+1) |
当在main函数中调用delay(1)时, 进行反汇编如下:
调用delay()时,多履行了两条指令,其间MOV R, #da
Keil C仿真截图与核算进程:
加上调用时刻,精确的核算时刻延时与Keil C仿真比照如下:(可见,仿真成果和核算成果是很挨近的)
t | Delay Time (us) | 仿真11.0592Mhz时钟(us) |
1 | 3+2×1+2 =7 | 7.7(实践) | 7.60 |
2 | 3+2×2+2=9 | 9.9 | 9.76 |
N | 3+2×N+2=2N+5 | (2N+5)*1.1 | / |
3 | 11 | 12.1 | 11.94 |
15 | 35 | 38.5 | 37.98 |
100 | 205 | 225.5 | 222.44 |
255 | 515 | 566.5 | 558.81 |
也就是说,这个延时函数的精度为2us,最小的时刻延时为7us,最大的时刻延时为3+255×2+2=515us.
实践中运用11.0592MHz的时钟,这个延时函数的精度将为2.2us,最小时刻延时为7.7us, 最大时刻延时为566.5us.
这个时刻延时函数,关于与DS18B20进行单总线通讯,现已满足精确了。
现在,咱们将时钟换成11.0592MHz这个实践用到的频率,每个机器周期约为1.1us.
现在让咱们来剖析一下这个之前用过的延时函数:









它的反汇编代码如下:
剖析: T表明一个机器周期(调用时刻相关于这个ms级的延时来说,可忽略不计)
2DECR7;1T低8位字节省1
3MOVR2,0x06;2T
4JNZC:0007;2T若低8位字节不为0,则跳到C:0007
5DECR6;1T低8位字节为0,则高8位字节省1
6C:0007ORLA,R2;1T
7JZC:001D;2T若高8位也减为0,则RET
8CLRA;1TA清零
9MOVR4,A;1TR4放高位
10MOVR5,A;1TR5放低位
11C:000DCLRC;1TC清零
12MOVA,R5;1T
13SUBBA,#0x7d;1TA=A-125
14MOVA,R4;1T
15SUBBA,#0x00;1TA
16JNCC:0000;2TA为零则跳到C:0000
17INCR5;1TR5增1
18CJNER5,#0x00,C:001B;2TR5>0,跳转到C:000D
19INCR4;1T
20C:001BSJMPC:000D;2T
21C:001DRET
关于delayMs(1), 履行到第7行就跳到21行, 共需时12T, 即13.2us
关于delayMs(2), 需时9T+13T+124×10T+7T+12T = 9T+13T+1240T+7T+12T =1281T =1409.1us.
关于delayMs(3), 需时9T×(3-1)+(13T+124×10T+7T)×(3-1)+12T
=1269T×(3-1)+12T=2550T=2805us.
关于delayMs(N),N>1, 需时1269T×(N-1)+12T = 1269NT-1257T=(1395.9N-1382.7)us.
使用Keil C仿真delayMs(1) = 0.00166558s = 1.67ms 截图如下:
由剖析可知详细的核算延时时刻与Keil C仿真延时比照如下:
i | Time Delay | 仿真延时 |
1 | 13.2us | 1.67ms |
2 | 1409.1us | 3.31ms |
3 | 2805us | 4.96ms |
N | (1395.9N-1382.7)us | |
10 | 12.6ms | 16.50ms |
20 | 26.5ms | 32.98ms |
30 | 40.5ms | 49.46ms |
50 | 68.4ms | 82.43ms |
100 | 138.2ms | 164.84ms |
200 | 277.8ms | 329.56ms |
500 | 696.6ms | 824.13ms |
1000 | 1394.5ms | 1648.54ms |
1500 | 2092.5ms | 2472.34ms |
2000 | 2790.4ms | 3296.47ms |
5 | 5.6ms | 8.26ms |
73 | 100.5ms | 120.34ms |
720 | 1003.7ms = 1s | 1186.74ms |
核算delayMs(10)得到延时时刻为:12576.3us约等于12.6ms,挨近咱们以为的10ms。
核算成果和仿真成果只需delayMs(1)有很大收支, 其它都挨近, 在承受范围内.
通过以上剖析,可见用C言语来做延时并不是不太精确,仅仅不容易做到十分精确罢了,若有一句句子变了,延时时刻很可能会不同,由于编译程序生成的汇编指令很可能不同。
PS:
关于每条51单片机汇编指令的字长和所需机器周期汇总如下:转自:http://bbs.mcustudy.com/printpage.asp?BoardID=2&ID=1454
Appendix E – 8051 Instruction Set
Arithmetic Operations
MnemonicDescriptionSizeCycles
ADD A,Rn Add register to Accumulator (ACC).11
ADD A,direct Add direct byte to ACC.21
ADD A,@Ri Add indirect RAM to ACC.11
ADD A,#da
ADDC A,Rn Add register to ACC with carry.11
ADDC A,direct Add direct byte to ACC with carry.21
ADDC A,@Ri Add indirect RAM to ACC with carry.11
ADDC A,#da
SUBB A,Rn Subtract register from ACC with borrow.11
SUBB A,direct Subtract direct byte from ACC with borrow21
SUBB A,@Ri Subtract indirect RAM from ACC with borrow.11
SUBB A,#da
INC A Increment ACC.11
INC Rn Increment register.11
INC direct Increment direct byte.21
INC @Ri Increment indirect RAM.11
DEC A Decrement ACC.11
DEC Rn Decrement register.11
DEC direct Decrement direct byte.21
DEC @Ri Decrement indirect RAM.11
INC DPTR Increment da
MUL AB Multiply A and B Result: A <- low byte, B <- high byte.14
DIV AB Divide A by B Result: A <- whole part, B <- remainder. 14
DA A Decimal adjust ACC.11
Logical Operations
MnemonicDescriptionSizeCycles
ANL A,Rn AND Register to ACC.11
ANL A,direct AND direct byte to ACC.21
ANL A,@Ri AND indirect RAM to ACC.11
ANL A,#da
ANL direct,A AND ACC to direct byte.21
ANL direct,#da
ORL A,Rn OR Register to ACC.11
ORL A,direct OR direct byte to ACC.21
ORL A,@Ri OR indirect RAM to ACC.11
ORL A,#da
ORL direct,A OR ACC to direct byte.21
ORL direct,#da
XRL A,Rn Exclusive OR Register to ACC.11
XRL A,direct Exclusive OR direct byte to ACC.21
XRL A,@Ri Exclusive OR indirect RAM to ACC.11
XRL A,#da
XRL direct,A Exclusive OR ACC to direct byte.21
XRL direct,#da
CLR A Clear ACC (set all bits to zero).11
CPL A Compliment ACC.11
RL A Rotate ACC left.11
RLC A Rotate ACC left through carry.11
RR A Rotate ACC right.11
RRC A Rotate ACC right through carry.11
SWAP A Swap nibbles within ACC.11
Da
MnemonicDescriptionSizeCycles
MOV A,Rn Move register to ACC.11
MOV A,direct Move direct byte to ACC.21
MOV A,@Ri Move indirect RAM to ACC.11
MOV A,#da
MOV Rn,A Move ACC to register.11
MOV Rn,direct Move direct byte to register.22
MOV Rn,#da
MOV direct,A Move ACC to direct byte.21
MOV direct,Rn Move register to direct byte.22
MOV direct,direct Move direct byte to direct byte.32
MOV direct,@Ri Move indirect RAM to direct byte.22
MOV direct,#da
MOV @Ri,A Move ACC to indirect RAM.11
MOV @Ri,direct Move direct byte to indirect RAM.22
MOV @Ri,#da
MOV DPTR,#da
MOVC A,@A+DPTR Move co
MOVC A,@A+PC Move co
MOVX A,@Ri Move external RAM to ACC (8 bit address).12
MOVX A,@DPTR Move external RAM to ACC (16 bit address).12
MOVX @Ri,A Move ACC to external RAM (8 bit address).12
MOVX @DPTR,A Move ACC to external RAM (16 bit address).12
PUSH direct Push direct byte on
POP direct Pop direct byte from stack.22
XCH A,Rn Exchange register with ACC.11
XCH A,direct Exchange direct byte with ACC.21
XCH A,@Ri Exchange indirect RAM with ACC.11
XCHD A,@Ri Exchange low order nibble of indirect RAM with low order nibble of ACC.11
Boolean Variable Manipulation
MnemonicDescriptionSizeCycles
CLR C Clear carry flag.11
CLR bit Clear direct bit.21
SETB C Set carry flag.11
SETB bit Set direct bit.21
CPL C Compliment carry flag.11
CPL bit Compliment direct bit.21
ANL C,bit AND direct bit to carry flag.22
ANL C,/bit AND compliment of direct bit to carry.22
ORL C,bit OR direct bit to carry flag.22
ORL C,/bit OR compliment of direct bit to carry.22
MOV C,bit Move direct bit to carry flag.21
MOV bit,C Move carry to direct bit.22
JC rel Jump if carry is set.22
JNC rel Jump if carry is not set.22
JB bit,rel Jump if direct bit is set.32
JNB bit,rel Jump if direct bit is not set.32
JBC bit,rel Jump if direct bit is set & clear bit.32
Program Branching
MnemonicDescriptionSizeCycles
ACALL addr11 Absolute subroutine call.22
LCALL addr16 Long subroutine call.32
RET Return from subroutine.12
RETI Return from interrupt.12
AJMP addr11 Absolute jump.22
LJMP addr16 Long jump.32
SJMP rel Short jump (relative address).22
JMP @A+DPTR Jump indirect relative to the DPTR.12
JZ rel Jump relative if ACC is zero.22
JNZ rel Jump relative if ACC is not zero.22
CJNE A,direct,rel Compare direct byte to ACC and jump if not equal.32
CJNE A,#da
CJNE Rn,#da
CJNE @Ri,#da
DJNZ Rn,rel Decrement register and jump if not zero.22
DJNZ direct,rel Decrement direct byte and jump if not zero.32
Other Instructions
MnemonicDescriptionSizeCycles
NOP No operation.11
其它可检查《单片机根底》-李广弟等编著,P70 “MCS-51单片机指令汇总”