2590 views|1 replies

2015

Posts

0

Resources
The OP
 

Summary of MCU delay methods [Copy link]

There are usually two ways to achieve delay: one is hardware delay, which requires the use of timer/counter. This method can improve the CPU's working efficiency and achieve accurate delay; the other is software delay, which mainly uses a loop. 1 Use timer/counter to achieve accurate delay Microcontroller systems generally use 11.059 2 MHz, 12 MHz or 6 MHz crystal oscillators. The first one is easier to generate various standard baud rates, and the latter two have a machine cycle of 1 μs and 2 μs respectively, which is convenient for accurate delay. In this program, it is assumed that a crystal oscillator with a frequency of 12 MHz is used. The longest delay time can reach 216=65 536 μs. If the timer works in mode 2, an extremely short time of accurate delay can be achieved; if other timing modes are used, the time to reload the initial value of the timing should be considered (reloading the initial value of the timer takes 2 machine cycles). In practical applications, timing often uses interrupt mode. If a proper cycle is performed, a delay of several seconds or even longer can be achieved. Using a timer/counter to delay is the best solution from the perspective of program execution efficiency and stability. However, it should be noted that after the interrupt service program written in C51 is compiled, the PUSH ACC, PUSH PSW, POP PSW and POP ACC statements will be automatically added, which will take up 4 machine cycles when executed; if there is a count value plus 1 statement in the program, it will take up another machine cycle. The time consumed by these statements should be taken into account when calculating the initial value of the timing, and subtracted from the initial value to achieve the purpose of minimum error. 2 Software Delay and Time Calculation In many cases, the timer/counter is often used for other purposes. At this time, only software methods can be used for delay. Here are some software delay methods. 2.1 Short delay can be implemented in the C file by using a function with the _NOP_() statement. A series of different delay functions, such as Delay10us(), Delay25us(), Delay40us(), etc., can be defined and stored in a custom C file and called directly in the main program when needed. For example, a delay function with a delay of 10 μs can be written as follows: void Delay10us( ) { _NOP_( ); _NOP_( ); _NOP_( ); _NOP_( ); _NOP_( ); There are 6 _NOP_() statements in the Delay10us() function, and each statement takes 1 μs to execute. When the main function calls Delay10us(), it first executes a LCALL instruction (2 μs), then executes 6 _NOP_() statements (6 μs), and finally executes a RET instruction (2 μs). Therefore, it takes a total of 10 μs to execute the above function. This function can be used as a basic delay function and called in other functions, that is, nested calls [4], to achieve a longer delay; but it should be noted that if the Delay10us() function is directly called 4 times in Delay40us(), the delay time will be 42 μs, not 40 μs. This is because when executing Delay40us(), a LCALL instruction (2 μs) is first executed, then the first Delay10us() is executed, and when the last Delay10us() is executed, it returns directly to the main program. Similarly, if there are two levels of nested calls, such as calling Delay40us() twice in Delay80us(), the LCALL instruction (2 μs) must be executed first, and then the Delay40us() function (84 μs) must be executed twice, so the actual delay time is 86 μs. In short, only the innermost function executes the RET instruction. This instruction returns directly to the parent function or the main function. For example, if Delay10us() is called 8 times directly in Delay80μs(), the delay time is 82 μs. By modifying the basic delay function and calling it in appropriate combinations, the above method can achieve delays of different times. 2.2 Nesting assembly program segments in C51 to achieve delay In C51, assembly language statements can be nested through the preprocessing instructions #pragma asm and #pragma endasm. The assembly language written by the user follows #pragma asm and ends before #pragma endasm. Such as: #pragma asm [ /size] Assembly language program segment [color=#0 00000] #pragma endasm The delay function can set the entry parameters, and the parameters can be defined as unsigned char, int or long type. According to the transmission rules of parameters and return values, the parameters and function return values are located in R7, R7R6, R7R6R5. The following points should be noted when applying: ◆ #pragma asm and #pragma endasm are not allowed to be nested; ◆ The preprocessing instruction #pragma asm should be added at the beginning of the program. Only comments or other preprocessing instructions can be placed before this instruction; ◆ When using the asm statement, the compiler system does not output the target module, but only outputs the assembly source file; ◆ asm can only use lowercase letters. If asm is written in uppercase, the compiler system will treat it as an ordinary variable; ◆ #pragma asm, #pragma endasm and asm can only be used within functions. Combining assembly language with C51 and giving full play to their respective advantages is undoubtedly the best choice for microcontroller developers. 2.3 Use an oscilloscope to determine the delay time Use an oscilloscope to measure the execution time of the delay program. The method is as follows: Write a function to implement delay, set a certain I/O line such as P1.0 to a high level at the beginning of the function, and clear P1.0 to a low level at the end of the function. Call the delay function in the main program in a loop, and measure P1.0 through an oscilloscope.The high level time on pin 0 can determine the execution time of the delay function. The method is as follows: 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 an oscilloscope and run the above program, you can see that P1.The waveform output by 0 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 loops, different delay times can be obtained. Of course, you can also use other statements instead of for loops to achieve delay. What is discussed here is only the method of determining the delay. 2.4 Use the disassembly tool to calculate the delay time 2.4 Use the disassembly tool to calculate the delay time Use the disassembly tool in Keil C51 to calculate the delay time. In the disassembly window, the target application can be displayed using a mixed code of the source program and the assembler program or the assembly code. To illustrate this method, also use "for (i=0;i C:0x000FE4CLRA//1T [color=#0 00000] C:0x0010FEMOVR6,A//1T C:0x0011EEMOVA,R6//1T C:0x0012C3CLRC/ /1T C:0x00139FSUBBA,DlyT //1T [backcolor =white] C:0x00145003JNCC:0019//2T C:0x001 60E INCR6//1T C:0x001780F8SJMPC:0011//2T [ color=#000000] It can be seen that there are 8 statements from 0x000F to 0x0017. By analyzing the statements, it can be found that not every statement is executed DlyT times. The core loop has only 6 statements from 0x0011 to 0x0017, with a total of 8 machine cycles. The first loop first executes the two statements "CLR A" and "MOV R6, A", which requires 2 machine cycles. Each loop requires 8 machine cycles, but the last loop requires 5 machine cycles. DlyT core loop statements consume (2+DlyT×8+5) machine cycles. When the system uses 12 MHz, the accuracy is 7 μs. When the 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 [color=#0 00000] C:0x00111F DECR7//1T [color=#000 000]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 accuracy of this loop structure is 5 μs. Through experiments, it was found that if while (DlyT--) is changed to while (--DlyT), the following code is obtained after disassembly: C:0x0014DFFE DJNZR7,C:0014//2T It can be seen that at this time, there is only one code sentence, which takes up 2 machine cycles in total, with an accuracy of 2 μs. The loop body takes DlyT×2 machine cycles; but it should be noted that the initial value of DlyT cannot be 0. Note: When calculating the time, the 2 machine cycle time for function calls and function returns should also be added. Part 2 Statement: The author is a beginner in single-chip microcomputer programming. In the spirit of exploration, he has conducted a thorough analysis of the delay code, calculated the error, and adjusted it according to the machine cycle occupied by different codes. As for the practical significance of adjusting the time error of about 0.01ms for practical applications, I dare not talk about it. However, after reading the green part of this article, you can clearly understand the design method of the delay program. Example program paragraph: ; System frequency: 6MHz Delay: MOV R5,#25 ;5ms delay——MOV instruction takes 1 machine cycle time Delay1: MOV R6,#200 ;200ms delay Delay2: MOV R7,#166 ;1ms delay constant Delay3: NOP ; Empty instruction, do nothing, stay for 1 machine cycle time DJNZ R7, Delay3 ; R7 minus 1 is assigned to R7. If R7 is not equal to zero at this time, jump to Delay3 to execute. ——2 machine cycle time DJNZ R6,Delay2 DJNZ R5,Delay1 The analysis is as follows: 1. First, calculate the machine cycle T=12*1/f=2μs. 2. Note that DJNZ R7, Delay3 needs to occupy the time of NOP and DJNZ itself for each execution, a total of 3 machine cycles. 6μs. Then 1ms takes 1ms*1000/6μs=166.67, so take 166. 3. Note that DJNZ R6, Delay2 is executed once after 166 cycles (the time is the MOV machine cycle + its own machine cycle, 3*2=6μs). DJNZ R5, Delay1 is not executed until 166*200 times, when R6=0. 4. DJNZ R5, Delay1 is when R5 is not 0, it will loop back. The time is also 6μs. 5. Total time: 166*200*25*6μs+200*25*6μs+25*6μs=5010150μs, totaling 5.01015ms (programmers have encountered similar escape loops. This program ignores the time to execute MOV and only calculates the time used for the loop, that is, 166*200*25*6/1000000=4.98ms, approximately 5ms). Program improvement: Remove NOP commands and integerize the delay constant required for 1ms. Delay: MOV R5,#25;5ms delay - MOV instruction takes 1 machine cycle time [color=#000000 ] Delay1: MOV R6,#200 ;200ms delay [color=#00000 0]Delay2: MOV R7,#250 ;1ms delay constant Delay3: ;NOP ;Null instruction, do nothing, stay for 1 machine cycle time DJNZ R7,Delay3 ;R7 minus 1 and assign it to R7. If R7 is not equal to zero at this time, jump to Delay3 to execute. ——2 machine cycle time DJNZ R6,Delay2 color] DJNZ R5,Delay1 The total time at this time is: 250*200*25*4μs+200*25*6μs+25*6μs=5030150μs. The time occupancy error is larger than that before improvement. It can be corrected by R7-30150/(25*200*4)=248 (because R7=250 takes 2 machine cycles, 4μs, and the calculation is equal to R7-1.5075,Reduce the time to less than 5ms, and fill in the remaining time, taking 248). Then: the total time is: 248*200*25*4μs+200*25*6μs+25*6μs=4990150μs, and the required time is: 5000000-4990150=9850μs, 9850/2=4925 machine cycles. Filling a MOV R4,#200, 4 NOPs, requires another 4920 machine cycles, which can be reduced to 24*205=4920. How to establish a function and adjust it according to the actual code, as follows: Delay: MOV R5,#25 ;5ms delay——MOV instruction takes 1 machine cycle time Delay1: MOV R6,#200 ;200ms delay Delay2: MOV R7,#250 ;1ms delay constant Delay3: ;NOP ;Null instruction, do nothing, stay for 1 machine cycle time DJNZ R7,Delay3 ;R7 minus 1 and assign it to R7. If R7 is not equal to zero at this time, jump to Delay3 to execute. ——2 machine cycle time DJNZ R6,Delay2 color] DJNZ R5,Delay1 NOP[/ size] NOP NOP [ size=4] NOP [back color=white]MOV R3,#6 Delayadd: MOV R4,#205 MOV R2,#0H DJNZ R3,Delayadd Analysis: 205*24 is adjusted to 205*6——This is because the Delay loop is a 4-machine cycle code, so 24/4=6. Please calculate: 205*6*4=4920;4920+5=4925. The time addition is just right. At this time, the time calculation is: 248*200*25*4μs+200*25*6μs+25*6μs=4990150μs+4925*2μs=5000000μs, a total of 5ms. Theoretically, 1μs is not bad (this is just for scientific discussion, the author is not clear about the specific error of the crystal frequency).

This post is from Microcontroller MCU

Latest reply

It's messy, not clear, and not systematic.  Details Published on 2019-2-22 08:40
 

6366

Posts

4937

Resources
2
 
It's messy, not clear, and not systematic.
This post is from Microcontroller MCU
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list