Transferred from: http://blog.sina.com.cn/s/blog_980e19e00101b5dh.html
Sometimes precise delay is required, such as the 18B20 temperature sensor is very strict in timing requirements and must be accurate to the microsecond level
First, with the NOP function
In Keil C51, call the library function directly:
#include//declared void _nop_ (void);
_nop_ (); Produce a NOP instruction
Function: For the delay is very short, requirements in the US level, the use of "_nop_" function, this function quite assembly NOP instruction, delay a few microseconds. NOP instruction is a single-cycle instruction, can be calculated by the crystal frequency delay time, for 12M crystal oscillator, delay 1uS. (if 11.0592MHz, the delay is 12* (1/11.0592) =1.085us). For the longer delay, the requirement is greater than 10US, the use of C51 in the loop statement to achieve.
Second, with for and while implementation
There are a few issues to be aware of when looping statements in select C51
First, the definition of the C51 in the loop variable, as far as possible the use of unsigned character variables.
Second, in the FOR Loop statement, try to use variable subtraction to do the loop.
Thirdly, in the Do...while,while statement, the variable in the loop body also adopts the method of reducing and reducing.
This is because in the C51 compiler, different methods of looping are used to accomplish the different instructions.
The following examples illustrate:
unsigned char i;
for (i=0;i<255;i++);
unsigned char i;
for (i=255;i>0;i--);
Where the second loop statement C51 compiled, it is done with the djnz instruction, which is equivalent to the following instruction:
MOV 09H, #0FFH
LOOP:DJNZ 09h,loop
The instructions are fairly concise and good for calculating the exact delay time.
The same is true for Do...while,while loop statements.
Cases:
unsigned char n;
n=255;
do{n--}
while (n);
Or
n=255;
while (n)
{n--};
These two loop statements are C51 compiled to form a djnz to complete the method,
Therefore, the calculation of the precise time is also very convenient.
Third: For the requirements of the precise delay time is longer, then the loop nested method is used to achieve, therefore, the loop nesting method is often used to achieve MS-level delay. For loop statements, the same can be done with the for,do...while,while structure, and the variables in each loop body still use unsigned character variables.
unsigned char i,j
for (i=255;i>0;i--)
for (j=255;j>0;j--);
Or
unsigned char i,j
i=255;
do{j=255;
do{j--}
while (j);
i--;
}
while (i);
Or
unsigned char i,j
i=255;
while (i)
{j=255;
while (j)
{j--};
i--;
}
These three methods are implemented using the DJNZ instruction nested implementation loop, by the C51 compiler with the following combination of instructions to complete the
MOV R7, #0FFH
Loop2:mov R6, #0FFH
LOOP1:DJNZ R6,LOOP1
DJNZ R7,LOOP2
The combination of these instructions in assembly language using DJNZ instruction to do delay, so its time to accurately calculate is also very simple, false above the initial value of the variable i is m, the initial value of the variable j is n, then the total delay time is: MX (nxt+t), where T is djnz instruction execution time (DJNZ instruction is a double-cycle instruction). The +t here is the time used by this instruction of Mov. The same is true for longer delays, which can be done with multiple loops.
Just pay attention to the above issues when designing a looping statement.
Here are some questions to be aware of when delaying subroutine programming in C51
1, in the C51 in the precise time-delay subroutine programming, try not to or less in the delay subroutine to define local variables, all the delay subroutine in the variable through the function of the parameter passed.
2, in the time-delay sub-program design, the use of do...while, the structure of the loop body than for the structure to do a good loop.
3, in the time-delay sub-program design, to carry out the loop body nesting, the use of first internal circulation, and then reduce and reduce the ratio of first reduction, and then the internal circulation is better.
unsigned char delay (unsigned char i,unsigned char j,unsigned char k)
{unsigned char b,c;
B= "J";
C= "K";
do{
do{
do{k--};
while (k);
K= "C";
j--;};
while (j);
J=b;
i--;};
while (i);
}
This precise delay subroutine is compiled by C51 to have the following command combination complete
The delay latency subroutine is as follows:
MOV r6,05h
MOV r4,03h
C0012:djnz R3, C0012
MOV r3,04h
DJNZ R5, C0012
MOV r5,06h
DJNZ R7, C0012
Ret
Assuming that the initial value of the parameter variable i is m, the initial value of the parameter variable j is n, the initial value of the parameter variable K is L, then the total delay time is: LX (NX (MXT+2T) +2t) +3t, where T is the time of djnz and MOV instruction execution. When m=n=l, the precision delay is 9 T, the shortest, when m=n=l=256, accurate delay to 16908803T, the longest.
Above reference http://wenku.baidu.com/view/e79d80c40c22590102029da1.html
Three, the following describes how to use Keil simulation delay time
Test function:
void Tempdelay (unsigned char idata us)
{
while (us--);
}
Test Case:
Tempdelay (80); 530uS
Tempdelay (14); 100uS
NOP; 1.085uS
Operation:
1. Open debugging
2, starting time is 0.00059136s
3, the implementation of Tempdelay (80) After the time of 0.00112413s, when 0.00053277s=532.77us
4, the starting time here is 0.00112630s
5, after the execution of Tempdelay (14), changed to 0.00122938s, time 0.00010308s=103.08us
6, this is the implementation of a NOP instruction (crystal oscillator 11.0592MHz, microcontroller for STC89C52), the time is 0.00123047s, spents 0.00000109s=1.09us
About 51 precision delay and Keil simulation delay time