The following are the delay programs of the MCU (including asm and C programs, which are used in the process of learning MCU). In the MCU delay program, the frequency of the crystal used should be considered. In the 51 series MCU. We usually use the crystal oscillators of 11.0592MHz and 12.0000MHz, and the crystal oscillators of 8.000MHz and 4.000MH are commonly used on AVR microcontrollers. Therefore, if the precise delay is involved in the online search procedure, you should pay attention to the frequency of the crystal oscillator.
Software delay: (asm)
Crystal 12MHZ, delay 1 second
The procedure is as follows:
DELAY: MOV 72H, #100
LOOP3: MOV 71H, #100
LOOP1: MOV 70H, #47
LOOP0JNZ 70H, LOOP0
NOP
DJNZ 71H, LOOP1
MOV 70H, #46
LOOP2JNZ 70H, LOOP2
NOP
DJNZ 72H, LOOP3
MOV 70H, #48
LOOP4JNZ 70H, LOOP4
Timer delay:
Crystal oscillator 12MHZ, delay 1s, timer 0 working mode is mode 1
DELAY1: MOV R7, #0AH ;; Crystal 12MHZ, delay 0.5 seconds
AJMP DELAY
DELAY2: MOV R7, #14H ;; Crystal 12MHZ, delay 1 second
DELAY: CLR EX0
MOV TMOD, #01H ; Set the working mode of the timer to mode 1
MOV TL0, #0B0H ; set the initial value of the timer
MOV TH0, #3CH
SETB TR0; turn on the timer
HERE: JBC TF0, NEXT1
SJMP HERE
NEXT1: MOV TL0, #0B0H
MOV TH0, #3CH
DJNZ R7, HERE
CLR TR0; timer to be cleared by software
SETB EX0
RET
C language delay program:
Void delay_18B20(unsigned int i)
{
While(i--);
}
Void Delay10us( ) //12mhz
{
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
}
/*****************11us delay function*************************/
//
Void delay(uint t)
{
For (;t>0;t--);
}
1ms delay subroutine (12MHZ)
Void delay1ms(uint p)//12mhz
{ uchar i,j;
For(i=0;i
{
For(j=0;j<124;j++)
{;}
}
}
Function: subroutine with a delay of 20ms
************************************************** ************/
Void delay20ms(void) //3*i*j+2*i=3*100*60+2*100=20000μs=20ms;
{ //(3*60+2)*100
Unsigned char i,j;
For(i=0;i<100;i++)
For(j=0;j<60;j++)
;
}
10ms delay subroutine (12MHZ)
Void delay10ms(void)
{
Unsigned char i,j,k;
For(i=5;i>0;i--)
For(j=4;j>0;j--)
For(k=248;k>0;k--);
}
((248*2+3)*4+3)*5+5=10ms
1s delay subroutine (12MHZ)
Void delay1s(void)
{
Unsigned char h,i,j,k;
For(h=5;h>0;h--)
For(i=4;i>0;i--)
For(j=116;j>0;j--)
For(k=214;k>0;k--);
}
200ms delay subroutine (12MHZ)
Void delay200ms(void)
{
Unsigned char i,j,k;
For(i=5;i>0;i--)
For(j=132;j>0;j--)
For(k=150;k>0;k--);
}
500ms delay subroutine program: (12MHZ)
Void delay500ms(void)
{
Unsigned char i,j,k;
For(i=15;i>0;i--)
For(j=202;j>0;j--)
For(k=81;k>0;k--);
}
The following are several delay programs using a crystal oscillator of 8.000 MHz (working mode 1 with timing 0):
(1) Delay 0.9MS
Void delay_0_9ms(void)
{
TMOD=0x01; /* Timer 0 works in mode 1 (16-bit counter)*/
TH0=0xfd;
TL0=0xa8;
TR0=1; /* start timer*/
While(TF0==0);
TR0=0;
}
(2) Delay 1MS
Void delay_1ms(void)
{
TMOD=0x01; /* Timer 0 works in mode 1 (16-bit counter)*/
TH0=0xfd;
TL0=0x65;
TR0=1; /* start timer*/
While(TF0==0);
TR0=0;
}
(3) Delay 4.5ms
Void delay_4_5ms(void)
{
TMOD=0x01; /* Timer 0 works in mode 1 (16-bit counter)*/
TH0=0xf4;
TL0=0x48;
TR0=1; /* start timer*/
While(TF0==0);
TR0=0;
}
If you are too lazy to calculate the initial value of the timer count when using the timer to do the delay program, you can find a small software specially used for delay in the Internet. I feel very practical when using it. If you can't find it, you can leave a message and leave it. I sent it to my own mailbox; if there is an error in the above delay, please correct me.
Several precise delay methods in Keil C51 programming
There are usually two methods for delay: one is hardware delay, and the timer/counter is used. This method can improve the CPU efficiency and precise delay. The other is software delay. The method is mainly carried out using a loop body.
1 Use timer/counter to achieve precise delay
A single-chip system typically uses a 11.059 2 MHz, 12 MHz or 6 MHz crystal. The first is easier to produce a variety of standard baud rates, the latter two machine cycles are 1 μs and 2 μs, respectively, for precise delay. It is assumed in this program that a crystal with a frequency of 12 MHz is used. The longest delay time is 216 = 65 536 μs. If the timer works in mode 2, the precise delay can be realized in a very short time; if other timing methods are used, the time of reinstalling the initial value of the timing should be considered (the initial value of the reloading timer takes 2 machine cycles).
In practical applications, the interrupt method is often used for timing, and a delay of several seconds or longer can be realized by performing an appropriate cycle. Using the timer/counter delay is the best solution from both program execution efficiency and stability. However, it should be noted that the interrupt service program written by C51 will automatically add PUSH ACC, PUSH PSW, POP PSW and POP ACC statements after compiling, which takes up 4 machine cycles; if there is a count value plus 1 statement in the program, It will take up 1 machine cycle. The time consumed by these statements is taken into account when calculating the initial value of the timing, and subtracted from the initial value to achieve the minimum error.
2 software delay and time calculation
In many cases, the timer/counter is often used for other purposes, and only software methods can be used to delay this time. Here are a few ways to delay software.
2.1 short delay
Can be implemented in the C file by using the function with _NOP_ () statement, define a series of different delay functions, such as Delay10us (), Delay25us (), Delay40us (), etc. stored in a custom C file, you need It is called directly in the main program. For example, a delay function with a delay of 10 μs can be written as follows:
Void Delay10us( ) {
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
}
There are six _NOP_( ) statements in the Delay10us( ) function, and each statement executes for 1 μs. When the main function calls Delay10us( ), it first executes an LCALL instruction (2 μs), then executes six _NOP_( ) statements (6 μs), and finally executes a RET instruction (2 μs), so it is necessary to execute the above functions. 10 μs. This function can be regarded as a basic delay function, which is called in other functions, that is, nested call [4] to achieve a longer time delay; but note that if you call 4 times Delay10us directly in Delay40us( ) With the ( ) function, the resulting delay time will be 42 μs instead of 40 μs. This is because when the Delay40us( ) is executed, the LCALL instruction (2 μs) is executed first, then the first Delay10us( ) is executed, and when the last Delay10us( ) is executed, it returns directly to the main program. And so on, if it is a two-level nested call, such as calling Delay40us() twice in Delay80us(), it must also execute the LCALL instruction (2 μs) first, and then execute the Delay40us() function (84 μs) twice. Therefore, the actual delay time is 86 μs. In short, only the innermost function executes the RET instruction. This instruction returns directly to the superior function or the main function. If 8 times Delay10us( ) is called directly in Delay80μs( ), the delay time is 82 μs. By modifying the basic delay function and the appropriate combination call, the above method can achieve delays at different times.
2.2 Nesting the assembler segment in C51 to achieve delay
In C51, assembly language statements can be nested by preprocessing directives #pragma asm and #pragma endasm. The user-written assembly language follows #pragma asm and ends before #pragma endasm.
Such as: #pragma asm
...
Assembly language block
...
#pragma endasm
The delay function sets the entry parameters, which can be defined as unsigned char, int or long. According to the rules of the parameters and return values, the parameters and function return values ​​are located in R7, R7R6, R7R6R5. Pay attention to the following points when applying:
â—† #pragma asm, #pragma endasm are not allowed to be nested;
â—† The preprocessor directive #pragma asm should be added at the beginning of the program. There can only be comments or other preprocessor directives before the directive.
â—† When using the asm statement, the compilation system does not output the target module, but only the assembly source file;
â—† asm can only use lowercase letters. If you write asm to uppercase, the compilation system will use it as an ordinary variable.
â—† #pragma asm, #pragma endasm, and asm can only be used within a function.
Combining assembly language with C51 and giving full play to their respective advantages is undoubtedly the best choice for microcontroller developers.
2.3 Determine the delay time using the oscilloscope
Use an oscilloscope to determine the delay program execution time. The method is as follows: Write a function that implements the delay. At the beginning of the function, set an I/O line such as P1.0 to a high level, and clear P1.0 to a low level at the end of the function. The delay function is called cyclically in the main program, and the execution time of the delay function can be determined by measuring the high time on the P1.0 pin through the oscilloscope. Methods as below:
Sbit T_point = P1^0;
Void Dly1ms(void) {
Unsigned int i,j;
While (1) {
T_point = 1;
For(i=0;i<2;i++){
For(j=0;j<124;j++){;}
}
T_point = 0;
For(i=0;i<1;i++){
For(j=0;j<124;j++){;}
}
}
}
Void main (void) {
Dly1ms();
}
Connect P1.0 to the oscilloscope and run the above program. You can see that the waveform of P1.0 output is a square wave with a period of 3 ms. Among them, the high level is 2 ms and the low level is 1 ms, that is, the execution time of the for loop structure "for(j=0; j<124; j++) {;}" is 1 ms. By changing the number of cycles, you can get delays at different times. Of course, you can use other statements to implement the delay without the for loop. The only discussion here is the way to determine the delay.
2.4 Using the disassembly tool to calculate the delay time
The delay time is calculated using the disassembly tool in Keil C51, and the target application can be displayed in the disassembly window using the mixed code or assembly code of the source and assembler. To illustrate this method, also use "for (i=0;i
C: 0x000FE4CLRA / / 1T
C: 0x0010FEMOVR6, A//1T
C: 0x0011EEMOVA, R6//1T
C: 0x0012C3CLRC//1T
C: 0x00139FSUBBA, DlyT //1T
C: 0x00145003JNCC: 0019//2T
C: 0x00160E INCR6//1T
C: 0x001780F8SJMPC: 0011//2T
It can be seen that there are 8 statements from 0x000F to 0x0017. The analysis statement can find that not every statement executes DlyT times. The core loop has only 6 statements from 0x0011 to 0x0017, a total of 8 machine cycles. The first cycle executes the two statements "CLR A" and "MOV R6, A". It takes 2 machine cycles, and each cycle requires 8 cycles. Machine cycles, but the last cycle requires 5 machine cycles. The DlyT sub-core loop statement consumes (2+DlyT×8+5) machine cycles, and the accuracy is 7 μs when the system uses 12 MHz.
When a while (DlyT--) loop body is used, the value of DlyT is stored in R7. The corresponding assembly code is as follows:
C: 0x000FAE07MOVR6, R7//1T
C: 0x00111F DECR7//1T
C: 0x0012EE MOVA, R6//1T
C: 0x001370FAJNZC: 000F//2T
The execution time of the loop statement is (DlyT+1) × 5 machine cycles, that is, the delay precision of this loop structure is 5 μs.
Through experiments, if you change while (DlyT--) to while (--DlyT), after disassembly, you get the following code:
C: 0x0014DFFE DJNZR7, C: 0014//2T
It can be seen that at this time, the code has only one sentence, occupying 2 machine cycles, the precision is 2 μs, and the loop body consumes DlyT × 2 machine cycles; however, it should be noted that the initial value of DlyT cannot be 0.
Note: The time and function should be added to the function call and the function returns 2 machine cycle times.
Waterproof Connector,Idc Connector,Idc Socket Connector,Horizontal Waterproof Idc Socket Connector
Shenzhen Jinyicheng Electronci Technology Co.,Ltd. , https://www.jycconnector.com