Through the examples of running lights, we have become accustomed to "bits". One bit is the on and off of a light, but the instructions we have learned are all introduced in "bytes": byte movement, addition, subtraction, logical operations, shifts, etc. Using bytes to handle some mathematical problems, such as controlling the temperature of a refrigerator, the volume of a TV, etc., is very intuitive and can be directly expressed in numerical values. However, if it is used to control the opening and closing of some switches, the on and off of lights, it is a bit indirect. Remember the example of running lights in our last class? We know that after sending the value to P1 port, we cannot immediately know which light is on and off, but we have to convert it into binary to know. There are many occasions in industry where it is necessary to handle this kind of switch output and relay pull-in. It is a bit troublesome to use bytes to handle it, so a bit processing mechanism is specially introduced in the 8031 microcontroller.
1. Bit addressable area
In 8031, some RAM and some SFR have bit addressing function, that is, each bit of these RAM has its own address, and this address can be used directly to operate on it.
Byte Address
Bit Address
2F
7F
78H
2EH
77H
70
2DH
6FH
68H
2CH
67H
60H
2BH
5F
58H
2AH
57H
50H
29H
4F
48H
28H
47H
40H
27H
3FH
38H
26H
37H
30H
25H
2F
28H
24H
27H
20H
23H
1FH
18H
22H
17H
10H
21H
0FH
08H
20H
07H
06H
05H
04H
03H
02H
01H
00H
Figure 1
The 16 bytes from 20H to 2FH of the internal RAM are the bit addressing area of 8031. See Figure 1. It can be seen that we can directly use the bit address to find each bit in each RAM, without using the byte address and then the logical instruction method.
2. Bit-addressable special function registers
There are some SFRs in 8031 that can be bit-addressed. The characteristics of these SFRs are that their byte addresses are divisible by 8, such as A accumulator, B register, PSW, IP (interrupt priority control register), IE (interrupt enable control register), SCON (serial port control register), TCON (timer/counter control register), P0-P3 (I/O port latch). We are not familiar with some of the above SFRs yet, and we will explain them in detail when we explain the relevant content.
3. Bit operation instructions
In the hardware structure of the MCS-51 microcontroller, there is a bit processor (also known as a Boolean processor), which has a set of instructions for bit variable processing. When performing bit processing, CY (the carry bit we mentioned earlier) is called a "bit accumulator". It has its own bit RAM, which is the 16 byte units from 20H to 2FH of the internal RAM we just talked about, that is, 128 bit units, and its own bit I/O space (that is, P0.0...P0.7, P1.0...P1.7, P2.0...P2.7, P3.0...P3.7). Of course, in physical entities, they are exactly the same as the original byte-addressed RAM and ports, or these RAMs and ports can be used in two ways.
1. Bit transfer instructions
MOV C, BIT
MOV BIT, C
The function of this group of instructions is to realize data transfer between the bit accumulator (CY) and other bit addresses.
Example: MOV P1.0,CY; send the status in CY to the P1.0 pin (if we are doing arithmetic operations, we can know the current CY value by observation).
MOV P1.0,CY; Send the status of P1.0 to CY.
2. Bit correction instructions
1. Bit clear instruction
CLR C ; make CY=0
CLR bit ; Make the bit address of the instruction equal to 0. Example: CLR P1.0 ; Even if P1.0 becomes 0
2. Position 1 instruction
SETB C ; make CY=1
SETB bit; Make the specified bit address equal to 1. Example: SETB P1.0; Make P.0 become 1
3. Bit complement instruction
CPL C; make CY equal to the opposite value of the original, from 1 to 0, and from 0 to 1.
CPL bit; Make the value of the specified bit equal to the opposite of its original value, from 0 to 1, and from 1 to 0.
Example: CPL P1.0
Taking the experiment we have done as an example, if the light was originally on, it will go out after executing this instruction. Conversely, if the light was originally off, it will turn on after executing this instruction.
1. Bit logic operation instructions
1. Bit and instruction
ANL C,bit; CY is ANDed with the value of the specified bit address, and the result is sent back to CY
ANL C,/bit; first take out the value in the specified bit address and then invert it, then AND it with CY, and send the result back to CY, but note that the value in the specified bit address itself does not change.
Example: ANL C,/P1.0
Assume that before executing this instruction, CY=1 and P1.0 equals 1 (light off), then after executing this instruction, CY=0 and P1.0 also equals 1.
The following procedures can be used to verify:
ORG 0000H
AJMP START
ORG 30H
START: MOV SP, #5FH
MOV P1, #0FFH
SETB C
ANL C,/P1.0
MOV P1.1,C; send the completed result to P1.1. The result should be that the light on P1.1 is on, while the light on P1.0 is still off.
2. Bit or instruction
ORL C,bit
ORL C,/bit
Please analyze the function of this by yourself, and then compare it with the above example and write a verification program to see if you get it right?
1. Bit conditional transfer instructions
1. Determine CY transfer instruction
JC rel
JNC rel
The function of the first instruction is to jump if CY is equal to 1, and to execute sequentially if it is not equal to 1. So where to jump to? We can understand it this way: JC label, if it is equal to 1, jump to the label and execute. We have already talked about this instruction in the last class, so I will not repeat it here.
The second instruction is the opposite of the first instruction, that is, if CY=0, it will jump, and if it is not equal to 0, it will be executed sequentially. Of course, we also understand: JNC label
2. Determine the variable transfer instruction
JB bit,rel
JNB bit,rel
The first instruction is to jump if the value in the specified bit is 1, otherwise execute sequentially. Similarly, we can understand this instruction like this: JB bit, label
Please analyze the second instruction yourself
Let's take an example to illustrate:
ORG 0000H
LJMP START
ORG 30H
START:MOV SP,#5FH
MOV P1, #0FFH
MOV P3, #0FFH
L1: JNB P3.2, L2; There is a button connected to P3.2. When it is pressed, P3.2=0
JNB P3.3,L3; There is a button connected to P3.3. When it is pressed, P3.3=0
LJM P L1
L2: MOV P1,#00H
LJMP L1
L3: MOV P1,#0FFH
LJMP L1
END
Write the above example into the film and see what happens...
Press the button connected to P3.2, and all the lights on the P1 port will light up. Release it or press it again, and the lights will not go out. Then press the button connected to P3.3, and all the lights will go out. What does this look like? Isn't this the "start" and "stop" functions often used in industrial sites?
How is it done? At the beginning, 0FFH is sent to the P3 port, so that all the leads of P3 are at a high level, and then L1 is executed. If P3.2 is at a high level (the key is not pressed), the JNB P3.3, L3 statements are executed in sequence. Similarly, if P3.3 is at a high level (the key is not pressed), the LJMP L1 statements are executed in sequence. In this way, P3.2 and P3.3 are continuously detected. If the key on P3.2 is pressed once, it will be transferred to L2, and MOV P1, #00H will be executed to make all the lights on, and then it will be transferred to L1 again, and the cycle will continue until P3.3 is detected to be 0, then it will be transferred to L3, and MOV P1, #0FFH will be executed to make all the lights off, and then it will be transferred to L1 again, and the cycle will continue endlessly.
Can you make some minor changes and rewrite this program using JB instructions?