您的位置 首页 基础

用C51编写单片机延时函数

参考了51单片机KeilC延时程序的简单研究,自己也亲身测试和计算了一些已有的延时函数。这里假定单片机是时钟频率为12MHz,则一个机器…

参阅了51单片机 Keil C 延时程序的简略研讨,自己也亲自测验和核算了一些已有的延时函数

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

voiddelay(unsignedchart)
{
while(–t);
}

反汇编代码如下:

履行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, #data需求1个机器周期,LJMP需求2个机器周期,即调用delay()需求3us.

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.
现在让咱们来剖析一下这个之前用过的延时函数:

//延时函数,关于11.0592MHz时钟,例i=10,则大约延时10ms.
voiddelayMs(unsignedinti)
{
unsignedintj;
while(i–)
{
for(j=0;j<125;j++);
}
}

它的反汇编代码如下:

剖析: T表明一个机器周期(调用时刻相关于这个ms级的延时来说,可忽略不计)

1C:0000MOVA,R7;1T
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,#data Add immediate data to ACC.21
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,#data Add immediate data to ACC with carry.21
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,#data Subtract immediate data from ACC with borrow.21
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 data pointer.12
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,#data AND immediate data to ACC.21
ANL direct,A AND ACC to direct byte.21
ANL direct,#data AND immediate data to direct byte.32
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,#data OR immediate data to ACC.21
ORL direct,A OR ACC to direct byte.21
ORL direct,#data OR immediate data to direct byte.32
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,#data Exclusive OR immediate data to ACC.21
XRL direct,A Exclusive OR ACC to direct byte.21
XRL direct,#data XOR immediate data to direct byte.32
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
Data Transfer

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,#data Move immediate data to ACC.21
MOV Rn,A Move ACC to register.11
MOV Rn,direct Move direct byte to register.22
MOV Rn,#data Move immediate data to register.21
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,#data Move immediate data to direct byte.32
MOV @Ri,A Move ACC to indirect RAM.11
MOV @Ri,direct Move direct byte to indirect RAM.22
MOV @Ri,#data Move immediate data to indirect RAM.21
MOV DPTR,#data16 Move immediate 16 bit data to data pointer register.32
MOVC A,@A+DPTR Move code byte relative to DPTR to ACC (16 bit address).12
MOVC A,@A+PC Move code byte relative to PC to ACC (16 bit address).12
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 onto stack.22
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,#data,rel Compare immediate byte to ACC and jump if not equal.32
CJNE Rn,#data,rel Compare immediate byte to register and jump if not equal.32
CJNE @Ri,#data,rel Compare immediate byte to indirect and jump if not equal.32
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单片机指令汇总”

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/jichu/272176.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部