| |
 |
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. The condition that result in AC being is: If a carry
was generated out of bit 3 into bit 4 of the accumulator. In other
words, if there is a carry out from the lower nibble.
|
|
|
| |
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, #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 James Rogers
|