Lighting display with time-delay program[Copy link]
Light display with delay program After the previous stage of learning, we finally wrote a program that can control the change of light. In practical applications, this program can be used to control light-emitting diodes, relays, and thyristors. However, for relays, thyristors, and other devices that require high power, they cannot be driven directly by a single-chip microcomputer. They must be connected to transistors or integrated circuits at the output to expand the driving capacity.
Following the previous explanation, you can change the order of light display according to your needs, or change the display pattern. However, the previous program has a disadvantage, that is,
whether it is necessary to press a button for each step of operation in actual work? If so, it is better to use manual control directly. In fact, the manual operation just now is designed for debugging the program to check the experimental effect. With manual operation, each step forward, if the result of the operation is different from the design, you can stop and check the reason. In computer debugging, it is called "single-step operation". The corresponding program running by itself is called "continuous operation".
If after the program is entered, K1 (marked with SE) is turned to the "E" side, and instead of pressing the STEP key, the EXE key is pressed once, the program will run by itself, and the word "厂" will be displayed on the motherboard. Its original meaning is to display the English "r" (run means to run), but the shape is quite different.
At this time, observe the LED of the experimental board again. It does not appear to be displayed in turn as imagined, but all are on, but the brightness is a little lower than before. What is going on? In the manual experiment, each change is manually operated, and the process is very slow. The phenomenon of light conversion can be clearly observed. The computer runs directly, and the speed is much faster than manual operation. Although the lights are displayed in turn, the lights are observed to be connected due to the lag effect of the eyes. However, each light is only lit for one-tenth of the time (think about why?), so it looks dark.
In order to observe the effect of alternating light, it is necessary to let the computer pause for a period of time after each conversion, but the computer cannot be stopped, so a program is added after each light change to let the computer waste some time before running the next step. This program is called a "delay program". Delay programs are widely used in computer programs.
For the sake of simplicity, only two sets of light transformation programs are given, and readers can expand them according to the principle. Program 2, delayed light change 8000 1 0RG 800H 8000 7590AA 2 LOOP: MOV P1, #0AAH; Light 1 8003 7FFF 3 MOV R7, #OFFH; Preset R7 to 255 8005 7EFF 4 WAIT1: MOV R6, #OFFH; Preset R6 to 255 8007 00 5 WAIT1: NOP; No operation 8008 DEFD 6 DJNZ R6, WAIT2; R6 decrements 1, if not zero, returns to DELA2 800A DFF9 7 DJNZ R7, WAIT1; R7 decrements 1, if not zero, returns to DELA1 800C 759055 8 MOV P1, #055H; Light 2 800F 7FFF 9 MOV R7, #0FFH; preset R7 to 255 8011 7EFF 10 WAIT3: MOV R6, #0FFH; preset R6 to 255 8013 00 11 WAIT4: NOP; no operation 8014 DEFD 12 DJNZ R6, WAIT4; R6 decrement by 1, if not zero, return to DELA2 8016 DFF9 13 DJNZ R7, WAIT3 1R7 decrement by 1, if not zero, return to DELA1 8018 0100 14 AJMP LOOP 15 END
Compared with program 1, this program uses two registers, R6 and R7. In a single-chip microcomputer, 8 registers can be used at the same time, namely R0, R1...R7. What are so many registers used for? In a complex program, many operations need to be performed, and the initial values and intermediate results of the operations can be saved in registers. If there are too few registers, the operation will be inconvenient. In our program, two registers are used, and it doesn't matter which one is used.
The following is an explanation of the improved part of program 2: Lines 3 and 4 pre-send 0FFH (equal to 255 in decimal) to the R7 and R6 registers. Then execute a no-operation (NOP) instruction, which does nothing except consuming a period of time (two microseconds). The function of the DJNZ R6, WAIT2 instruction is: decrement R6 by 1, and determine whether it reaches 0. If it does not reach 0, return to WAIT2, and execute NOP (no-operation instruction) again... until it loops 255 times, R6 decreases to 0, and executes the next instruction. This instruction also consumes 2 microseconds. The
subsequent DJNZ R7, WAIT3 has the same function as the previous one. When R7 is decremented by 1 and is not equal to 0, it returns to WAIT3, sets R6 to 0FFH again, and R6 is decremented again. In this way, a total of 65025 cycles (255x255) are looped. On the Dp-851K machine, each cycle consumes 4 microseconds, a total of about 0.3 seconds, that is, each time the light changes, it pauses for 0.3 seconds. As the time is extended, the light changes can be clearly observed. The delay time can be changed by changing the setting values of R6 and R7.
Input the machine code of Program 2 into the single-chip microcomputer and experiment with the continuous operation mode. Is it as analyzed above? However, if you go through it step by step in a single-step manner, even if you press the keyboard twice a second, it will take 18 hours to complete a cycle, while the computer only takes 0.3 seconds. This is the difference between computers and humans!
In Program 2, the two delay programs are very similar: lines 3-7 and lines 9-13. If you add a light change instruction, you must also add a delay program after it, so that the whole program seems very cumbersome. Can these programs be simplified? Absolutely, this requires the use of program form.
Programs that need to be used in multiple places in the program are compiled into an independent part called a "subroutine". Add a label to the first line of the subroutine as the name of the subroutine, and the last line must be the return instruction RET. Just add a call instruction CALL XXXX where the program is used. Here XXXX is the name of the subroutine, that is, the entry address of the subroutine. The above example can be adapted as follows: Program 3: Light change using delay subroutine 8000 1 0RG 800H 8000 7590AA 2 LOOP: MOV P1, #0AAH; Light 1 8003 110C 3 ACALL WAIT ; Call delay subroutine 8005 759055 4 MOV P1, #055H ; Light 2 8008 110C 5 ACALL WAIT ; Call delay subroutine 800A 0100 6 AJMP L00P 800C 7FFF 8 WAIT: MOV R7, #0FFH; Preset R7 to 255 800E 7EFF 9 WAIT1 : MOV R6, #0FFH; Preset R6 to 25 8010 00 10 WAIT2: NOP; No operation 8011 DEFD 11 DJNZ R6, WAIT2; R6 decremented by 1, if not zero, return to DELA2 8013 DFF9 12 DJNZ R7, WAIT1; R7 decremented by 1, if not zero, return to DELA1 13 END In this program, a delay subroutine called "WAIT" is written. The content of the delay program is the same as lines 3-7 of the previous program 2, but the main program is much simpler, and the subroutine is also clear after it is independent. There are also some advantages to using it in the program: the modules that have been successfully debugged can be compiled into subroutines, which can be used directly in the future without having to be rewritten. When debugging a large program, decomposing a large program into several subroutines can make the program flow clear and facilitate debugging and speeding up the progress. There are several issues to pay attention to when using subroutines: 1. Each subroutine must have a unique name to facilitate the specification when calling the main program. 2. The last line of the subroutine must be a return instruction (RET). 3. The registers used in the subroutine cannot conflict with the main program. In the above example, the subroutine uses R6 and R7. In the main program, you cannot use R6 and R7 to store data before or after calling the subroutine. For example, the following program will have an error. MOV R6, #05H MOV R7, #06H ACALL WAIT MOV A, R6 ADD A, R7 …… WAIT: MOV R7, #0FFH; preset R7 to 255 WAIT1: MOV R6, #0FFH; preset R6 to 255 WAIT2: NOP; no operation DJNZ R6, WAIT2; R6 is reduced by 1, and if it is not zero, it returns to DELA2 DJNZ R7, WAIT1; R7 is reduced by 1, and if it is not zero, it returns to DELAI END The original intention of the program is to save data in R6 and R7, and calculate the sum of R6 and R7 after the delay. However, in the subroutine WAIT, R6 and R7 have been used (the actual values are both 0 in the end). The result of the subsequent addition operation is not the expected 0BH (binary 05H + 06H = 0BH) but 0. What if there is a conflict between the registers used by the main program and the subroutine? We will talk about it later, and we can use the stack method to solve it.