A collection of EMC microcontroller programming skills
EMC single-chip programming skills collection (conversion)
Professional PCB proofing, fast delivery, Taiwan quality
Since the EM78XXX single chip came out, more than ten different grades of single chips have been launched, ranging from 78P152 with 8Pin to 78P860 with 100Pin OTP. The assembly language instructions are the same, only 57, so I repeated the practice several times. You can become familiar with the usage of instructions. Assembly language is very easy to use in I/O control and has high efficiency. Therefore, most of the books in the shop mainly focus on discussing control, and there is not much space dedicated to discussing software techniques. In fact, veterans know that the control of chips is often Go through DATA when you use it
BOOK, pay attention to TIMING, and then prepare an oscilloscope, and you can do it in threes or twos. On the contrary, whether the algorithm is used well or not will greatly affect the stability of the product, so experienced programmers usually have their own set of sunflower secrets, so the best way to improve your skills is to practice more. Other people's programs will also make you progress quickly.
Convert BCD to Binary
Since EM78XXX is an 8-bit microcontroller, in order to save memory, our example only uses a BYTE to store two BCD numbers as an example. The range of the numbers is between 0 and 99. The converted result is placed in ACC. If you Need more digits, I believe you should not be difficult to modify after reading.
Procedure one
This example program costs 13 instructions CYCLE in total, and requires two variable spaces, which will affect the contents of the original BCD after execution.
MOV A, BCD
MOV TMP,A
MOV A,@0x0F
AND TMP,A
SWAP BCD
AND BCD,A
BC PSW,0
RLC BCD; *2
MOV A, BCD
ADD TMP,A
RLC BCD
RLCA BCD; *8
ADD A, TMP
Description
The method used in program one should be considered the most well-known method, and it is also the most intuitive method. First save the BCD single digit, because the tens digit must be multiplied by 10, so use the shift technique to multiply Add 10 to the single digit, and put the answer into ACC.
Procedure two
The disadvantage of program one is that after the program is executed, the original BCD content has been destroyed in the process of shifting. In order to improve this deficiency, let's look at it in another way. In the following program, we are trying to improve the previous defect. It costs 11 instructions CYCLE and still needs two variable spaces, but it will not destroy the original BCD content after execution.
SWAPA BCD
MOV TMP,A
MOV A,@0x0F
AND BCD,A
AND TMP,A
BC PSW,0
RLCA TMP
SWAP TMP
RRC TMP
ADD A, TMP
ADD A,BCD
Procedure Three
We are still dissatisfied with the result of program two. It seems to be a little too complicated. Although the speed has been improved, there is still room for memory allocation, so we improved to the type of program three. The conversion process only costs 10 instructions CYCLE, and only one variable space is needed, and the contents of the original BCD will not be changed after execution.
MOV A,@0x0f
AND A, BCD
JBC BCD, 4
ADD A,@10
JBC BCD,5
ADD A,@20
JBC BCD, 6
ADD A,@40
JBC BCD,7
ADD A,@80
Description
After reading the above three examples, do you think the third procedure is the most concise and easy to understand? Writing a program is indeed a very challenging task, and you can find a lot of inspiration and fun, you can't think of it!
Binary to BCD code
The following example program will convert the binary number stored in the ACC into a two-digit BCD code (Compacted BCD Code). The largest BCD code that can be converted is 99.
CLR BCD
DIGIT_HI:
ADD A,@256-10
JBS PSW,FC
JMP DIGIT_LO
INC BCD
JMP DIGIT_HI
DIGIT_LO:
ADD A,@10
SWAP BCD
OR BCD,A
The trap of subtraction
The subtraction instruction of EM78 series assembly language is SUB. You must pay special attention when using this instruction, because ACC is always a subtraction and cannot be a subtract. The syntax of the SUB instruction has the following three types:
SUB A,R (R-A→A)
SUB R,A (R-A→R)
SUB A,K (K-A→A)
In other words, if we want to calculate the value of A-2, if we write:
SUB A,@2
In fact, the implementation of 2-A, the solution is as follows:
ADD A,@256-2 or
ADD A,@254
Exchange the contents of two sets of buffers
If you think that you must borrow the third set of variables to exchange the contents of the two sets of memory, then you can refer to the following way, just use some mathematical skills to become fast and simple.
MOV A,REG1
SUB A,REG2
ADD REG1,A
SUB REG2,A
Principle explanation
A=REG1
A=REG2-REG1
REG1=REG1+A
=REG1+(REG2-REG1)
=REG2
REG2=REG2-(REG2-REG1)
=REG1
If X>Y, swap...
Continuing the previous example, this method is particularly useful in Bubble Sort.
MOV A,X
SUB A,Y
JBC PSW,FC
JMP NO_CHANGE
ADD X,A
SUB Y,A
2's complement
2's complement addition often replaces subtraction. The traditional approach is to take 1's complement first and then add 1.
COM REG
INC REG
Or it can be obtained in another way, the difference is that the second way will affect the PSW buffer.
ADD A,REG
SUB A,REG
If the number you requested has been placed in the ACC, then only one line can be solved.
SUB A,@0
Rotate byte operation
In the 8051 instruction, there are RLC and RL instructions for left-handed rotation. RLC will rotate CY together when ACC is left-handed, while RL will only rotate the MSB of ACC into LSB. The EM78XXX instruction only has RLC, so how can it be rotated without CY? The answer is two rotations:
RLCA REG1
RLC REG1
As shown in Figure 1, the first bit rotation does not really change the content of REG1. The purpose is to put the MSB of REG1 into the FC first, and the second bit rotation turns the MSB just placed in the FC into the LSB. In the same way, the bit rotation of two BYTES without FC is the same principle.
RLCA HI_BYTE
RLC LO_BYTE
RLC HI_BYTE
Range judgment
Writing programs will inevitably encounter IF..THEN.. occasions, some people think that the conditional judgments of EM78XXX are too cumbersome, so the author also organizes them. Conditional judgment formula can be divided into open interval conditional formula and closed interval conditional formula to discuss, as shown in Figure 2.
The open conditional formula is based on point N as the starting point. The conditional judgment when the value to be measured is greater than N or less than or equal to N is described in the syntax of C as follows:
if(number>n)
... /* number is greater than N */
else
... /* number is less than or equal to N */
EM78XXX assembly language is written as follows:
MOV A,@N+1
SUB A,Number
JBC PSW,FC
JMP LABEL_1; greater than N
JMP LABEL_2; less than or equal to N
The closed condition judgment refers to whether the measured value N is within the range of X and Y, if it is described in C syntax:
if((number>=x) && (number<=y))
.... /* in range */
else
.... /* False */
How to do it in EM78 assembly language? The general practice is to make conditional judgment based on the PSW after subtraction. The procedure is as follows:
MOV A,@2
SUB A,number
JBS PSW,FC
JMP FALSE
MOV A,@y+1
SUB A,SI
JBC PSW,FC
JMP FALSE
IN_RANGE:
; ....
FALSE:
; ....
This IF conditional takes 8 instructions Cycle, which is not too complicated. But there is a more concise method, the following uses the PSW (R3) after the addition as a conditional judgment, a total of 5 lines are clean.
MOV A,Number
ADD A,@255-y
ADD A,@y-x+1
JBC PSW,FC
JMP IN_RANGE
FALSE:
; ....
IN_RANGE:
; ....
Description
The key lies in the first three lines. x represents the lower limit of the conditional formula, and y represents the upper limit of the conditional formula. It can be seen that the special effects are still made with the CY flag. Not only are they streamlined but also a little clever, many veterans love to use them. , This is also one of the secret weapons in their pockets. If you think it's good, you might as well include it in the tips, and then you can follow the same pattern.
ACC and cache content exchange
For this reason, we are going to introduce a fast logic algorithm, only 3 instructions CYCLE, you can exchange the contents of the ACC and the contents of the register, no muddle, Very cute!
XOR Number,A
XOR A,Number
XOR Number,A
Readers are asked to calculate on the paper by themselves, and then they will know the answer.
Exchange the contents of multiple buffers
Using the method introduced above, it can be extended to the example of multiple sets of buffer exchange. The following program shifts the contents of 5 sets of DATA. The data in the first buffer is transferred to the second buffer. The data is then transferred to the third buffer, and so on, the last data is transferred to the first buffer, forming a kind of byte data rotation.
MOV A,@5
MOV COUNT,A
MOV A,@DATA1
MOV RSR,A
MOV A,DATA5
NEXT:
XOR INDIR,A
XOR A, INDIR
XOR INDIR,A
INC RSR
DJZ COUNT
JMP NEXT
Calculate MOD 2N
If you just need to calculate ACC MOD X, and X is exactly 2 to the Nth power, use ACC AND
(X-1) is the fastest way. For example, to judge whether YEAR is a leap year, there is a simple way to exclude some non-leap year conditions, as long as it is not divisible by 4, it is not a leap year. So you can use YEAR
AND 3 is resolved.
MOV A,@4-1
AND A,YEAR
JBS PSW,FZ
JMP NOLEAP
Clear a continuous memory
The best way to read and write a continuous segment of memory is to use indirect addressing, but it should be noted that in some high-end MCUs such as M78447/811/860, the memory is 20H~
3FH can be divided into 4 groups of BANK. If it is not switched to the correct bank before, it will cause read and write errors. The following example program will clear all 32 BYTES in BANK1 to 0.
INDIR == 0x00
RSR == 0x04
COUNT == 0x10
REG == 0x20
BANK1 == 0x40
BANK2 == 0x80
BANK3 == 0xC0
MOV A,@32
MOV COUNT,A
MOV A,@REG|BANK1
MOV RSR,A
NEXT:
CLR INDIR
INC RSR
DJZ COUNT
JMP NEXT
Calculate how many "1"s are in a BYTE
This small program can check that there are several 1s in a BYTE, which may be used in some algorithm processes, and the calculated results are placed in ACC.
RRCA DATA
AND A,@0x55
SUB DATA,A
MOV A,DATA
AND A,@0x33
ADD DATA,A
RRC DATA
ADD DATA,A
RRC DATA
SWAPA DATA
ADD A,DATA
AND A,@0x0F
Ways to save NOP instructions
Are you still struggling with the procedure? NOP instruction is sometimes useful in delaying instruction time. If you have two consecutive NOP instructions, you can use JMP to the next instruction instead, because this can reduce one instruction BYTE and achieve the same effect.
E.g:
NOP
NOP
Can be written as:
JMP NEXT_INST
NEXT_INST:
;....
Because a NOP costs one instruction Cycle, but a JMP instruction requires two instructions Cycle. Although sometimes I complain that the JMP instruction will take a little longer, I don't think it has such a magical effect.
Too many labels?
One of the most nerve-wracking problems of writing assembly language is that there are labels everywhere in the program. This has two disadvantages. The first is that it will cause label duplication if you are not careful. The second is that you can't think of an appropriate label name. If you are exhausted for the label naming problem, I will provide you with a small method. If you use "$" in the program to indicate the address of the current PC, it can be deduced that "$+2" means PC+2, "$- 4" means PC-4, look at the example below, you will immediately understand:
MOV R,R
JBS PSW,FZ
JMP $+2
JMP $-4
; ....
But I have to give you a suggestion. An important meaning of label is that it has the function of annotation, especially for those who are lazy to write annotations. Therefore, this method is only suitable for use in highly repetitive program fragments.
SWITCH...CASE description
In the process of program design, it is inevitable that you will often encounter the problem of multiple options. Use EM78XXX's table lookup instruction to try it out. So TBL can be used for multiple condition judgments in addition to general lookup table instructions.
MOV A,CASE
TBL
JMP EVENT1; CASE=0
JMP EVENT2; CASE=1
J
Previous: EMC MCU learning one