As we all know, c51 is difficult to grasp the running time of the program when programming, so it is difficult to be very precise when writing a delay program. The solution is to insert assembly statements, but I always feel that the assembly is not so easy to use. You can also use a timer. Come to do it, but it’s just a small delay program, no need to make a fuss. In fact, there are still ways. Here are some commonly used delay programs.

As we all know, c51 is difficult to grasp the running time of the program when programming, so it is difficult to be very precise when writing a delay program. The solution is to insert assembly statements, but I always feel that the assembly is not so easy to use. You can also use a timer. Come to do it, but it’s just a small delay program, no need to make a fuss. In fact, there are still ways. Here are some commonly used delay programs.

Design of Several Common Delay Programs of C51 Single-chip Microcomputer

1. Us-level delay program

A commonly used function is as follows:

void delayus (unsigned char x)

{while(–x);

}

The generated assembly code is:

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

So the delay time of calling a function is (2x+5)us, which can be used to delay the time greater than 5us.

Note that if x is an unsigned char type, and –x cannot be written as x–, otherwise the assembly code will have a large string: 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

Because the DJNZ statement in the assembly is first subtracted and then judged, which is consistent with the -xx algorithm, there is a lot of difference between -x and x-. The above function is only suitable for x in the range of 0-255. If you need to delay more than 255*2+5us, you can call the function several times in succession.

2. Delay program in ms

A commonly used function:

void delayms (unsigned int x)

{

unsigned char i;

while(x–)

{

for(i=0;i《125;i++){;}

}

}

Let’s take a look at its accuracy

x us

1 1024

5 5076

10 10141

50 50661

100 101311

It can be seen that the accuracy is not “fine”. As the value of x increases, the delay error becomes larger, and it is only suitable for use where the delay is not required to be very accurate. So I thought of making some changes to the program, and wondering if 125 was too large. If it was changed to a variable, and the value of x is different, then some corrections can be made to the delay time, and the program is changed to the following:

void delayms (unsigned int x, unsigned char y)

{

unsigned char j;

while(x–)

{

for(j=0;j}

}

Using different y values ​​for different delay times, a “strange” phenomenon is found. When y=123, the error of the delay time is a fixed value:

x us

1 1017

2 2016

5 5016

10 10016

50 50016

100 100016

Except for x=1, the remaining errors are all 16us, that is, no matter how big x is, there is only 16us error. The accuracy is greatly improved, which can meet most of the needs!

The Links:   NL6448BC20-30F NL128102AC31-02E