| |
 |
The 8051
|
|
|
|
| |
|
| |
|
| |
The Program Status Word (PSW) |
| |
|
| |
Every microcontroller contains flags that may be used for
testing the outcome of an instruction's execution. For example, the carry
flag may be used to test the outcome of an 8-bit addition to see if the
result is greater than 255. |
| |
Some microcontrollers use a special bit to indicate whether
the contents of the accumulator is zero or not (the PIC microcontroller,
for example). This flag is usually called the zero or Z flag and conditional
jump instructions that test its value can be used to branch if the accumulator
is zero or if the accumulator is not zero (if Z is set, the accumulator
contains zero, if Z is clear the accumulator contains a number other than
zero). |
| |
The 8051 does not have such a bit. To test the status of
the accumulator the instructions JZ rel (jump if (A) = 0) and JNZ
rel (jump if (A) <> 0) are used. |
| |
|
| |
The 8051 PSW is detailed below: |
| |
|
| |
Program Status Word (PSW) |
| |
| Bit |
Symbol |
Address |
Description |
| PSW.7 |
CY |
D7H |
Carry flag |
| PSW.6 |
AC |
D6H |
Auxiliary carry flag |
| PSW.5 |
F0 |
D5H |
Flag 0 |
| PSW.4 |
RS1 |
D4H |
Register bank select 1 |
| PSW.3 |
RS0 |
D3H |
Register bank select 0 |
| PSW.2 |
OV |
D2H |
Overflow flag |
| PSW.1 |
-- |
D1H |
Reserved |
| PSW.0 |
P |
D0H |
Even parity flag |
|
| |
|
| |
Carry Flag |
| |
We have already made use of the carry flag, but a recap on
its function is given below. |
| |
The carry flag has two functions. |
| |
- Firstly, it is used as the carry-out in 8-bit addition/subtraction.
For example, if the accumulator contains FDH and we add 3 to the contents
of the accumulator (ADD A, #3), the accumulator will then contain zero
and the carry flag will be set. It is also set if a subtraction causes
a borrow into bit 7. In other words, if a number is subtracted from
another number smaller than it, the carry flag will be set. For example,
if A contains 3DH and R3 contains 4BH, the instruction SUBB A, R3 will
result in the carry bit being set (4BH is greater than 3DH).
- The carry flag is also used during Boolean operations. For example,
we could AND the contents of bit 3DH with the carry flag, the result
being placed in the carry flag - ANL C, 3DH
|
| |
|
| |
Parity Bit |
| |
We also spoke earlier on the parity bit, but again
to recap: |
| |
The parity bit is automatically set or cleared
every machine cycle to ensure even parity with the accumulator. The number
of 1-bits in the accumulator plus the parity bit is always even. In other
words, if the number of 1s in the accumulator is odd then the parity bit
is set to make the overall number of bits even. If the number of 1s in the
accumulator is even then the parity bit is cleared to make the overall number
of bits even. |
| |
For example, if the accumulator holds the number
05H, this is 0000 0101 in binary => the accumulator has an even number
of 1s, therefore the parity bit is cleared. If the accumulator holds the
number F2H, this is 1111 0010 => the accumulator has an odd number of
1s, therefore the parity bit is set to make the overall number of 1s even. |
| |
As we shall see later in the course, the parity
bit is most often used for detecting errors in transmitted data. |
| |
|
| |
Overflow Flag (OV) |
| |
The overflow flag is bit 2 of the PSW. This flag
is set after an addition or subtraction operation if the result in the accumulator
is outside the signed 8-bit range (-128 to 127). In other words, if the
addition or subtraction of two numbers results in a number less than -128
or greater than 127, the OV flag is set. |
| |
When signed numbers are added or subtracted, software
can check this flag to see if the result is in the range -128 to 127. |
| |
For example: 115 + 23 = 138 (73H + 17H = 8AH).
If these numbers are being treated as signed numbers then 8AH is (as a signed
number) -118 in decimal. Obviously, 115 + 23 is not equal to -118. The problem
lies with the fact that the correct answer (138) is too big to be represented
by an 8-bit signed number. Therefore, the OV flag is set to alert the program
that the result is out of range. |
| |
|
| |
You may wonder what happens if the sum of two
numbers is outside the range of an unsigned number. For example: 200 + 60
= 260. The result is a 9-bit number and the carry flag is set. However,
the result is also greater than 127 (the 8-bit signed number maximum) so
you might expect the OV flag to be set also. But, if you test this in the
Keil simulator (or any 8051 simulator) you will notice OV is not set. Why? |
| |
The answer is quite simple: the equation in HEX
is: C8H + 3CH - regardless of whether we are dealing with signed or unsigned
numbers, 3CH is equal to 60 in decimal. However, C8H as an unsigned number
is 200 in decimal, but as a signed number is -56 in decimal. When deciding
the value of the OV flag, only the case of signed numbers is taken into
account. So, this equates to -56 + 60 = 4. If you run this code in the simulator
you will see that the accumulator contains 4, the carry is set to indicate
that, if this is unsigned arithmetic, the answer is greater than 255, but
OV is clear because if this is signed arithmetic the answer is in the range
-128 to 127. |
| |
The largest number we could get from signed addition
is 127 + 127 = 254. In this case OV is set because the answer is outside
the 8-bit signed number range. Therefore, the only way the carry can be
set is through unsigned arithmetic, and in that case OV is not set. |
| |
|
| |
Auxiliary Carry Flag (AC) |
| |
The auxiliary carry flag is set or cleared after
an add instruction (ADD A, operand or ADDC A, operand) only.
There are two conditions that result in AC being set. |
| |
- If the lower four bits of the accumulator (the lower nibble) are in
the range AH to FH.
- If a carry was generated out of bit 3 into bit 4 of the accumulator.
|
| |
This flag may be tested after an addition to see
if the value in the accumulator is outside the BCD range. If it is, the
instruction DA A (decimal adjust A) can be used to change
the HEX code in A to BCD. |
| |
For example: |
| |
|
| |
MOV R6, #4
MOV A, #8
ADD A, R6
JNB AC, skipAdjust
DA A
|
| |
skipAdjust: |
| |
-- continue with
code ...
|
| |
|
| |
The above code adds 4 to 8, leaving 12 in the
accumulator. 1210 = 0CH. This is outside the BCD range (the lower
nibble is between AH and FH), therefore AC will be set and the following
instruction (DA A) will change A from 0C to 12. |
| |
|
| |
Another example: |
| |
|
| |
MOV R6, #8
MOV A, #9
ADD A, R6
JNB AC, skipAdjust
DA A
|
| |
skipAdjust: |
| |
-- continue with code
...
|
| |
|
| |
The above code adds 8 to 9, leaving 17 in the
accumulator. 1710 = 11H. This is outside the BCD range. The lower
nibble is not between AH and FH, however if you perform this addition in
binary you will see there is a carry from bit 3 into bit 4. Therefore AC
will be set and the following instruction (DA A) will change A from
11 to 17. |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
Copyright
(c) 2005-2006 NyCelt LLC
|