“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.
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