用C51编写单片机延时函数

来源:本站
导读:目前正在解读《用C51编写单片机延时函数》的相关信息,《用C51编写单片机延时函数》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《用C51编写单片机延时函数》的详细说明。
简介:参考了51单片机 Keil C 延时程序的简单研究,自己也亲身测试和计算了一些已有的延时函数。

这里假定单片机是时钟频率为12MHz,则一个机器周期为:1us.

参考了51单片机 Keil C 延时程序的简单研究后,

反汇编代码如下:

用C51编写单片机延时函数

执行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)时, 进行反汇编如下:

用C51编写单片机延时函数

调用delay()时,多执行了两条指令,其中MOV R, #data需要1个机器周期,LJMP需要2个机器周期,即调用delay()需要3us.

Keil C仿真截图与计算过程:

用C51编写单片机延时函数

用C51编写单片机延时函数

加上调用时间,准确的计算时间延时与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.

现在让我们来分析一下这个之前用过的延时函数:

它的反汇编代码如下:

用C51编写单片机延时函数

分析: 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 截图如下:

用C51编写单片机延时函数

用C51编写单片机延时函数

用C51编写单片机延时函数

由分析可知具体的计算延时时间与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单片机汇编指令的字长和所需机器周期汇总如下:

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 DIV AB Divide A by B Result: A 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单片机指令汇总”

提醒:《用C51编写单片机延时函数》最后刷新时间 2024-03-14 00:51:34,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《用C51编写单片机延时函数》该内容的真实性请自行鉴别。