0% found this document useful (0 votes)
465 views78 pages

Hardware Description of The 8051

The 8051 microcontroller has an 8-bit data bus and can address 64KB of external program and data memory separately. It has 128 bytes of internal RAM and 4KB of internal ROM program memory. Most instructions execute in a single clock cycle. The 8051 can access its I/O pins, timers, serial port, and interrupts through software.

Uploaded by

SudeepSah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
465 views78 pages

Hardware Description of The 8051

The 8051 microcontroller has an 8-bit data bus and can address 64KB of external program and data memory separately. It has 128 bytes of internal RAM and 4KB of internal ROM program memory. Most instructions execute in a single clock cycle. The 8051 can access its I/O pins, timers, serial port, and interrupts through software.

Uploaded by

SudeepSah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 78

===========================================================================

| |
| |
| |
| =|||= =|||= ||||||| =|| |
| || || || || || =| || |
| || || || || || || |
| || || || || || == || |
| ||||| || || ||===|= || |
| || || || || || || |
| || || || || || || |
| || || || || = || || |
| =|||= =|||= =|||= || |
| |
| |
| |
| |
| |
| |
| H H A RRRRr DDDDd W W A RRRRr EEEEEE |
| H H A A R R D D W W A A R R E |
| H H A A R R D D W W A A R R E |
| HHHHHH AAAAA RRRR D D W W W AAAAA RRRR EEEEE |
| H H A A R R D D W W W W A A R R E |
| H H A A R R D D W W W W A A R R E |
| H H A A R R DDDD W W A A R R EEEEEE |
| |
| |
| |
| |
===========================================================================

Hardware description of the 8051 Microcontrollers

Esslingen in August 1991

Note from the English translators:


----------------------------------
The objective of this translation was to remain as close as possible to
the original German, rather than having a paraphrase. Such translations
are bound to come across as stilted and colloquial. While we have tried
to clear up obvious errors, please note the disclaimer from the original
author about the correctness of the document. However we hope that
English readers will find items of benefit in their 8051 programming tasks.
While we will be grateful for indicators of any translation errors, please
direct all other queries to the original author.

Tracey Lee [email protected] Singapore, March 1997


Anthony Khoo

Forward:
--------

This documentation is for beginners, and pertains to the setup and


function of microcontrollers from the MCS-51 family. It is comprehensive
since incomplete knowledge about the hardware would conceal rather than
help in the understanding of the subject.

The documentation was written, so that it may be read like a textbook.


It will try not to introduce ideas which are covered in later chapters.
This naturally is not always possible, when the individual components depend
on each other.

However it attempts to give each keyword as much background information


as possible within individual chapters, so that problems specific to it may
be referred to.

When possible, in the various chapter short examples are given. In addition
in an extra chapter, as an example, the set up and programming of a computer
card with two different PCs connected by serial ports are described.

The basic type of the MCS-51 family is the 8051 controller from Intel.
Other types from Intel, and controllers designed by other companies based on
this family possess the same functions as the 8051. Some have added on
several extra functions. Hence the 8052 has an extra timer and a larger
internal RAM.

The 8031, 8751 types are identical to the 8051, but they possess no internal
ROM and an internal EPROM, respectively.

First we will look at only the 8051, explaining its architecture. Following,
several functions of the other CPU's of the MCS-51 family will be considered.

I cannot guarantee the completeness and absolute correctness of the


documentation. I am always grateful for additions, tips and error corrections.

(c)1991,1993 Werner Hennig-Roleff


Sulzgrieser Str. 101
73733 Esslingen
0711/376718

Table of contents:
-------------------

1. 8051 Characteristics ................................... 1


2. Data and Address ................................... 2
3 Arithmetic core of the 8051 ............................ 4
3.1 8051-block diagram 4
3.2 Timer/ Cycles 7
3.3 Command execution 8
3.4 Special Function Register 10
3.4.1 ACC 11
3.4.2 B 11
3.4.3 PSW 12
3.4.4 SP 13
3.4.5 DPTR = DPH:DPL 14
3.4.6 PCON 14
3.5 Ports 16
3.6 external program memory access 20
3.7 external data memory access 23
3.8 Power on for an external Bus 25
3.9 internal RAM 28
4. Instruction set ..................................... 33
4.1 Data transfer 35
4.2 Arithmetic operations 38
4.3 Logic Link 41
4.4 Bit manipulations 43
4.5 Unconditional jumps and calls 44
4.6 Conditional jumps 47
5. Assembler ............................................ 49
5.1 The ASM51 49
5.2 Segment assignment under ASM51 51
5.2.1 fixed address assignment 52
5.2.2 relocatable address assignment 54
5.3 ASM51 Call 54
5.4 Program examples 55
5.5 ASM51 bugs 57
6. further components of the 8051 ......................... 58
6.1 Interrupt logic 58
6.2 Timer0 and Timer1 61
6.3 serial communications 62
6.3.1 asynchronous, synchronous mode 63
6.3.2 serial mode set up 63
6.3.3 Interrupt Mode, Polled Mode 67
6.3.4 Baud rate table 70
7. further controller of the 8051 Family 71
7.1 the 8052 71
7.1.1 additional SFR of the 8052 71
7.1.2 Timer2 71
7.1.3 serial communications with timer2 73
Appendix
A.1 ASCII table ........................................ 75
A.2 Instruction set in hexadecimal order ............. 77

1. 8051 Characteristics Page 1

1. 8051 characteristics
-----------------------

The 8051 is often embedded in control circuits, for that reason the name
microcontroller has been commonly used for the 8051.
The 8051 operates on an 8 bit data bus. Externally it can address 64 kByte of
data and code separately. Additionally it has internal RAM (128 Byte) and
internal ROM (4 kByte) of program memory.
Instructions from addresses 0000 to 0FFFh operate from internal program
memory. Instructions from higher addresses will always be read from external
program memory. Through an input pin the internal program memory can be
switched off.

Most of the instructions need one cycle (1 s) to execute.


The data manipulation instructions are as follows:

MOV (data transfer),


XCH (data exchange),
INC, DEC (increment +1, decrement -1),
ANL, ORL, XRL (logic operations),
ADD, ADDC, SUBB (addition, subtraction),
MUL, DIV (multiplication, division).

A special feature of the 8051 is that almost all its electrical connections
(pins) can be accessed with software. It also has access to two integrated
timers, one serial port (UART) as well as two interrupt inputs.

Additionally it is possible to manipulate single BITs with MOV, SETB, CLR and
CPL.

The 8051 has available conditional and unconditional jump instructions.


Subprograms may be called up. The return address will be placed by the CPU
on the stack. The stack is located in internal RAM and increases upwards
when used.

Division can only be done byte wise (8 BIT). For larger data, more complicated
procedures are necessary. The size of the internal RAM is often limiting.

As a cost effective controller, the 8051 enjoys great popularity.

2. Data and Addresses Page 2

2. Data and Addresses:


----------------------

Arithmetic only handles numeric values : for example sizes of measurements,


calculation values, etc. As to the handling of text, the ALU will require
a numeric value to be assigned to every character.

Digital techniques work with two logic values (1=high or 0=low).


With one binary digit 2 numeric values can be selected.
With two binary digits 4 different numeric values can be represented:
0 = 00b, 1 = 01b, 2 = 10b and 3 = 11b (the "b" is a label for a binary value).

The alphabet consists of 26 characters. Distinguishing between the capital


and small letters and catering for several special values in addition,
(1 2 3..0 , + - ? ! : ; / ( and so on) so we have approx. 80 values.
To be able to clearly differentiate between them at least 7 binary
digits are necessary.

The assignment of characters to numeric values has naturally been the norm.
In the ASCII standard (American Standard Code for Information
Interchange) 8 binary digits are used to represent numeric values. Such a
numeric value between 0 and 255 are designated as a BYTE. Each of its binary
digits is a BIT.

The choice of 8 bits per BYTE comes also into consideration in the
representation of numeric values for computations, for in hexadecimal
notation, this can be represented by just two digit hex numbers. Larger values
(with more digits) use several bytes.

To support computing, controllers and processors are equipped with 8 bit wide
data lines. Newer, faster CPU's in future will hold 16 or 32 BIT wide data
lines. With all this, the ASCII table is in addition used for the coding of
text (see Appendix). The following designations are normally used:

BIT 1 data line


NYBBLE 4 data lines = BYTE one digit hex value 0..0F
BYTE 8 data lines two digit hex value 0..0FF
WORD 16 data lines four digit hex value 0..0FFFF
DWORD 32 data lines eight digit hex value 0..0FFFFFFFF

MSB LSB
+++++++++
| Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 | BYTE
+++++++++
| High NYBBLE | Low NYBBLE |

MSB = most significant Bit


LSB = least significant Bit

2. Data and Addresses Page 3

The 8051 is an 8 bit computer, that is: numeric values, characters and also
the code are stored as bytes. The data bus has 8 parallel data lines.

On chip, the data is transferred over an interconnecting INTERNAL DATA BUS.


If a processor board is constructed and an external RAM and/or EPROM is used,
then 8 connecting lines must be brought in between the 8051 and the external
memory for the data. This is the EXTERNAL DATA BUS.
The transition switching between the internal and the external data bus
takes place over special drivers (see ports).

In order to store a number the size of a BYTE, 8 flip flops will be needed.
To store a complete text, many such 8 flip flop memory locations will be
needed. In addition, each memory location should be individually accessible.
For each memory location a select line is needed.

Memory chips produced today are highly integrated (a 62256 RAM chip has
for example 32768 memory locations: it can store 32 kBytes). In order to
access a given memory location, it is not necessary to have 32768 select
lines. Instead, coded addresses are used, which are decoded only in the
RAM chip. So with 16 address lines, which the 8051 prepares, 65536 memory
locations can be addressed.

To select which memory location will be accessed on the 8051 depends


not only on the address, but also on the data type.
Differences will occur between: SFR, internal RAM, external RAM, internal
ROM, external EPROM

3.1 Block diagram Page 4

3.1 8051 Block diagram:


------------------------

The 8051 uses an 8 bit wide data bus. It has several internal registers,
which are likewise 8 bit wide. It can access external components (as memory)
over drivers. It has internal RAM, 2 Timers, serial input/output and internal
program memory.

++
++||++
| ++ |
++++ ++
ALE | | | |
_PSEN |Oscillator++ Arithmetic Logic Unit ++
| | +===>| | |
+++ | ++ |
| | | <Code-Fetch> | |
| | | | | _EA
Timer: | |i | | | ++
++ |n | | +>| Program- |
| TMOD |<=====+t | +=============| Counter, |
++ |e | |i | | Address- |
| TCON |<=====+r | |n | +==| Register |
++ |n ++ |t | |e ++
| TH0:TL0 |<=====+ | internal | |. | |x
++ |D | | |A | |t
| TH1:TL1 |<=====+A | PROM |<==+d | |.
++ |T | | r | |A
|A ++ | |d
| | |r
| | |
++ | Port-Latches: | | Driver:
| ACC |<=====+ ++ | +======>|
++ +==========>| P0 |<=====+============>| Port 0
| B |<=====+ ++ |
++ | ++ +======>|
| PSW |<=====+==========>| P2 |<==================>| Port 2
++ | ++
| PCON |<=====+==========>| P1 |<==================>| Port 1
++ | ++
| DPH:DPL |<=====+==========>| P3 |<==================>| Port 3
++ | ++
| SP |<=====+
++ |
|
| ++
serial port: | | internal |
++ |======>| |
| SCON |<=====+ | RAM |
++ | | |
| SBUF |<=====+ ++
++

3.1 Block diagram Page 5

The block diagram is a schematic of the internal hardware setup. It is


naturally not precise in all particulars. It views the structure as a
programmer sees it, rather than the actual electrical set up.

As indicated in the block diagram, the CPU can access the SFR (see chapter
3.4) and internal RAM over the internal data bus. For external memory access
(XDATA) ports P0 and P2 are used. Concurrent with the high address byte being
placed in P2, at first the low address byte will be placed in P0. After the
negative edge of the ALE (address latch enable) data will be expected or output.

The instructions (CODE) that the 8051 is supposed to execute, will be read
from the internal ROM or optionally from an external program memory. A read-in
of CODE occurs twice every instruction cycle. The instructions are likewise
placed as numeric values in the size of a BYTES. Therefore a maximum of 256
different instructions are possible. Every number is assigned a definite
instruction: so means e.g. the CODE 0A4h --> multiplies the Register
ACC with the Register B (for the complete instruction set see chapter 4).

The next diagram shows an example of an external wiring of the 8051 with an
external RAM and an EPROM. Since Port 0, during the first half of an access,
first guides the low address and then for the second half switch
(multiplexer) to data, the low address must be stored in a latch. (There are
however RAMs, which have multiplexed inputs such as the DPR SAE 81C80 from
Siemens, which does not need a latch).

8051 RAM
++ ++
| _WR+>|_WR |
| _RD+>|_RD |
| | high Adr. | |
| P2+===========================+======>| |<======+
| | |A | | |
| | LATCH |D | | D|
| | ++ |D ++ A|
| ALE+>|74 LS| |R EPROM T|
| | | 373 |low Adr. |E ++ A|
| P0|<===+====>| +==========+S | | |
| | | | | |S | | |
| | | ++ | | |<======+
| | | +======>| | |
| | | _PSEN | | |
| _PSEN+|>|_RD | |
++ | ++ |
| external DATA |
+===============================================+

3.1 Block diagram Page 6

The diagram of the 8051 here ++


belongs together with the P1.0 | 1 40| + 5V
understanding of the hardware P1.1 | 2 39| P0.0 (AD0)
and the following explanations P1.2 | 3 38| P0.1 (AD1)
of the individual components of P1.3 | 4 37| P0.2 (AD2)
the 8051. P1.4 | 5 36| P0.3 (AD3)
P1.5 | 6 35| P0.4 (AD4)
P1.6 | 7 34| P0.5 (AD5)
P1.7 | 8 33| P0.6 (AD6)
reset | 9 32| P0.7 (AD7)
(RxD) P3.0 |10 31| _EA
(TxD) P3.1 |11 30| ALE
(_INT0) P3.2 |12 29| _PSEN
(_INT1) P3.3 |13 28| P2.7 (A15)
(T0) P3.4 |14 28| P2.6 (A14)
(T1) P3.5 |15 28| P2.5 (A13)
(_WR) P3.6 |16 28| P2.4 (A12)
(_RD) P3.7 |17 28| P2.3 (A11)
XTAL2 |18 28| P2.2 (A10)
XTAL1 |19 28| P2.1 (A9)
GND |20 28| P2.0 (A8)
++

The 8051 runs on +5V. Most of the connections are through the ports. These
port pins can be directly accessed from software. In addition they have extra
hardware functions (indicated above in brackets). Only the RESET pin, the
external/internal code fetch toggle (_EA), the quartz input, the oscillator
output for the address latch as well as the external program memory read
signal cannot be accessed by software.
Summary:

Port0: XTAL1, XTAL2:


8 bit input/output. Alternatively Connection point for quartz
serves as the output of the low or an external oscillator.
address and for write/read when
accessing external memory. ALE:
Address Latch Enable signal to the
memory of the low address of
Port1: Port0 during access to external
8-Bit input/output memory.

Port2: _PSEN:
8-Bit input/output. Alternatively Program Store Enable (read signal)
serves as the output of the high during access of external code.
address when accessing external
memory.
reset:
Port3: must be set high for at least 2
8-Bit input/output. Alternately cycles, then Reset.
P3.0 and P3.1 is also input
/output for serial port, P3.2 _EA:
and P3.3 are also interrupt in- External Access: when low, all code
puts, P3.4 and P3.5 as timer will be read externally.
gates, P3.6 and P3.7 as write/read When high, code from 0000...0FFFh
signals when accessing external data. will be internally read, upper
addresses externally.

3.2 Oscillator Page 7


3.2 Oscillator / Cycles:


-------------------------

The logic in the 8051 operates on a clock. The oscillator is derived from a
quartz crystal. The maximum usable frequency is 12 MHz (there are already
newer CPUs with 16 MHz). The quartz crystal must oscillate as suggested.
Additionally, an inverting amplifier must be connected in the oscillator
circuit. This driver is integrated into the 8051. In order that the crystal
does not oscillate at higher frequencies, two small capacitors are connected
to it.

Quartz crystal, max. 12 MHz


30pF ++ 30pF
+++++||+++++
GND| | ++ | |GND
+ | | +
| |
| |
------o XTAL1----o XTAL2------
| |
| |
| | \ |
++ \+> to internal
| / oscillator recovery

Wiring with quartz crystal with 8051 HMOS + CMOS

Warning!: 8051 computers use HMOS and CMOS technologies. The CMOS
implementation contains a somewhat differently wired quartz driver.
In an external wiring with a crystal (as shown above) nothing is
changed. However when using an external oscillator clock and this clock
(TTL Level) feeds it, a separate wiring is needed as shown below:

With HMOS execution the external With CMOS execution the external
oscillator
crystal is fed to pin XTAL2. To is fed to XTAL1. The output XTAL2 of the
deactivate the internal crystal internal crystal driver remains open.
drivers connect XTAL1 to GND.

++ ++
| ++ | external oscillator | ++ | external oscillator
| +||+ ++ | +||+ ++
| ++ | | | ++ | |
++ | ++ |
+ GND | |
| | ----o XTAL1----o XTAL2---
--------o XTAL1----o XTAL2--- | |
| | | | \ |
HMOS | | CMOS ++ \+
| | \ | | | /
++ \+> internal |
| / oscillator +> internal oscillator

3.3 Command execution Page 8

The oscillations that come from XTAL2 or XTAL1 or the crystal driver is
divided into 2. After that a symmetrical oscillation of maximum 6 MHz is
available. This clock will be used as the 8051 system clock: that is, all
logic inside the 8051 will change state based on this clock.
The execution of an instruction will need at least 6 system clocks
(State 1 to 6 = 1 cycle).

Crystal: 12 MHz maximum (some special CPU at 16 MHz also)


System clock: 6 MHz
Cycles: 1 MHz --> 1 s

++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++++ ++ +
XTAL + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++++ ++ ++ ++
+ ++ ++ ++ ++ ++ ++ +
SysClk ++ ++ ++ ++ ++ ++ ++
State | 1 | 2 | 3 | 4 | 5 | 6 | 1
^ ^ ^
1.Code-Fetch 2.Code-Fetch

Asymmetrical crystal oscillation will still give a symmetrical system clock


(indicated for States 5 and 6 in above diagram).

3.3 Command execution:


---------------------

For every cycle the CPU always allows for 2 bytes from the program memory
(code fetch). This happens automatically at state 1 and state 4 (see also
timing for external code access):

There are instructions without and with 1 to 2 operands. These cycles


generally read 2 code bytes and over fetching will be rejected. With
instructions which need more than 1 cycle to execute the next instruction will
be repeatedly read until the actual statement is reached.

--- Example:

Example: Opcode: Cycles: Fetch:


--------------------------------------------------------------------------
NOP 00 1 00 05 1 byte too much, ignored
INC SP 05 81 1 05 81
INC DPTR A3 2 A3 E2 E2 83 in the 2nd cycle next fetch
MOVX A,@R0 E2 2 E2 83 __ __ in 2nd cycle XDATA no fetch
MOVC A,@A+PC 83 2 83 02 __ 02 in the 2nd cycle MOVC access
LJMP 3344 02 33 44 2 02 33 44 ??

3.3 Command execution Page 9


With a NOP a code byte too many will be read. It will not be evaluated,
rather re-read in the next cycle. With INC DPTR in first cycle 1 code byte
too many will be read. In the 2nd cycle the code byte of the next instruction
will again be read but also not be evaluated yet.

With an external data memory access (MOVX) there is a special feature. Here
in the 2nd cycle, no code fetch takes place, rather the external RAM will be
accessed.

Accessing a table in program memory through MOVC in the 1st cycle, a byte of
the next instruction will be read along already (too much). In the 2nd cycle,
the access to the table takes place first and then yet another code fetch,
which will however be rejected.

An LJMP instruction needs 3 code bytes and 2 cycles. In the 1st cycle the
opcode and the high byte of the target address (1st operand) will be read. In
the 2nd cycle the low byte of the target address (2nd operand) and (too much)
the opcode of the next code byte will be read. After carrying out the jump,
the program counter will be at the new address. The next code fetch takes
place there. From here is also apparent, why the over-read instructions in
the previous cycles are repeatedly rejected.

The execution of instructions takes place mainly in state 5. There the code
address for the code fetch of the next cycle will again also be already
set.

3.4 SFR Page 10


3.4 SFR (Special Function Register):


-------------------------------------

Contrary to some processors, no special instructions are used to control timer


and serial ports. This control is done with special registers, which are assigned
in the data region of the 8051. Every SFR (special function register) is assigned
a DATA address, the access takes place over the internal data bus.
With enhanced controllers such as the 8052, 80515, 80552 and others, in
comparison to the 8051, additional functions come with extra SFRs. However, they
come
with the same instruction set!
Instead of the DATA address, a predefined abbreviation (Mnemonic) can be used
in the case of the ASM51 assembler. The following table holds all SFR of the
8051 with mnemonic and DATA Address:

Ports: Timer:
P0 DATA 80h TCON DATA 88h
P1 DATA 90h TMOD DATA 89h
P2 DATA 0A0h TL0 DATA 8Ah
P3 DATA 0B0h TL1 DATA 8Bh
TH0 DATA 8Ch
Arithmetic registers and CPU control: TH1 DATA 8Dh
PSW DATA 0D0h
ACC DATA 0E0h Interrupt control:
B DATA 0F0h IE DATA 0A8h
PCON DATA 87h IP DATA 0B8h

Pointer: serial port:


SP DATA 81h SCON DATA 98h
DPL DATA 82h SBUF DATA 99h
DPH DATA 83h

Some SFR are bit addressable (always those whose DATA Addresses
end with 0 or 8). For an 8051 these are:
PSW - Bit's: IE - Bit's IP - Bit's
CY BIT 0D7h EA BIT 0AFh PS BIT 0BCh
AC BIT 0D6h ES BIT 0ACh PT1 BIT 0BBh
F0 BIT 0D5h ET1 BIT 0ABh PX1 BIT 0BAh
RS1 BIT 0D4h EX1 BIT 0AAh PT0 BIT 0B9h
RS0 BIT 0D3h ET0 BIT 0A9h PX0 BIT 0B8h
OV BIT 0D2h EX0 BIT 0A8h
P BIT 0D0h SCON - Bit's
P3 - Bit's SM0 BIT 9Fh
TCON - Bit's RD BIT 0B7h SM1 BIT 9Eh
TF1 BIT 8Fh WR BIT 0B6h SM2 BIT 9Dh
TR1 BIT 8Eh T1 BIT 0B5h REN BIT 9Ch
TF0 BIT 8Dh T0 BIT 0B4h TB8 BIT 9Bh
TR0 BIT 8Ch INT1 BIT 0B3h RB8 BIT 9Ah
IE1 BIT 8Bh INT0 BIT 0B2h TI BIT 99h
IT1 BIT 8Ah TXD BIT 0B1h RI BIT 98h
IE0 BIT 89h RXD BIT 0B0h
IT0 BIT 88h

3.4 SFR Page 11

The SFRs are accessed directly. The have in code stand the HEX address of the
SFR as operand. Example for an SFR access:

MOV TMOD, #20h ; a value to be written to TMOD


MOV 89h, #20h ; the same with DATA addr
ORL PSW, #18h ; change the value in PSW
MOV A, SBUF ; load the value from SBUF into accumulator
In this chapter the general CPU registers are explained. The registers which
are assigned to unique components (such as Ports, Timer, Interrupt, serial
port) will be explained in the context of these functions.

3.4.1 ACC (Accumulator):


-------------------------

The accumulator (DATA E0h) serves as the main calculation register.


Arithmetic operations can only be effected in connection with the ACC.
Moreover the ACC is used to access external memory and indirect jumps (see
instructions ADD, ADDC, SUBB, MUL, DIV, MOVX, MOVC, JMP, JZ, SWAP, CLR,...).
The ACC can be addressed bitwise:

ACC.0 BIT 0E0h ACC.4 BIT 0E4h


ACC.1 BIT 0E1h ACC.5 BIT 0E5h
ACC.2 BIT 0E2h ACC.6 BIT 0E6h
ACC.3 BIT 0E3h ACC.7 BIT 0E7h

When accessing the ACC, special (shorter and faster) instructions are
available. To make the distinction, the ASM51 mnemonic abbreviation "A" is
written instead of "ACC". For the 8051 different opcodes are generated.

Example:
MOV ACC, #44h Hex code: 75 E0 44 2 cycles
or MOV A, #44h Hex code: 74 44 1 cycle

3.4.2 B-Register:
------------------

The B-Register (DATA F0h) serves as a general purpose register. It can be used
as intermediate storage for values. In multiplication and division it is used
as an assisting calculation register. It can be treated bitwise:

B.0 BIT 0F0h B.4 BIT 0F4h


B.1 BIT 0F1h B.5 BIT 0F5h
B.2 BIT 0F2h B.6 BIT 0F6h
B.3 BIT 0F3h B.7 BIT 0F7h

3.4 SFR Page 12

3.4.3 PSW (Program Status Word):


----------------------------------

The PSW (DATA D0h) holds the most important flags of the CPU as well as two
bits for register bank switching (see 3.9 internal RAM). The flags are
important for computation operations and comparisons:

P BIT 0D0h RS1 BIT 0D4h


PSW.1 BIT 0D1h F0 BIT 0D5h
OV BIT 0D2h AC BIT 0D6h
RS0 BIT 0D3h CY BIT 0D7h

+++++++++
| CY | AC | F0 | RS1 | RS0 | OV |PSW.1| P | PSW (D0h)
+++++++++

++ ++
| PSW.1 | and | F0 | have no hardware function. They can be used by the
++ ++ user for any purpose. PSW.5 is predefined by
ASM51 as F0 (Flag 0). PSW.1 and PSW.5 can be used as
intermediate storage for any bit value.

++
| P | is the parity flag. It always reflects the status of the ACC.
++ If the sum of all bits in the ACC is even (even Parity), then P = 0.
If the sum is odd (odd Parity), then P = 1. The parity flag cannot
be written by software (only read).

Example: ACC = 11h = 00010001b --> = 2, even --> P = 0


ACC = E3h = 11100011b --> = 5, odd --> P = 1

++
| OV | is the overflow flag (overflow flag). It is set, after a
++ multiplication, when the result is larger than a byte (then it
no longer fits in the ACC alone). It will be set when division by 0
occurs. In addition, it will be set during additions and subtractions when
there is a sign error.

In computations with signed numbers, the highest bit represents the sign
(example: 31 = 1Fh, -31 = 9Fh). So only numbers from -128 to +127 are
represented. Now when a positive number is added to a positive number, the
result must (again) be positive. A negative number minus a negative number
must (again) be negative. With an overflow, this is not the case:

Example: 42h + 47h = 89h = -9 --> Error! true result +137

++
| AC | is the auxiliary carry flag (auxiliary overflow flag): it will be set
++ when there is a carry over from bit 3 during addition and subtraction.

3.4 SFR Page 13

++
| CY | is the carry flag (carry flag): it will be set on a carry from
++ bit 7 during addition, subtraction, by decimal adjust and on
rotate left through carry. Besides it will be set on a carry
from bit 0 by rotate right through carry and when the left operand is less
than the right during "Compare and Jump if Not Equal".

As in the ACC, there are special instructions also for accessing the carry
flag. These are characterised by the use of the mnemonic "C" which stands for
"CY".

Example: SETB CY hex code: D2 D7 1 cycle


SETB C hex code: D3 1 cycle

++ ++
| RS1 | and | RS0 | serve to select the register bank. These bits are
++ ++ set by software (only read through the CPU).

RS1:RS0 = 00 --> Reg Bank 0 RS1:RS0 = 10 --> Reg Bank 2


RS1:RS0 = 01 --> Reg Bank 1 RS1:RS0 = 11 --> Reg Bank 3

3.4.4 SP (Stack Pointer):


--------------------------

The CPU sets up a stack memory in internal RAM. The CPU will place the
return address in the stack with every subprogram call (LCALL or ACALL).
The same takes place automatically through the CPU when entering an interrupt
routine. A RET or RETI will fetch the return addresses from the stack. An
application program can access stack memory with the PUSH and POP
instructions.

The SP (DATA 81h) always shows the final pushed value. To store a byte
the SP will first increment and then the value will be written into internal
RAM address, where the SP points to. Return addresses are of type WORD, with
which the CPU will first put the low byte then the high byte to the stack.

The stack grows from the bottom to the top. After a reset the SP shows the
internal RAM address 07h. The first pushed byte will be written in 08h
(with that reg bank 0 will not be overwritten by the stack). An application
program should soon after a reset load the SP with the program's last used
internal RAM address, so that the stack will be placed above the program's
data.

Warning! The 8051 internal RAM ends at address 7Fh. Should the SP show upper
address values, an additional PUSH will increment it- with a POP garbage
comes back!

3.4 SFR Page 14

3.4.5 DPL, DPH (Data pointer):


-------------------------------

The data pointer (DPTR) is the sole 16 bit register of the 8051, which can
also be loaded for 16 bit access. It is put together from the Special Function
Registers DPH = data pointer high (DATA 83h) and DPL = data pointer low (DATA
82h). The data pointer serves to access external RAM (see MOVX), tables in
code memory (see MOVC) and for indirect jumps (see JMP).
3.4.6 PCON (Power-Control):
----------------------------

The PCON register (DATA 87h) hold further CPU flags. The power control
flags exist only in the CMOS versions (80C51). The most significant
bit (SMOD) belongs to the setting of the baud rate of the serial port
(see serial port). PCON is not addressable bitwise.

+++++++++
|SMOD | - | - | - | GF1 | GF0 | PD | IDL | PCON (87h)
+++++++++

++
| SMOD | determines the gain factor for the driving oscillator of the serial
++ port. For serial modes 1, 2 or 3 the baud rate (Shift Time) will be
divided by 2, when SMOD = 0.

++ ++
| GF1 | and | GF0 | have no hardware functions. They cannot be manipulated by
++ ++ BIT Addresses (set and clear only with ORL respectively
PCON). They can be used from the program for any purpose.
A proposed use is for indicating whether idle mode has been activated.

++
| IDL | switches the CPU into idle mode (only CMOS!). When IDL = 1 is set
++ (with OR PCON, #1), the next instruction will not be executed.
The 8051 goes into IDLE mode. This means:

* Instruction execution stops.


* the port output pins keep their last electrical value
* the timer continues to run
* the serial port continues to operate
* all other registers keep their values
* the supply current is reduced by about 23% (at 5V and 12 MHz)

The idle mode can be discontinued by activating an interrupt or by a reset.


The interrupt must also be enabled. If an interrupt is activated, the entry
into the interrupt routine will clear IDL. The interrupt routine will
execute. After the RETI instruction execution will continue at the

3.4 SFR Page 15

instruction following the idle mode activation. GF1 or GF0 may serve to
indicate idle mode was set, by the code for the interrupt routine (IDL will
be cleared by hardware).

If a reset occurs during the idle mode, then the IDL in PCON will be cleared
immediately. The execution of instructions continues with subsequent
instructions --> until two cycles later the reset logic starts up and all SFRs
as well as the program counter are set back. Execution starts again at the
reset address 0000.
First of all the two or three instructions following the idle mode will be
executed. The correct execution of the instruction in this condition is not
guaranteed. Accessing the ports or external data memory should therefore
be avoided after idle mode activation (possibly insert 3 NOP's).
Access to the internal RAM is not a problem, for the hardware prevents access
to the internal RAM at this time.

After leaving the idle mode upon reset, all SFRs are set back. Also GF1 and
GF0 are cleared. But the internal and external RAM are unchanged.

++
| PD | switches the CPU into power down mode (only CMOS!). If PD = 1
++ is set (via OR PCON, #2), then the next instruction will not be
executed. The 8051 goes into POWER DOWN Mode. This means:

* the instruction execution stops.


* the port output pins keep their last electrical value
* ALE and _PSEN goes low
* the timers stop
* the serial port stops
* the supply current reduces itself to about 0.3% (at 5V and 12 MHz)

The power down mode can only be exited through a reset. This reset will then
reset all SFRs (also ports to 0FFh), but not the internal and external RAM.

During the power down state the supply voltage can be reduced to 2V without
the contents of the internal RAMs being lost.
To do this successfully, first PD is activated, and the voltage must go back
to 5V, before the reset is released.

3.5 Ports Page 16

3.5 Ports:
-----------

Every 8 electrical connections of the 8051 are connected to a port. There


is direct access to the port pins from the software. The connections are also
used for other functions, which can only be controlled from the hardware,
such as for the code fetch from an external program memory.

In order that the ports may be used for input and output, they have a special
driver:

| /|read pin
| +< ++
| | \| |
i| | |
n| | /|read latch +5V o |
t|\<+< ++ | |
e| \| | |++ |
r| | ++++ |
n| | | | | Pin0.x
a| ++ | | ++o
l|\>+D Q++ switch | |
| | | ++ | |++
D| | /Q++ _\ ++++
a| ++ +++ | |
t| Latch | | +
a| | |
| Address/Data output

The above picture shows a simplified setup of a pin of Port 0. Port 2


has in principle the same setup, except that there is an extra pull up
resistor at the output.

alternative function of P0, P2:


--------------------------------
Port 0 and Port 2 alternatively serve to read from the external program
memory (code fetch) and to read from and write to the external data memory.
The low byte of the addresses are given out over Port 0 and the data read or
written. Port 2 functions as output for the high byte of the address.

If code is executed from the internal ROM only and no external data memory
is used (no MOVX instruction), then the alternative functions of port 0 and
port 2 will never be activated. Port 0 and Port 2 can then be dedicated to
any function (in/output pins). At Port 0, pull up resistances will then be
required.

If port 0 and port 2 are used for code fetches, then the other functions
will mostly be shut out. Then the hardware automatically clears the contents
of the port 0 latches with every external data access.

With MOVX @Ri instructions, port 2 will not be controlled by the hardware
with high addresses.

3.5 Ports Page 17

Writing to port P0 and P2:


--------------------------
In the "normal" function a byte written into the port address (P0 DATA 80h,
P2 DATA A0h) over the internal data bus will be stored in the latches.
A switch changes between the "normal" function and the alternative function,
regardless of when the alternative function value has given out values. The
content of the latch stays unchanged (Exception: Read from P0 for Code-Fetch,
MOVX and MOVC).

The upper transistor will only take control, when a logic 1 for the alternate
function happens to be placed on the pin. If there is a 1 in the latch, and
no value is given for the alternate function, then the output at Port 0 is at
high impedance (floating). At port 2, the integrated pull up takes effect. In
both cases, the pin can be used as input. If there is a 0 in the latch, then
the lower transistor will be activated, and the pin will always be low (not
available as input).

Read from Port P0 and P2:


-------------------------
At Port 2, no reading of data for the alternate function of the memory access
takes place (issue only high address). At Port 0 data will be read over a
tristate driver to the internal data bus. Before every read access of external
memory, the hardware automatically writes #0FFh in the Port P0 - latches (only
with alternative functions). With "normal" read accesses, the user himself
must see to it that the latch outputs are high, since only then can a read be
properly performed over a port pin (this condition is satisfied after a
Reset).

If through a software instruction a "normal" read from a port is done through


an SFR address, then this occurs after the instruction, from the pins directly
over a driver or over another tristate driver from the latch output. With all
read-modify-write accesses the reading is done from the latch, otherwise from
the pin.

An example:

CPL P2.1 is a read-modify-write instruction: The value in the latch from pin
P2.1 is to be changed. If there is a 0 inside, then a 1 is to be written in
and vice versa.
If read from a pin, a mistake can o | <--- Load
occur when the circuit is switched on | | +o
as in the example given here. +++ | |
The base of the NPN transistor is | | | |
driven directly from the pin - made +++ P2.1 /
possible by the internal pull up. +o+< NPN
With the latch set, the voltage at | | \E
the pin will only be 0.6 V. From the |++ | |
pin, a low level will be read back, +++ | |
even though there is a 1 in the latch. | | +
The CPL instruction will be wrongly + |
executed.

Read-modify-write instructions are:


JBC jump when bit (in latch) is set and clear latch
DJNZ decrement port (SFR of the ports) and jump when not 0
CPL change (Port-) Bit
ANL, ORL, XRL, INC, DEC change (Port-) Byte

3.5 Ports Page 18

to the Distinction:
JB (jump, when bit is set) is not a read modify write instruction, since
the contents of the latch here is not used. Here the pin will be read.

Problems may arise with the following instruction sequence:

PUSH P2 PUSH P2 is not a read modify write instruction, and for


MOV P2, #80h that reason the value of the port pin's will be placed on
MOV R0, #0 the stack. This can be the contents of the latch, but
MOVX A, @R0 that need not be so (see circuit on previous page).
POP P2 The contents of the latch may only be reliably placed on
the stack, when no port pin is turned on as input, and
the load on the output pins is such that the electric level is not wrong.

Differences between Port P1 and P3 to P0:


-----------------------------------------
P1 and P3 are different from port P0 in that they have no multiplexer. As far
as we are concerned, the output for the alternative function connects with the
latch output over a NAND gate. Input will not go to the internal data bus,
but directly to the components of the alternative functions.

| /|Pin read
| +< ++
| | \| |
i| | |
n| | /|Latch read +5V o |
t|\<+< ++ | |
e| \| | +++ |
r| | | | |
n| ++ | +++ | Pin 3.x
a|\>+D Q++ NAND ++o
l| | | | ++ |++ | Pin 1.x
| | /Q| ++ & +o+++ |
D| ++ ++ | | |
A| Latch | ++ + |
T| | |
A| | /| |
| | +< ++
| | \|
alternative: |
output input

In regard to the "normal" access to a port address (SFR) through the software
there is no difference from port P0 (see Comments about P0).

P1 and P3 possess integral pull up resistors. The upper transistor drawn into
the diagram for P0 does not exist. However there is a special feature: On the
chip of the 8051 the pull up resistors are not achieved through permanently
fixed resistors rather through special field effect transistors. If a pin is
switched from 0 to 1, port P1 and P3 will, for the duration of 2 crystal
clocks (= 1/6 cycle) switch the resistance of the

3.5 Ports Page 19

FET, so that a low impedance is imposed (at port 2 this will be for the entire
period of the alternate function of the high address output). Thereby, faster
settling time of the output signal of a pin is achieved, and yet the pull up
is of sufficiently high impedance so that the pin can be used for input.

With port P3, no alternative output takes place, so the input of the NAND
gate is high. For this case the logic condition of the pins depends on the
latch.
Should the pin be used for input, in the same way as with P0, #0FFh is written
to the port latches from P1 or P3. However this must take place if alternate
output functions are to be used, since contrary to Port P0 and P2, no switch
exists with P1 and P3.

3.6 external program memory Page 20


Alternate functions of the 8051:


---------------------------------

Port 0: Address (low Byte) and data for external memory access.
Port 2: Address (high Byte) for external memory access.

P3.7 = _RD: Read signal for external data memory access


P3.6 = _WR: Write signal for external data memory access
P3.5 = T1: Timer 1 Gate
P3.4 = T0: Timer 0 Gate
P3.3 = _INT1 external interrupt input 1
P3.2 = _INT0 external interrupt input 0
P3.1 = TxD Send output from the serial port
P3.0 = RxD Receive input from the serial port

electrical characteristics of the ports:


----------------------------------------
Isink = 2,4 mA Port 0 (UoL < 0,45 V guaranteed)
Isink = 1,6 mA Port 1,2,3 (UoL < 0,45 V guaranteed)
Pull-Up 10...30 k Port 1,2,3
Idrive = 0,4 mA Port 0 (UoH > 2,4 V guaranteed)

Important: with all port pins there must be a 1 in the latch, when the pin
is to be used for input!

3.6 Access of the external program memory:


-----------------------------------------

The accessing of external program memory takes place automatically 2 times


every cycle through the hardware (see 3.3 instruction execution). The 8051
has an internal ROM and an input pin _EA (External Access).

_EA = 1 : The instructions of code addresses 0000-0FFFh are read internally.


The instructions of code addresses 1000-FFFFh are read externally.
(8052 has 8 kByte internal ROM: addresses 0000-1FFFh)

_EA = 0 : All the instructions of code addresses are read externally.

The _EA-Pin serves to turn off the internal ROM. _EA cannot be read like the
port pins from the software.

The 8031 has no internal ROM. Here all instructions are read externally.
It is nonetheless recommended that the _EA pin (since it is available with
the 8031 as it has a similar package construction) be put to GND. In the case
of the 8344 (the ROMless version of the 8044) I was already able to note that
it does not function correctly when _EA = 1. It seemed as though it had an
internal ROM. Perhaps it is more convenient for the manufacturer to make one
mask and then print the chips separately.
3.6 external program memory Page 21

_PSEN (Program Store Enable serves as a read signal for the external program
memory. Similarly, the _PSEN cannot be accessed via software.

external program memory read:


-----------------------------
(compare also with 3.3 instruction execution and 3.5 ports):

-- previous ------->|<---------------- this cycle --------------->|


| | | | | |
++ ++ ++ ++ ++ ++ ++ ++
SysClk + ++ ++ ++ ++ ++ ++ ++ +
| | | | | | |
State 5 | 6 | 1 | 2 | 3 | 4 | 5 | 6 |
| ^1.Fetch | | ^2.Fetch | |
+ | ++ | | ++ | |
ALE ++ | ++ | +
+ | ++ | ++ |
_PSEN ++ | ++ | +
| | | | | | |
P2 CCCCCCCCCCCCCCCCCCCCC-CCCCCCCCCCCCCCCCCCCCCCC-CCCCCCCCCCCCCCCCC
| | | | | | |
P0cpuOut AAAAA---------?????---AAAAAAAA--------?????---AAAAAAAA---------
P0epromOut -----DDDDDDDDDDDDD------------DDDDDDDDDDDD-------------------D

CCC = code address


DDD = data out
? = data read
--- = high impedance

The code fetch access begins already in state 5 of the previous cycle with the
application of address. In the middle of state 5 the ALE goes low. For
external access ALE serves as a signal for the address latch to take over the
low address from P0 to store them (see 3.1 ff).
With the end of state 5 the _PSEN goes low and simultaneously P0 goes high
impedance (as input: indicated with a ---). The associated EPROM now places
data to the external data bus (as long as _PSEN = 0).
From the start of state 1 the P0 in 8051 expects data (indicated by the ???,
in addition high impedance). These lie already at the output from the EPROM.
In the middle of state 1 the data will be transferred over P0 to the internal
data bus and _PSEN and ALE will both again be high.

Towards the end of state 1 the (incremented) address for the next code fetch
will be placed.

The above timing diagram shows the ideal execution of both code fetch accesses
in a cycle. Actually all transfers are affected by the switching times.
For correct functioning of the 8051 the observance of the following
timings are required :
- at the latest tPLIV after _PSEN is low, the program memory must put valid
data to the bus.

3.6 external program memory Page 22

- at the latest tAVIV after valid addresses from the 8051 have been given,
the program memory must put valid data to the bus.

The time value depends on the 8051 type (manufacturer). Exact values are to
be taken from the data sheet. Typical valid values (with T = 1/fOscillation):

tPLIV = (3 * T) - 105 ns .... (3 * T) - 150 ns > 100 ns (at 12 MHz)


tAVIV = (5 * T) - 105 ns .... (5 * T) - 150 ns > 267 ns (at 12 MHz)

For program memory often EPROMs and PROMs are used. A typical EPROM indicated
as 27256-250 means that the EPROM has 256 kBIT (= 32 kByte) in terms of
memory cells with an address access time of 250 ns.

Indicated is the address access time: the time from the issue of the address
until valid data is put on the output. The chip enable access time is about
the same (time of application of an active chip select signal until valid
data). The output enable access time (time of application of an active _PSEN
until valid data) is significantly smaller (range in the order of 20 ns to 60
ns). The critical time for the use as program memory of 8051 is the chip
access time (= address access time). If these requirements are fulfilled,
then the other times are also ok.

The input memory must have an address access time of 267 ns


(at 12 MHz CPU crystal). If the chip select is formed with the help of a gate
from the address, the program memory at the gate must have a faster
propagation time.
A GAL 16V8-25 has a propagation time of 25 ns. It may be used with a program
memory with an access time of less than 242 ns. The indicated time tAVIV
(address valid instruction valid) is always important for the input CPU type
and the usable CPU crystal in the data sheets plus the gate propagation time
of the chip select logic.

With a CPU crystal of 12 MHz, one is always safe with EPROMs with 200 ns. For
many uses, 250 ns is enough.

With a MOVC instruction, the read access takes place at the program memory
through the software in the second cycle instead of the 1st code fetch.

3.7 external data memory Page 23

3.7 Accessing external data memory:


------------------------------------

The access of the external data memory takes place in the second cycle of the
execution of the MOVX instruction (see 3.3 instruction execution). That's why
in this cycle there is no code fetch (the only the case where ALE and _PSEN
do not appear). An XDATA access lasts 6 system clocks (twice as long as a
CODE access).

_RD (Port P3.7 pin) serves as a read signal for the external data memory.
_WR (Port P3.6 pin) server as a write signal.
When MOVX instructions are used, these bits in Port 3 - Latch are to be
set (this occurs after a reset).

XDATA read:
------------

-- previous ------->|<----------------- this cycle ---------------->|


| | | | | |
++ ++ ++ ++ ++ ++ ++ ++
SysClk + ++ ++ ++ ++ ++ ++ ++ +
| | | | | | |
State 5 | 6 | 1 | 2 | 3 | 4 | 5 | 6 |
+ | | | | ++ | |
ALE ++ | +
| | | | | | |
+ | | +
_RD ++ | | |
| | | | | | |
P2 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_CCCCCCCCCCCCCCCCC
| | | | | | |
P0cpuOut XXXXXXXXXX--------------------?????-----------CCCCCCCCC--------
P0ramOut ---------------DDDDDDDDDDDDDDDDDDDDDDDD------------------------

XXX = XDATA address


(also compare with 3.6 program memory access)

The XDATA address will already be placed at state 5 of the first cycle of the
MOVX instruction. With MOVX A,@DPTR: at P2 the high address (DPH) and at P0
the low address (DPL). With MOVX A,@Ri: the value from the latch (SFR of P2)
remains at P2 and the address (from Ri) will be placed at P0.
In the middle of state 5 ALE will go low. Consequently, the addresses from P0
can be transferred into an (external) address latch (see 3.1 ff). About the
end of State 6, P0 will go to high impedance (address taken), following which
_RD becomes low. A connected RAM now lays data on the external data bus
(_RD = 0).
From the beginning of state 3, the 8051 expects data at P0 (indicated by the
???). In the middle of state 3, the data will be moved over onto the internal
data bus, following which _RD and ALE will again be high.

Towards the end of state 4 the address for the code fetch of the next cycle
will be placed if a code fetch takes place externally (if internally, then P0
and P2 remain at high impedance - see 3.6 and 3.3).

3.7 external data memory Page 24

An access of the external data memory lasts longer than a code fetch. The ALE
is once not given out. For the access longer times are available:
- at the latest tRLDV after _RD becomes low, the external data memory must
place valid data on the bus.
- at the latest tAVDV after valid addresses from the 8051 have been given,
valid data from the external data memory must be put on the bus.

Generally it is something like (with T = 1/fOsc):

tRLDV = (5 * T) - 105 ns .... (5 * T) - 165 ns > 251 ns (at 12 MHz)


tAVDV = (9 * T) - 105 ns .... (9 * T) - 165 ns > 585 ns (at 12 MHz)

XDATA write:
------------

-- previous ------->|<-------------- this cycle ------------------->|


| | | | | |
++ ++ ++ ++ ++ ++ ++ ++
SysClk + ++ ++ ++ ++ ++ ++ ++ +
| | | | | | |
State 5 | 6 | 1 | 2 | 3 | 4 | 5 | 6 |
+ | | | | ++ | |
ALE ++ | +
| | | | | | |
+ | | +
_WR ++ | | |
| | | | | | |
P2 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_CCCCCCCCCCCCCCCCC
| | | | | | |
P0cpuOut XXXXXXXXX-DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD----CCCCCCCCC--------
P0ramOut --------------------------------------?------------------------

XXX = XDATA address


(compare also with 3.6 program memory access)

The XDATA address will already be placed at state 5 of the first cycle of the
MOVX instruction. With MOVX A,@DPTR: at P2 the high address (DPH) and at P0
the low address (DPL). With MOVX A,@Ri: at P2 the value from the latch
(SFR of P2) and at P0 the address (from Ri).
In the middle of state 5 ALE will go low. Consequently, the addresses from P0
can be transferred into an (external) address latch.
Towards the end of state 6 at P0, the address will be taken away and data be
placed, thereafter the _WR goes low.
At the end of state 3 _WR will again be high. With it the external data
memory takes over the data from P0. Thereafter, P0 will again be at high
impedance and ALE again high.

At the end of state 4 the address for the code fetch of the next cycle will
be placed if the code fetch takes place externally (if internally, then P0
and P2 remains at high impedance - see 3.6 and 3.3).

3.8 external connection, example Page 25

- The 8051 guarantees, that at least tQVWH before _WR is high, valid
data lies on the bus.
- the 8051 guarantees, that at least tWLWH + tAVWL before _WR is high,
a valid address has been given out.

Generally, the following are true (with T = 1/fOsc):

tQVWH = (7 * T) - 105 ns .... (7 * T) - 150 ns > 433 ns (at 12 MHz)


tWLWH = (6 * T) - 100 ns = 400 ns (at 12 MHz)
tAVWL = (4 * T) - 70 ns ..... (4 * T) - 130 ns > 96 ns (at 12 MHz)

For the data memory there exists therefore the requirements of address access
time of 585 ns for reading and 496 ns for writing (at 12 MHz CPU clock). Most
of the types of the series 6264 ... 62256 (static RAMs) have address access
time under 150 ns, so that here no problem should occur.

3.8 Connection for the external data bus (example):


----------------------------------------------------
The address space for CODE and XDATA is separate. The electrical distinction
is achieved through read signals _PSEN (for CODE) and _RD (for XDATA).
A typical connection with EPROM and RAM has already been shown in 3.1. Now we
have here a connection of the overall address space with 64 kByte RAM and 64
kByte EPROM:

++
+_WR>| | ++
| +_RD>| RAM |<o|INV|+
| | | | ++ |
| | +========>| 32kx8 |<===+ |
8051 CPU | | | ++ | |
++ | | | ++ | |
| _WR++|_WR>| | | |
| _RD++|_RD>| RAM |<|+ A15
| | | | | |
| P2+=======ADDRESSBUS==+========>| 32kx8 |<===+
| | ++ | ++ |
| ALE+>|LATCH| | ++ |
| P0|<===+====>| +==+ | | |
| | | ++ +========>| EPROM |<===+
| | | | | |
| _PSEN+|PSEN>| 64kx8 |<+ |
++ | ++ + |
+===DATABUS===========================+

Since static RAMs are available only up to 32kx8, two RAM chips are needed.
The 1st RAM receives as chip select the address A15 and the second RAM the
inverted value of A15. As CODE memory, an EPROM 64kx8 is used. Its chip
enable pin can be put at GND (always selected).

3.8 external connection: example Page 26

The 1st RAM is active at all addresses, at which A15 = 0, so with


0000...7FFFh. The 2nd RAM becomes active with 8000...FFFFh (A15 = 1).

In hardly any circuitry will such a large external data memory be needed.
Therefore most use only one RAM chip. Often a yet smaller RAM is used
(cheaper). Recommended are the types 6264 (8kx8), 62128 (16kx8) and 62256
(32kx8). Smaller types than 8kx8 can admittedly be used, however they are
more expensive.

If only a RAM is inserted in XDATA space, then its chip enable pin can be
placed at GND (always selected). The same memory cell in the RAMs can be
accessed over different XDATA addresses (multiply selected). This is not a
problem when the software is ok.

--- IO Region ------------------------------------------------------

The XDATA region, besides being used for external data memory, can be used
for other purposes. Some examples:

- for the reading of jumper settings or other data through a tristate driver.
- as universal port (8 bit input/output) over bidirectional tristate
drivers (74LS245).
- for connecting special components such as to external analog/digital
converters, to a SCC (serial communication controller) for a second serial
port, to a display module and others.
- as ports to other processors through 8 bit register (realised by the Intel
8044 BITBUS processor card) or over DPR (Dual Port RAM).
(-- see example in Appendix)

With IO functions installed, one or several XDATA addresses must be


reserved. In general an address decoder is then needed.
Often the RAM will be placed in the region from 0000...7FFFh (A15 as Chip
Select) and the IO Region above 8000h.

--- load driver code --------------------------------------------------------

If a constructed processor card with a port is connected for example to a PC,


then it makes sense for one part of the CODE region to use a RAM in order to
load the CODE over the port. An EPROM is always needed, at least for the
loader routine of the port. The code at address 0 (reset address) is read
from the EPROM.

When using an EPROM 16kx8 and a RAM 32kx8 the following setups can, for
example, be made:

XDATA 0000...7FFFh --> access on RAM 0000...7FFFh


CODE 0000...3FFFh --> access on EPROM 0000...3FFFh
CODE 4000...7FFFh --> access on RAM 4000...7FFFh

3.8 external connection, example Page 27

| | |
_PSEN + _PSEN ++_OE |
| | | EPROM |
P2.6 + A14 ++_CE 16kx8|
| | | ++ ++
| | ++ | ++
| | ++ | NOR ++ | ++
8051 | ++ INV ++ | | NOR ++_OE |
CPU | ++ ++ ++ | | |
| ++ | ++ | |
P3.7 + _RD + INV ++ ++_CE |
| ++ + | RAM |
| | 32kx8|
P3.6 + _WR +_WR |
| | |

The diagram shows a possible connection of _PSEN and _RD to the


generation of the RAM read signals for the above example. In this setup,
the CODE up till address 3FFFh from the EPROM and CODE above 4000h works
from RAM.
CODE is loaded into RAM through MOVX. The interrupt vectors are in EPROM.
There the vectors can be connected to the load region via LJMP 4003h, LJMP
400Bh ... , as long as they are not used by the loader routine.

An especially simple realisation of the code execution from the external RAM
(load driver code) can be achieved, when the load routines are burnt into
internal EPROM and _EA = 1 is set. Now _PSEN and _RD need only be connected
over an AND gate. An external EPROM is no longer required.

| o +5V
_EA ++ | |
| ++ ++_CE |
_PSEN + _PSEN + | + | |
| | AND ++_OE |
P3.7 + _RD + | | RAM |
| ++ | 32kx8|
P3.6 + _WR +_WR |
| | |

3.9 internal RAM Page 28

3.9 internal RAM:


------------------

A special feature of the 8051 is its internal RAM of 128 bytes. The access is
faster compared to access over the external RAM and there are different
access methods. With simple programs the 8051 can (in combination with the
internal EPROM) act as a stand alone processor.

Access methods for the internal RAM:


------------------------------------
direct: the internal RAM address is given in the code
register: special instructions for the access of register R0..R7,
which lie in internal RAM at addresses 00..1Fh.
indirect: through pointer. R0, R1, SP can act as pointers
bit: the internal RAM addresses 20h..2Fh can additionally be selected
bitwise.

+ + FF Shown here is the partitioning of the


| | internal RAM as far as addressing
| 80h .. FFh | possibilities are concerned.
| |
80 ++ The 8051 has an internal RAM of 128
| | 7F bytes. The overall regions can be addressed
| | directly or indirectly.
| | The 8052 and others have an internal RAM of
| | 256 bytes. Only 00...7Fh may be directly
| | addressed. The direct DATA addresses above
| | 80h are reserved for SFR (see 3.4)
30 ++
28 | Bit | 2F The addresses 20...2Fh can be bitwise
20 ++ addressed. Assigned are the BIT-
18 | Reg.-Bank 3 | 1F addresses 00..7Fh. The BIT addresses above
10 | Reg.-Bank 2 | 80h are reserved for SFR.
08 | Reg.-Bank 1 |
00 | Reg.-Bank 0 | The registers are situated from 00 to 1Fh
++ (see also 3.4.3 PSW).

Register:
---------
The 8051 has 8 general purpose registers defined. These are not counted as
SFRs (special function registers), since they do not have special hardware
functions such as possessed by TCON, SCON and other SFRs.

The registers are differentiated by the fact that there are special (simple
and fast) instructions for accessing them. They are not like the SFRs, placed
in extra memory cells, rather their values are stored in internal RAM.
This takes place in 8 sequential internal RAM addresses = one register bank.
The active register bank can be selected through two BITs in the program
status word (see 3.4.3 PSW).

If register bank 0 is selected (this is the case after a reset, or


after ANL PSW, #11100111b or CLR RS0 and CLR RS1), R0 is associated with
internal RAM address 00, R1 with 01 and so on. If register bank 3 is
selected, then R0 is associated with address 18h, R1 with 19h and so on.

3.9 internal RAM Page 29

RS1:RS0 Reg Bank DATA address


------------------------------------
00 0 00..07
01 1 08..0Fh
10 2 10..17h
11 3 18..1Fh

The different register banks have benefits when using interrupts:


If a register is used in an interrupt routine, then its contents must be
be saved (PUSH on Stack) upon entry to the interrupt routine. Before the
RETI the register must be restored (POP from Stack). A register bank can
be assigned to an interrupt routine. Now only the register bank has to
be switched around (faster!).
Although the 8051 has five interrupt sources, one can make do with 4
register banks, since there are only 2 interrupt priority levels. An
interrupt can never be intruded upon by another interrupt of the same or
lower priority. Interrupts of the same priority can therefore be
assigned to the same register bank, provided that from the RETI no
values in the register have to be retained until the next interrupt.

Since by a reset only some SFRs, but not the internal RAM are cleared, the
contents of the register during a reset remain provided reg bank 0 was
selected. With a reset, the register bank is switched back to reg bank 0.

R0 and R1 still have, besides the possibility of general purpose use through
the software, the function of index registers in indirect addressing in
internal RAM and pagewise access of the external RAM (see instruction
set).

indirect addressing:
--------------------
In addition, one can have access to the internal RAM indirectly through
pointers. The registers R0 and R1 or the stack pointer (SP) can serve as
pointers. For RAM addresses above 80h (only 8052...) the only possibility
of accessing internal RAM is indirect addressing.

An indirect access through the SP to the internal RAM takes place


automatically with every call up of a subprogram, and also with entry into an
interrupt routine. At the same time, the CPU lays the return address to the
stack (low byte first). For the user, there is also the possibility of placing
values, etc on the stack with the instructions PUSH and to be read back with
a POP (see also 3.4.4 Stack Pointer).

When using R0 or R1 to access internal RAM the address of the memory location
must first be loaded into R0 or R1. The access takes place with a further
instruction:

3.9 internal RAM Page 30

Example:
MOV R0, #30h ; internal RAM address 30h is loaded
MOV @R0, #0Dh ; #0Dh is written in internal RAM 30h

An indirect access must seem complicated, but there are applications, where
indirect addressing is indispensable (e.g. with the handling of text strings,
with receive and send buffers...).

direct addressing:
------------------
Direct addressing permits quick access of data. From the programmer's
viewpoint, this allows for the storage of reserved values at prearranged
fixed addresses in internal RAM memory location. The assembler permits the
definition of variable names.

In the internal RAM of the 8051 (and also the enhanced CPU's 8052, 80535,...)
only 128 bytes can be directly addressed (addresses 00...7Fh). With the
linking of a program the address is put into the code.

Example:
Mnemonic: Opcode:
MOV A, 20h ; content of int RAM 20h in ACC --> E5 20
MOV A, #20h ; the difference: here value in ACC --> 74 20

direct BIT addressing:


---------------------
The internal RAM addresses 20h...2Fh can be selected bitwise. These
memory locations can also be used for flag bank (8 bits to a byte).
The access takes place with special bit instructions.

MSB LSB
+++++++++
| 7F | 7E | 7D | 7C | 7B | 7A | 79 | 78 | DATA 2Fh
| 77 | 76 | 75 | 74 | 73 | 72 | 71 | 70 | DATA 2Eh
| 6F | 6E | 6D | 6C | 6B | 6A | 69 | 68 | DATA 2Dh
| 67 | 66 | 65 | 64 | 63 | 62 | 61 | 60 | DATA 2Ch
| 5F | 5E | 5D | 5C | 5B | 5A | 59 | 58 | DATA 2Bh
| 57 | 56 | 55 | 54 | 53 | 52 | 51 | 50 | DATA 2Ah
| 4F | 4E | 4D | 4C | 4B | 4A | 49 | 48 | DATA 29h
| 47 | 46 | 45 | 44 | 43 | 42 | 41 | 40 | DATA 28h
| 3F | 3E | 3D | 3C | 3B | 3A | 39 | 38 | DATA 27h
| 37 | 36 | 35 | 34 | 33 | 32 | 31 | 30 | DATA 26h
| 2F | 2E | 2D | 2C | 2B | 2A | 29 | 28 | DATA 25h
| 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | DATA 24h
| 1F | 1E | 1D | 1C | 1B | 1A | 19 | 18 | DATA 23h
| 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | DATA 22h
| 0F | 0E | 0D | 0C | 0B | 0A | 09 | 08 | DATA 21h
| 07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | DATA 20h
+++++++++

The LSB of DATA 20h has the BIT address 00. The next bit of DATA 20h
has BIT address 01 and so on:

3.9 internal RAM Page 31

The BIT addresses 80h...FFh are reserved for Special Function Registers, even
when not all SFR addresses are used in the 8051. The SFR are always bitwise
addressable, by which the low nybble is address 0 or 8:

+++++++++ 8051-SFB
B | F7 | F6 | F5 | F4 | F3 | F2 | F1 | F0 | DATA F0h --------
+++++++++
ACC | E7 | E6 | E5 | E4 | E3 | E2 | E1 | E0 | DATA E0h
+++++++++
PSW | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | DATA D0h
+++++++++
IP | BF | BE | BD | BC | BB | BA | B9 | B8 | DATA B8h
P3 | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | DATA B0h
+++++++++
IE | AF | AE | AD | AC | AB | AA | A9 | A8 | DATA A8h
P2 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 | DATA A0h
+++++++++
SCON | 9F | 9E | 9D | 9C | 9B | 9A | 99 | 98 | DATA 98h
P1 | 97 | 96 | 95 | 94 | 93 | 92 | 91 | 90 | DATA 90h
+++++++++
TCON | 8F | 8E | 8D | 8C | 8B | 8A | 89 | 88 | DATA 88h
P0 | 87 | 86 | 85 | 84 | 83 | 82 | 81 | 80 | DATA 80h
+++++++++

Code for internal RAM access:


-----------------------------
For every addressing mode, there are special instructions. --> see also
instruction set.

With the creation of a program it must be observed, that differently addressed


memory locations do not overlap. Large programs quickly
become unclear. With correct application more capable assemblers and linkers
have a chance of error recognition. Memory locations are classified according
to data type.

The following rules should be noted:

- If possible, data should be defined with names at the beginning of source


files. In the program, do not use instructions with absolute addresses,
otherwise clarity is quickly lost.

- "fill" internal RAM beginning with the lowest address. That is:

*** first consider the registers: (in the case of ASM51 and A51 with USING
0, USING 1, etc.) reserve locations, according to the number of the
used register banks.

*** then define flags (since these can only be accommodated in DATA
(20h...2Fh)

3.9 internal RAM Page 32

*** then define direct DATA variables (if there is space, individually
assigned before the flags).

*** then allot locations for use of buffer (IDATA), which are to be
addressed indirectly

*** finally, space is allocated for stack.


Example for ASM51:

USING 1 ; reserve location for register bank 1


USING 0 ; reserve location for register bank 0

FLag1 BIT 0 ; this lies in DATA 20h

Variable1 DATA 10h ; location is still free (Reg Bank 2 unused)


BufPtr DATA 11h ; until 1Fh DATA can still be directly defined
BufCnt DATA 12h ; then watch out because of BIT (addresses)!

buffer IDATA 21h ; the buffer overlaps DATA and BIT


bufferLength EQU 20h
stack IDATA 41h ; Stack begins on top of the buffer - location
; to 7Fh! After reset the SP is to be initialised
; with: MOV SP, #(stack - 1)

the assignment of addresses is performed here "by hand". The ASM51 also offers
the possibility to let this be done through the linker (see assembler).

4. Instruction set Page 33

4. 8051 Instruction set:


-------------------------

All controllers of the 8051 family use the same instruction set. With the
newer (further developed) types, only some SFRs are used to control the
additional hardware functions.

A program consists of a series of instructions. The instructions are stored


in the form of coded numeric values in program memory (fixed value memory
e.g. EPROM). The 8051 has an internal translate table, in which every numeric
value is assigned a definite operation (see appendix).

In order that the 8051 executes a series of instructions (program), the


programmer must write a series of numeric values in the EPROM (machine code
or hexcode). For every instruction, he must look up the numeric value in a
table. This is very unclear and complicated.

A tool which relieves this work is the assembler: it translates a program


written in an abbreviated symbolic language into a series of numeric values.
The abbreviations of the individual instructions are shown as mnemonics. A
program so written down becomes itself an assembler sourcecode or machine
language. With it is processed that which the program language assembler
instructions use at the machine level.
Every instruction which the 8051 should execute later must therefore be
written as mnemonics.

A further popular tool for the generation of 8051 machine code is a C


compiler. C is a high level language, it provides predefined standardised
functions, which according to the call functions in the C sourcefile becomes
linked to the finished program. The functions are written as subroutines in
assembler, then compiled and placed in a library.
The advantage of a high level language such as C is that programs can be
created, which can be linked with another library and then run on different
computers. The programs for the 8051 is not so important, since the C
functions for the 8051 are very special. However, C offers several functions
such as floating point computations, which make the use of C compilers for the
8051 interesting. Many are also already familiar with the language C, which
besides a better clarity of the source files, often also becomes a deciding
point in favour of C.

In the following the complete instruction set of the 8051 is explained.


Indicated are the mnemonics, how they are used by the assembler and the
assigned hexcode. With some instructions, an extra one or two operands
are attached after the op code such as an address or a constant (coded
numeric values, then the instruction label).

In the mnemonics, abbreviations such as MOV (transfer), ADD (addition) etc,


are used. Instead of absolute addresses variable names are allowed. The
SFR names are already known as defaults to some assemblers and can as such be
loaded (for SFRs of the 8051 see 3.4).

4. Instruction set Page 34

Additionally, there are some special abbreviations:


---------------------------------------------------

# constant value follows


@ indirect addressing: Value from the memory digit, on which the
following register shows
A Accumulator (= ACC, but a special opcode is generated, when
A instead of ACC is used)
C Carry-Flag (= CY, but a special opcode is generated, when
C instead of CY is used)
DPTR data pointer (for accessing external data) - is together set from
DPH and DPL.
PC program counter (holds code address)
Ri (with i = 0...1) --> used to indicate that R0 or R1 is allowed for
this instruction.
Rn (with n = 0...7) --> used to indicate that R0 ... R7 are allowed
for this instruction.

In the following every 8051 instruction is briefly explained. To the left


is the code in ASM51 mnemonics and in the square in the middle the opcode
(hexvalue). Every square corresponds to a byte in program code. All the way
to the right is the number ofthe required cycles and the flags, in so far as
they themselves vary.
Mnemonic: Hex Code: Cycles: Flags:
---------------------------------------------------------------------------

To execute many instructions only a CPU cycle is needed. Some, especially


those with access to external memory require 2 cycles. A cycle lasts 6 CPU
system clocks (at 12 MHz quartz oscillator, 1 cycle lasts 1s). In every
cycle the timer, if they are running, increase by 1 increment each.

4.1 Data transfer Page 35

4.1 Data transfer:


--------------------
With the MOV instruction data from an internal register or from internal RAM
can be copied to another internal memory location.

++
MOV A, Rn | 1110 1nnn | 1 P
++
MOV Rn, A | 1111 1nnn | 1 -
+++
MOV A, direct | E5h | dataAdr | 1 P
+++
MOV direct, A | F5h | dataAdr | 1 -
+++
MOV A, @Ri | 1110 011i | 1 P
++
MOV @Ri, A | 1111 011i | 1 -
+++
MOV A, #data | 74h | data | 1 P
+++
MOV Rn, #data | 0111 1nnn | data | 1 -
+++
MOV @Ri, #data | 0111 011i | data | 1 -
+++
MOV Rn, direct | 1010 1nnn | dataAdr | 2 -
+++
MOV direct, Rn | 1000 1nnn | dataAdr | 2 -
+++
MOV @Ri, direct | 1010 011i | dataAdr | 2 -
+++
+++
MOV direct, @Ri | 1000 011i | dataAdr | 2 -
++++
MOV direct, #data | 75h | dataAdr | data | 2 -
++++
MOV direct1, direct2 | 85h | dataAdr2 | dataAdr1 | 2 -
++++

Each operand which is placed on the right in the mnemonic is written on


the left.

What is worth noting is that in the hex code for "MOV direct1, direct2",
the sequence in the hexcode across that in the mnemonic is interchanged.
Example: MOV A, R5 ; ED ->write contents of R5 to ACC
MOV PSW, A ; F5 D0 ->write contents of A to PSW
MOV A, @R1 ; E7 ->write contents of internal RAM,
; address which is in R1, to ACC
MOV R2, #22h ; 7A 22 ->write 22h to R2
MOV R7, 22h ; AF 22 ->write contents of internal RAM
; address 22h to R7
MOV 30h, SP ; 85 81 30 ->write SP to internal RAM addr 30h

4.1 Data Transfer Page 36

With the XCH instruction, data will be exchanged between internal register
or internal RAM and the accumulator.

++
XCH A, Rn | 1100 1nnn | 1 P
+++
XCH A, direct | C5h | dataAdr | 1 P
+++
XCH A, @Ri | 1100 011i | 1 P
++

Example: if reg bank 1 is active, put #16h in DATA 9, in ACC, #9Fh


XCH A, R1 ; C9 -> in ACC #16h and in DATA 9 #9Fh

XCHD interchanges the low nybble of the addressed byte in internal RAM with
the low nybble from the ACC.

++
XCHD A, @Ri | 1101 011i | 1 P
++

Example: Put R0 in #33h, in DATA 33h put #16h, in ACC #9Fh


XCHD A, @R0 ; D6 -> in ACC #96h and in DATA 33h #1Fh

Load data pointer with constant:

++++
MOV DPTR, #data16 | 90h | data16(high) | data16(low) | 2 -
++++

This is the only 16 bit operation of the 8051. It has the same
function as:
MOV DPH, #HIGH(data16)
and MOV DPL, #LOW(data16)

4.1 Data Transfer Page 37


-

external data memory access:

++
MOVX A, @DPTR | E0h | 2 P
++
MOVX @DPTR, A | F0h | 2 -
++
MOVX A, @Ri | 1110 001i | 2 P
++
MOVX @Ri, A | 1111 001i | 2 -
++

When accessing external data memory the _RD becomes the read signal
and _WR becomes the write signal. The access takes place through the
alternative functions of Port 0 and Port 2 (see 3.5). The value in the
latch of Port 2 remains the same. The value in the latch of Port 0
will be overwritten during reading with 0FFH by the hardware.

IMPORTANT!
When indirectly accessing with Ri, only the low address multiplexed
with Port 0 is given out. The content of the latch of P2 remains during
the access at the port output. The user has to write the high byte of
the address into P2 before access when using external RAM.

Example:
MOV DPTR, #0FF00h ; load data pointer
MOVX A, @DPTR ; access (read) external RAM

MOV R0, #0 ; this routine clears the external


MOV P2, #1 ; RAM from address 100h to 1FFh. P2
CLR A ; is loaded with the high byte of the
clearPage1: ; address (=Page), R0 gets the LOW byte
MOVX @R0, A ; R0 is continuously decremented.
DJNZ R0, clearPage1

Read byte from the program memory:

++
MOVC A, @A+DPTR | 93h | 2 P
++
MOVC A, @A+PC | 83h | 2 P
++

A byte from the program memory (external or internal: depending on


the address and /EA Pin) is read into the ACC. The address is the
sum of the contents of ACC and the DPTR or the program counter (earlier
increased by 1 increment) (see also 3.3, 3.5 and 3.6).

The content of the latch of P2 doesn't change in the process, while


before access the hardware writes 0FFh into P0.

4.2 Arithmetic Operations Page 38

Byte to/from stack:

+++
PUSH direct | C0h | dataAdr | 2 -
+++
POP direct | D0h | dataAdr | 2 -
+++

Upon a PUSH the Stack Pointer is incremented by 1 and then the value
is written to this address. With a POP the SP is first read and then
decremented. The stack pointer always points to the final pushed byte.

Subprogram calls and interrupts also push values on to the stack


(see also ACALL, LCALL, RET, RETI). If the stack is full (SP points
to addresses above 7Fh, nevertheless with a PUSH, the SP is further
incremented, the data however gets lost.
The 8044 has an internal RAM of 192 bytes (to address 0BFh). The
8052 has an internal RAM of 256 bytes. When SP overruns over 0FFH
the register region of the 8052's internal RAM is overwritten.

After a Reset the SP stands at address 07.

4.2 Arithmetic operations:


---------------------------

Adding value, register, internal RAM Addr to ACC:

+++
ADD A, #data | 24h | data | 1 C AC P OV
+++
ADD A, @Ri | 0010 011i | 1 C AC P OV
++
ADD A, Rn | 0010 1nnn | 1 C AC P OV
+++
ADD A, direct | 25h | dataAdr | 1 C AC P OV
+++

After the execution the ACC holds the result, the C Flag holds the
overflow in Bit 7 and AC holds the overflow from Bit 3. The OV flag is
set, when a sign error occurs (see 3.4.3 PSW).

Example: before ADD: after ADD:


ADD A, #44h ; A = 33h --> A = 77h, C = 0, AC = 0, OV = 0
ADD A, #44h ; A = 43h --> A = 87h, C = 0, AC = 0, OV = 1
ADD A, #4Ah ; A = 2Ah --> A = 74h, C = 0, AC = 1, OV = 0
ADD A, #93h ; A = 0B1h --> A = 44h, C = 1, AC = 0, OV = 1

4.2 Arithmetic Operations Page 39

Add value, register, internal RAM addr. to ACC with Carry:

+++
ADDC A, #data | 34h | data | 1 C AC P OV
+++
ADDC A, @Ri | 0011 011i | 1 C AC P OV
++
ADDC A, Rn | 0011 1nnn | 1 C AC P OV
+++
ADDC A, direct | 35h | dataAdr | 1 C AC P OV
+++

As addition without carry. However, the value of the Carry flag is added
as well.

Example: before ADD: after ADD:


ADDC A, #44h ; A = 33h, C = 1 --> A = 78h, C = 0, AC = 0, OV = 0
ADDC A, #44h ; A = 33h, C = 0 --> A = 77h, C = 0, AC = 0, OV = 0

Subtract value, register,internal RAM addr. from ACC with Carry:

+++
SUBB A, #data | 94h | data | 1 C AC P OV
+++
SUBB A, @Ri | 1001 011i | 1 C AC P OV
++
SUBB A, Rn | 1001 1nnn | 1 C AC P OV
+++
SUBB A, direct | 95h | dataAdr | 1 C AC P OV
+++

Subtract immediate data, indirect byte, contents of Rn rsp. direct


byte plus the Carry flag from ACC. Flags see ADD.

Increment = the contents of the given register increases by 1.

++
INC A | 04h | 1 P
++
INC Rn | 0000 1nnn | 1 no Flags
++
INC @Ri | 0000 011i | 1 no Flags
+++
INC direct | 05h | dataAdr | 1 no Flags
+++
INC DPTR | A3h | 2 no Flags
++

4.2 Arithmetic Operations Page 40

Decrement = the contents of the indicated register is decreased by 1.

++
DEC A | 14h | 1 P
++
DEC Rn | 0001 1nnn | 1 no Flags
++
DEC @Ri | 0001 011i | 1 no Flags
+++
DEC direct | 15h | dataAdr | 1 no Flags
+++

Multiply ACC with B-Register:

++
MUL AB | A4h | 4 C P OV
++

The result is in ACC. When the result is a word, the low Byte is in ACC,
the high byte in B and the OV flag is set. The C Flag is always cleared
(C = 0).

Divide ACC by B register:

++
DIV AB | 84h | 4 C P OV
++

The result is in ACC and the remainder in B. When an error (Division


by 0) occurs the OV - Flag is set. The carry flag is always cleared.

Decimal adjust of ACC:

++
DA A | D4h | 1 C P
++

When two BCD numbers are added together, the result must thereafter be
corrected, it should also come out in BCD format.
If the AC flag is set, or the low nybble > 9, then 6 is added. If the
C flag is set, or the high nybble > 9, then 60h is added. When there is
an overflow of bit 7 of the ACC in the result, then the carry flag (C=1)
is set.

4.3 logical associations Page 41

Example: bcd_59 = 0101 1001


bcd_68 = 0110 1000
+
after ADD (without correction): bcd_C1 = 1100 0001 (Flags: AC=1, C=0)
because of (AC=1): 0000 0110
because of (high nybble > 9): 0110 0000
+
result (with correction): bcd_27 = 0010 0111 (Flags: C=1)

4.3 logical associations:


--------------------------

+++
ANL A, #data | 54h | data | 1 P
+++
ANL A, @Ri | 0101 011i | 1 P
++
ANL A, Rn | 0101 1nnn | 1 P
+++
ANL A, direct | 55h | dataAdr | 1 P
+++
ANL direct, A | 52h | dataAdr | 1 no Flags
++++
ANL direct, #data | 53h | dataAdr | data | 2 no Flags
++++

bitwise logical AND association:


when both bits 1, then 1

+++
ORL A, #data | 44h | data | 1 P
+++
ORL A, @Ri | 0100 011i | 1 P
++
ORL A, Rn | 0100 1nnn | 1 P
+++
ORL A, direct | 45h | dataAdr | 1 P
+++
ORL direct, A | 42h | dataAdr | 1 no Flags
++++
ORL direct, #data | 43h | dataAdr | data | 2 no Flags
++++

bitwise logical OR association:


when one of the two bits is 1, then 1

4.3 logical associations Page 42

+++
XRL A, #data | 64h | data | 1 P
+++
XRL A, @Ri | 0110 011i | 1 P
++
XRL A, Rn | 0110 1nnn | 1 P
+++
XRL A, direct | 65h | dataAdr | 1 P
+++
XRL direct, A | 62h | dataAdr | 1 no Flags
++++
XRL direct, #data | 63h | dataAdr | data | 2 no Flags
++++

bitwise logical XOR association:


when both bit are different, then 1

++
CLR A | E4h | 1 P
++

clear ACC --> ACC = 0

++
CPL A | F4h | 1 P
++

Complement to ACC --> ACC is bitwise inverted

++
RL A | 23h | 1 no Flags
++

rotate ACC bitwise to the left:


slides contents of ACC bitwise to the left. The highest bit is written
to the lowest. The parity flag does not change, since the sum above all
the bits remains the same.
++
RLC A | 33h | 1 P C
++

rotate ACC bitwise from the left through Carry :


slides contents of ACC bitwise to the left. The highest bit is
consequently in C and C is written to the lowest bit.

4.4 Bit manipulations Page 43

++
RR A | 03h | 1 no Flags
++

rotate ACC bitwise to the right:


slides contents of ACC bitwise to the right. The lowest bit is
written to the highest. The parity flag itself is not changed, since
the sum over all the bits stays the same.

++
RRC C | 13h | 1 P C
++

rotate ACC bitwise to the right through Carry:


slides Contents of ACC bitwise to the right. The lowest bit is in C
and C is written into the highest bit.

++
SWAP A | C4h | 1 no Flags
++

the low nybble of the ACC is interchanged with the high nybble

4.4 Bit-Manipulation:
----------------------

+++
MOV C, bit | A2h | bitAdr | 1 C
+++
MOV bit, C | 92h | bitAdr | 2 no Flags
+++

copy contents from bit address to C or C to bit address.


+++
ANL C, bit | 82h | bitAdr | 2 C
+++
ANL C, /bit | B0h | bitAdr | 2 C
+++

logical AND bit or inverted value of bit to C

4.5 absolute jumps and CALL's Page 44

+++
ORL C, bit | 72h | bitAdr | 2 C
+++
ORL C, /bit | A0h | bitAdr | 2 C
+++

logical OR bit or inverted value of the bit to C

++
CLR C | C3h | 1 C
+++
CLR bit | C2h | bitAdr | 1 no Flags
+++

clear bit or Carry-Flag --> Bit = 0

++
CPL C | B3h | 1 C
+++
CPL bit | B2h | bitAdr | 1 no Flags
+++

invert bit or carry flag

++
SETB C | D3h | 1 C
+++
SETB bit | D2h | bitAdr | 1 no Flags
+++

set bit or Carry-Flag --> Bit = 1


4.5 absolute jumps and CALLs:
----------------------------------

CALL codeAdress

This is not a machine instruction of the 8051. The assembler itself


determines here whether a ACALL or LCALL is to be used. By "Forward
References", i.e. addresses, which the assembler at this point does not
yet know, a LCALL is always inserted, even when an ACALL is enough.

4.5 absolute jumps and CALL's Page 45

JMP codeAdress

This is not a machine instruction of the 8051. The assembler itself


determines here if an SJMP, AJMP or LJMP is to be used. With "forward
references" an LJMP is always inserted, even if it is not efficient.

+++
ACALL codeAdr | A10 A9 A8 1 0001 | A7 A6 A5 A4 A3 A2 A1 A0 | 2 no Flags
+++

Absolute CALL (within a 2 KByte Page):


The PC (Program Counter) is incremented by 2 and the return address
is placed on the stack (low byte first). Then the following
address is loaded into the PC:
A11 to A15 into PC (Program Counter) remain unchanged,
the lower 11 bits are loaded from the opcode.

++++
LCALL codeAdr | 12h | CodAdrHigh | CodAdrLow | 2 no Flags
++++

Long CALL:
The PC (Program Counter) is incremented by 3 and the return address is
loaded on the stack (low byte first). Then it is loaded with the value
from the opcode.

++
RET | 22h | 2 no Flags
++

Return from subprogram (CALL):


The return address is fetched from the stack (high byte first) and
jumped to.
++
RETI | 32h | 2 no Flags
++

Return from Interrupt:


The CPU has taken note in an internal register, which interrupts
are being handled. There can also be two interrupts, since there are
two priority levels, and a routine at a lower level of an interrupt
can be disrupted by one of a higher level. When an interrupt is being
serviced, all other interrupts at equal or lower priority level are
blocked. With RETI, the interrupt with the higher value is deleted and
the interrupts are free again.

4.5 absolute jumps and CALL's Page 46

The return address is fetched from the stack (high byte first) and
jumped to.

Warning: Should a software reset MOV A, #0


take place within an interrupt PUSH ACC
routine through a jump to 0000, PUSH ACC
the jump must then take place MOV A, #LOW(retiReset)
over a double RETI, since PUSH ACC
otherwise the internal Enable MOV A, #HIGH(retiReset)
Register contrary to a hardware PUSH ACC
reset, would not be cleared. retiReset:
RETI

+++
SJMP codeAdr | 80h | relOffset | 2 no Flags
+++

Short JUMP (-128 +127):


The PC is incremented by 2 and with it is the relOffset added.
The highest bit of the value relOffset acts as the sign.

For computation: the relOffset (BYTE) is first converted to a WORD


(on an 8088 compatible CPU by means of CBW). If the relOffset is negative
(high bit is set), 0FF00h is added to it, otherwise 0. This WORD is
added to the incremented PC.

Example: relOffset = 47h --> 0047h + PC


relOffset = 87h --> FF87h + PC

+++
AJMP codeAdr | A10 A9 A8 0 0001 | A7 A6 A5 A4 A3 A2 A1 A0 | 2 no Flags
+++

Absolute JUMP (within 2 KByte Page):


The PC is incremented by 2 and the address is then constructed in the
following manner: A11 to A15 in PC (program counter) remains unchanged,
the lower 11 bits are loaded from the opcode.
++++
LJMP codeAdr | 02h | CodAdrHigh | CodAdrLow | 2 no Flags
++++

Long JUMP:
Jump to the address indicated in the opcode.

4.6 conditional jumps Page 47

++
JMP @A+DPTR | 73h | 2 no Flags
++

Jump indirectly to Accumulator + Data Pointer:


Add contents from ACC and DPTR, then jump to this address.

4.6 conditional jumps:


-----------------------
Jump by the relative offset, when the condition is fulfilled. For the
computation of the target address see SJMP (4.5 unconditional jump).

+++
JZ codeAddress | 60h | relOffset | 2 no Flags
+++
JNZ codeAddress | 70h | relOffset | 2 no Flags
+++

jump, when ACC = 0 or when ACC not = 0

+++
JC codeAddress | 40h | relOffset | 2 no Flags
+++
JNC codeAddress | 50h | relOffset | 2 no Flags
+++

jump, when C = 1 or C = 0

++++
JB bit, codeAdress | 20h | bitAdr | relOffset | 2 no Flags
++++
JNB bit, codeAdress | 30h | bitAdr | relOffset | 2 no Flags
++++
JBC bit, codeAdress | 10h | bitAdr | relOffset | 2 no Flags
++++

jump, when bit = 1, or Bit = 0:


In the case of JBC: Jump, when bit = 1 and clear bit.

4.6 conditional jumps Page 48

++++
CJNE A, direct,codeAdr | B5h | dataAdr | relOffset | 2 C
++++
CJNE A, #data, codeAdr | B4h | data | relOffset | 2 C
++++
CJNE Rn, #data,codeAdr | 1011 1nnn | data | relOffset | 2 C
++++
CJNE @Ri,#data,codeAdr | 1011 011i | data | relOffset | 2 C
++++

compare and jump, when not equal:


If the left operand less than the right, the carry flag is subsequently
set (C = 1).

+++
DJNZ Rn, codeAdr | 1101 1nnn | relOffset | 2 no Flags
++++
DJNZ direct, codeAdr| D5h | dataAdr | relOffset | 2 no Flags
++++

Decrement and jump after that, when contents not equal to 0

++
NOP | 00h | 1 no Flags
++

no action. NOP is often used when a waiting time has to be passed through.
With a crystal of 12 MHz one NOP takes 1 s.

++
reserved | A5h | ? ?
++
invalid opcode. No instruction is assigned to this HEX code.

5. Assembler Page 49

5. Assembler:
~~~~~~~~~~~~~~
An assembler is used to translate a program written with mnemonic symbols
into executable HEX code. Every instruction is individually written in
source code. Some assemblers may offer the possibility of defining MACROs,
but even there every single instruction is defined in the source file. MACROs
act only as an abbreviation for instructions which often repeat themselves.

The assembler translates every individual instruction to the corresponding


HEX code (see 4. instruction set). The assembler also calculates the target
addresses for a JMP or CALL.

For the 8051 there are a number of commercial assemblers such as the ASM51
from Intel or the A51 from Keil. But there are also several shareware products
such as TASM, which are equally suitable. From the magazine Elektor, there is
an assembler course which is currently being carried out (start: 09.1991) and
at the same time, there is also a cost effective assembler EASM51. However
EASM51 generates HEX which is self defined. Most other assemblers generate HEX
code in Intel HEX format.

--- There is now also a public domain macro assembler (AS), from
Alfred Arnold, Prlat-Lewen-Str.3, 5206 Neukirchen 1
Request from: ftp.rog.rwth-aachen.de (directory pub/assembler)

5.1 ASM51:
~~~~~~~~~~~~~~~
The ASM51 and the A51 are largely compatible. The assembler itself generates
an object file. This file cannot be loaded into an EPROM or into an 8051
processor. The object file contains as yet no absolute addresses. In the
source code, defined segments (in the code region), being relocatable, can
still be moved around within the 64 kByte address location.

The address allocation is handled by the Linker (RL51.EXE). The linker


generates an absolute file. The program is now assigned code addresses.
This process has its advantages in large programs. The linker can link
together several object files into an absolute file. A program can be created
from several smaller modules.
It remains clearer, besides, the ASM51 is this way suitable for use in
companies where often several people work on a program.

In addition, there is the possibility of putting together into a library file


general routines, which are used frequently (LIB51.EXE). Through the Linker,
library routines can be bound into an absolute file.

The absolute file still cannot be loaded into various Eproms. It still
requires a converter program from Absolute to HEX format (OH.EXE).

Assembler: ASM51 --> Object file


Linker: RL51 --> Absolute file
Converter: OH --> HEX-File

5. Assembler Page 50

Note: The absolute and the object file have the same structure: The
files consist of contiguous RECORDs. Every record starts with a byte,
which defines the record type, after that follows a word with the number
of bytes which follow in the record body. At the end another byte follows
with a checksum. The structure of the record body varies according to
the record type. Absolute and object files hold code in binary
form. Additionally it can contain variable names defined in the source
file.

Even when an object file contains code in binary form, it should not be
confused with a binary file. Binary files are used by simple assemblers
and eprom programmers. Binary files only contain code. The offset inside
the files is equal to the address.
Binary files such as those of short programs which begin at offset 0000
are very compact. With object files, the record type and the record
length are still placed at the beginning. With programs which contain
code with high addresses, the binary file becomes more substantial
quickly. Unused addresses which lie before that must be filled up with
0FFh.

HEX-Files contain only code. Every byte is represented as an ASCII HEX


digit. They can be viewed with a normal editor. Hex Files are standard
for loading onto many Eprom programmers.

In this description we will not go into the various enhancements of an


assembler such as the ASM51. Rather, we'll explain only briefly the essential
syntax involved in the creation of a small program.

The ASM recognizes all mnemonics, such as defined in chapter 4. The ASM51
also recognizes the default SFR and SFB definitions of the 8051. Therefore
the abbreviation PSW DATA 0D0h need not, for example be defined; PSW can be
directly used.

For bit addresses the predefined SFB name can likewise be brought in. The SFR
name of the (DATA-)byte, in which this bit is located, can also be used. The
the number of the bit can be indicated after a period.
Example:
The Auxiliary Carry flag (BIT 0D6h) is located SETB 0D6h
in the Program Status Word (DATA 0D0h). SETB AC
The following instructions lead to the same SETB PSW.6
result.

If code for another CPU is be generated, then the additional SFR and SFB must
be defined. Here an Include File is used in practice. With ASM51, include
files with the SFR definitions for other CPUs are included on the disk. The
Include files contain all the SFR definitions for the CPU, including those
which the ASM51 already recognizes by default (of the 8051). The ASM51 brings
in such a case an error message; for that reason the SFR definitions which are
known to be default will be turned off with the instruction $NOMOD51.
5. Assembler Page 51

Instruction (directives) can be indicated as well in the source file to


control the assembler. Only the most important are explained here. Most of
the others are concerned anyway with the format of the listing file.

$noMOD51 the SFRs for the 8051, which are otherwise known to be the
default, are turned off. $NOMOD51 must be placed at the beginning of
the source file.

$INCLUDE(fileName) the mnemonics which are contained in the indicated


file will take over, at the location in the assembler source file where
$INCLUDE stands. The Include file must contain valid source code.

$DEBUG the variable definitions are taken over as debug information into
the Object File. $DEBUG is placed at the beginning of the source files.

$DEBUG and $NOMOD51 can also be given at the command line (then without $).

With USING n (n = 0..3) the Register bank can be reserved. The Linker reserves
the appropriate addresses in the internal RAM. Default is set at USING 0.

ASM51 knows the following code addresses by default. These definitions


are not switched off even with the instruction noMOD51.

RESET CODE 00h Note: for the 8052 the definition


ExtI0 CODE 03h Timer2 CODE 2Bh should
Timer0 CODE 0Bh still be inserted
ExtI1 CODE 13h into the Include file
Timer1 CODE 1Bh with the SFR definitions.
SINT CODE 23h

5.2 Segments under ASM51:


-------------------------------

A program can already be prepared with fixed addresses in the source code, or
written to be relocatable. These options may also be used in combination.

The addressing mode of the type DATA, IDATA, XDATA, BIT or CODE is
correspondingly assigned to the variables of the various memory regions or of
the code. A segment indication of the correct type is to be preassigned to
each variable definition or code procedure.

5. Assembler Page 52

5.2.1 fixed address assignment:


-----------------------------
A fixed address assignment is the simplest way to create a program in ASM51.
Here the addresses which are already fixed are placed in the object file. The
linker cannot move the translated code regions about anymore.

At professional programmer sites, fixed segments are only used where the
hardware necessitates fixed addresses. For example, with jump addresses for
reset and the interrupts. But also for certain fixed addresses in XDATA
region (if a hardware extension is built under a certain definite address
there).

A fixed address assignment is achieved by first using one of the following


key words:

CSEG, XSEG, DSEG, ISEG, BSEG

The additional "AT addr" may follow the above keywords. With that, the
beginning of the segment is set on a definite fixed address. Otherwise, the
ASM51 by default begins every segment with 0000.

A segment remains open until a new key word (from the above) is indicated. At
the beginning of the source files the assembler assumes a default CSEG AT 0000.

Naturally, code can only be entered in the CSEG. For that, the mnemonics,
which are explained in chapter 4 are used. In addition, there are the
following pseudo instructions to facilitate the inclusion of text, tables or
fixed values in the code:

DB byte ; reserve 1 Byte (? means value = any)


DW word ; reserve 1 Word

Example:

DB 0A5h ; Hex value A5h


DB 'This is a Text.',0 ; Text in quotes followed by hex value 0
DW label1 ; Hex value of the address of Label1. The
; high byte is first stored.

In other segments (DSEG, ISEG, XSEG or BSEG) code mnemonics cannot be stored.
Here only variable names are defined. The location for every defined variable
is defined with a DS. In every segment type, variables are fixed by a label.
Every label has a : placed after it.

DS n reserve n Bytes
DBIT n reserve n Bit

5. Assembler Page 53

Example:

ISEG AT 30h
buffer: DS 20 ; 20 bytes reserved for buffer
stack: DS 12

CSEG ; now continues with Code = ISEG closed


.......

For a very simple program the use of segments may be omitted. Then, the
variable names are defined with following directives (example):

dAdr1 DATA 23h


iAdr1 IDATA 8Fh
xAdr1 XDATA 1234h
bAdr1 BIT 0
cAdr1 CODE 0FFF0h
value1 EQU 1 ; Definition of a fixed value

This form is used also for the definition of SFRs for other CPUs other than
the 8051, in order to incorporate it with an INCLUDE.

Simple assemblers often recognize only the EQU assignment. There, variables
of type DATA, XDATA, IDATA and BIT are also defined with EQU. The ASM51 can do
this as well. However, error messages which are generated by ASM51 are
lost, if a variable with a wrong type is used in an instruction.

Simple assemblers also do not use the directive CSEG AT Addr, in order to
begin the assembling of a code address, rather they use ORG addr.

When creating a program, often only the following directives are needed:

END ; This key word must be placed at the end of the assembler
; source file.

$ ; instead of this symbol, the ASM51 always brings in the


; actual address of the PC.

5. Assembler Page 54

---------------------------------

With relocatable segment statements, first the segment names are defined in
the following form. Several identical segment types can also be defined.
segNameC SEGMENT CODE
segNameX SEGMENT XDATA
segNameD SEGMENT DATA
segNameI SEGMENT IDATA
segNameB SEGMENT BIT

The following keywords are then to be placed before the individual areas:

RSEG segNameC
RSEG segNameX
RSEG segNameD
RSEG segNameI
RSEG segNameB.

The entry of code mnemonics and variable definition takes place just as with
fixed segments.

In connection with relocatable written program modules, the following


directives are important:

PUBLIC varName1, varName2,... ; Variable names are made known to the


; linker

EXTRN CODE (cAdr1,cAdr2,...) ; Variable names are externally declared.


EXTRN DATA (dAdr1,dAdr1,...) ; With that, the assembler knows that they
EXTRN IDATA (iAdr1,....) ; are defined in another segment.
EXTRN XDATA (xAdr1,....)
EXTRN BIT (bAdr1,bAdr2....)
EXTRN NUMBER (value1,value2...)

5.3 ASM51 call:


------------------

The calling up of the assembler, linker and converter program occurs in the
form below. The statements in the <> are optional. Otherwise, as default,
the object file receives the extension .obj, the listfile .lst and the
absolute file receives no extension. The default setting of the size of the
internal RAM in the linker is 128 bytes.

ASM51 sourcename <OJ(objectname)> <PR(listname)>


RL51 objectname <TO absolutename> <RAMSIZE(256)>
OH absolutename TO hexname

5. Assembler Page 55

5.4 Program example:


---------------------
Following program example shows how the variable names are defined
absolutely. A serial interrupt routine is shown in which a received character
is sent back as an echo.

We are working only with CSEG. The code begins with the default setting of
CSEG AT Reset with address 0. The interrupt routine is fixed and situated at
the address 23h.

++
|TxFlag BIT 00 ; Bit0 in DATA 20h as flag |
|stack IDATA 21h ; address in internal RAM for stack |
| |
|;CSEG AT reset ; Code starts at default label Reset |
| AJMP init ; Jump to the initialisation |
| |
|CSEG AT SINT ; address 23h is the entry point for SINT|
| JNB RI, sintChkTx ; has something been received? |
| PUSH ACC |
| MOV A, SBUF ; read in |
| CLR RI ; receive buffer again ready |
| JB TxFlag, echoChar |
| JNB TI, $ ; wait until send buffer is free |
|echoChar: |
| MOV SBUF, A ; send back as echo |
| CLR TxFlag |
| CLR TI ; Mark that send buffer is full |
| POP ACC |
|sintChkTx: |
| JNB TI, sintRet ; when send buffer empty interrupts, then|
| SETB TxFlag ; flag is set, thereafter clear TI so |
| CLR TI ; serial interrupt is accessible again |
|sintRet: |
| RETI |
| |
|init: |
| MOV SP, #(stack - 1) ; stack placed |
| MOV IE, #90h ; enable SINT |
| MOV SCON, #50h ; serial port and timer 1 |
| MOV TH1, #0FDh ; initialise |
| MOV TMOD, #20h |
| SETB TR1 |
| JMP $ ; Waiting loop. Interrupt on receive |
| |
|END |
++
In the above program, the subsequent placement of the code in program
memory is already fixed during the assembly.

In the following page, another program example with relocatable code


is presented:

5. Assembler Page 56

++
|idataSeg SEGMENT IDATA ; Name for relocatable segments |
|dataSeg SEGMENT DATA ; are defined. |
|codeSeg SEGMENT CODE |
| |
| PUBLIC initRingBuf |
| PUBLIC putCharToBuf, getCharFromBuf |
| |
| USING 0 ; reserve Register bank 0 |
| |
|RSEG dataSeg ; |
| rdBufPtr: DS 1 ; Read pointer for ringbuffer |
| wrBufPtr: DS 1 ; Write pointer for ringbuffer |
| |
|RSEG idataSeg ; read in |
| ringBuf: DS 30 ; 30 Bytes for Ringbuffer |
| |
|RSEG codeSeg |
| initRingBuf: ; Initialisation routine |
| MOV rdBufPtr, #ringBuf ; read pointer on buffer start |
| MOV wrBufPtr, #ringBuf ; write pointer on buffer start |
| RET |
| |
| putCharToBuf: ; wrBufPtr shows the |
| XCH A, wrBufPtr ; location in buffer, |
| INC A ; where it will be written |
| CJNE A, #(ringBuf+30), noRingBufTop ; to next. |
| MOV A, #ringBuf |
| noRingBufTop: ; write without regard, |
| CJNE A, rdBufPtr, leaveRdBufPtr ; as to whether reading |
| INC rdBufPtr |
| CJNE rdBufPtr, #(ringBuf+30), leaveRdBufPtr |
| MOV rdBufPtr, #ringBuf ; has been completed. |
| leaveRdBufPtr: ; If a character is not |
| XCH A, wrBufPtr ; read in time it will be |
| MOV @R0, A ; lost. |
| RET |
| |
| getCharFromBuf: |
| MOV A, rdBufPtr ; when the read pointer is |
| CJNE A, wrBufPtr, getCharDo ; equal to the write pointer, |
| SETB C ; the buffer is empty. Then RET|
| RET ; with carry. |
| getCharDo: |
| MOV R0, A |
| MOV A, @R0 ; After reading, increment the |
| INC R0 ; read pointer. |
| CJNE R0, #(ringBuf+30), leaveRdBufPtrR0 |
| MOV R0, #ringBuf |
| leaveRdBufPtrR0: ; The read pointer points to |
| MOV rdBufPtr, R0 ; the next byte to be read. |
| CLR C |
| RET |
|END |
++

5. Assembler Page 57

The above program is fully relocatable. It can be linked with another program
by the linker. The program can be used by routines which have been made ready
here to handle ringbuffers by invoking it through CALLs. Note however that
R0 which passes over the character in the accumulator, is destroyed and that
in a read the carry is set in the event the buffer is empty, and that as
such no character can be read.

In practice such routines are often used in connection with an interrupt


routine. For example with serial reception. In any case, in an interrupt
routine, firstly all used registers and flags must be saved and then the
received character is registered in a ringbuffer.
The procedure putCharToBuf is correspondingly to be completed. The reading of
the ringbuffer takes place through the main program.

5.5 ASM51 - Bugs:


------------------

The ASM51 has some peculiarities, be forewarned:

The ASM51 does not recognize PCON DATA 87h, although this is an SFR of
the 8051.

Several editors set asc26 as end of file code at the end of the
source code. ASM51 brings this up as an error, but continues correctly.
With such files the error message 2 ERRORS FOUND can be ignored.

When reading in characters from a file, ASM51 clears the most significant
bit of every byte. As such, asc8Dh is treated like asc0Dh. For that reason
values greater than asc7Fh cannot be used in strings (also not , , , ).
asc8Dh = '' (will also be confused with end of line inside a comment.)

The character asc25h = '%' is reserved in ASM51 for the identification


of MACROs. It may not be used in strings. ASM51 might even make an error,
when a '%' is placed in a comment.
The character ascA5h = '' may also not be used.

Only the first 31 characters of variable names will be evaluated, extra


characters are ignored. This is not a bug, the programmer should only take
note.

6.1 Interrupt logic Page 58

6. Further hardware components of the 8051:


-------------------------------------------

6.1 Interrupt logic:


---------------------

The 8051 has 5 sources of interrupts. The interrupt logic incorporates the
registers IE (Interrupt Enable), IP (Interrupt Priority) and several flags
of TCON (Timer Control).

When the requirement for an interrupt is fulfilled and the interrupt is


enabled, then the CPU interrupts the current program, pushes the return
address onto the stack and then it will activate an interrupt
routine. However the flags will not be automatically saved (such as in an
8088). A fixed jump address is assigned to every interrupt source.

EXTI0 CODE 0003h ; external interrupt input _INT0 (P3.2)


Timer0 CODE 000Bh ; Timer 0 overflow
EXTI1 CODE 0013h ; external interrupt input _INT1 (P3.3)
Timer1 CODE 001Bh ; Timer 1 overflow
SInt CODE 0023h ; serial interrupt: Receive (RI) or Transmit (TI)

The interrupts can be disabled with software. They can only be generated
when the corresponding bit in the Interrupt Enable register is set.
Additionally, EA must be 1. The flags in the IE register can be bit addressed.
Consequently, all interrupts can be disabled with CLR EA. With SETB EA all
those that were set are enabled again. After a reset all interrupts are
disabled (IE = 0xx00000b).

+++++++++
| EA | _ | _ | ES | ET1 | EX1 | ET0 | EX0 | IE DATA 0A8h
+++++++++

EX0 BIT 0A8h ; enable external INT0


ET0 BIT 0A9h ; enable Timer0 interrupt
EX1 BIT 0AAh ; enable extern INT1
ET1 BIT 0ABh ; enable Timer1 interrupt
ES BIT 0ACh ; enable serial interrupt
EA BIT 0AFh ; enable/disable all set interrupts

The 8051 works with 2 interrupt priority levels. Through the Interrupt
Priority register (IP) a priority level may be assigned to every interrupt
source (1 = high Priority).

+++++++++
| _ | _ | _ | PS | PT1 | PX1 | PT0 | PX0 | IP DATA 0B8h
+++++++++

PX0 BIT 0B8h ; external INT0 priority


PT0 BIT 0B9h ; Timer0 interrupt priority
PX1 BIT 0BAh ; external INT1 priority
PT1 BIT 0BBh ; Timer1 interrupt priority
PS BIT 0BCh ; serial interrupt priority

6.1 Interrupt logic Page 59

An interrupt in process cannot be disrupted by another interrupt of the same


or lower priority level. But an interrupt with higher priority
can do so with a lower interrupt. The 8051 takes note in an internal register
which interrupts are in process. There can be a maximum of 2 simultaneously,
since there are only 2 priority levels. With a RETI the highest interrupt is
the one to be executed.

When two interrupts of equal priority occur simultaneously, EXTI0 has


preference over Timer0, EXTI1, Timer1, SINT (this row-sequence within a
priority level).
In state 5 of every cycle (see 3.2 Oscillator and 3.3 instruction execution)
the interrupt requirements will be latched in the flags (see below). In the
following cycle these requirements will be examined (poll). If this is the
last cycle of an instruction (there are instructions which last 2 cycles) an
LCALL to the interrupt routine takes place. When this is not so, polling
is done one cycle later.

However an LCALL is not generated, when the interrupt is disabled, when


another interrupt is in process (priority?) or when the last instruction is a
RETI or there was an access of IE or IP. Sometimes this is the result, that
when an interrupt is in service, and another is activated, that after the
RETI, firstly at least one instruction of the main routine will be executed,
before a jump into the activated interrupt takes place.

Before every poll, the new interrupt requirements will be taken over anew in
state 5 of the previous cycle. The CPU will not jump on an active interrupt,
when it was blocked, and now removed.

The following flags serve as interrupt requests :

IE0 (in TCON) external INT0 flag


TF0 (in TCON) Timer 0 overflow flag
IE1 (in TCON) external INT1 flag
TF1 (in TCON) Timer 1 overflow flag
RI (in SCON) serial Receive full
TI (in SCON) serial Transmit empty

An interrupt request occurs when the corresponding flag is set. In a serial


interrupt one of these two suffices: RI or TI.
For that the software must check in the interrupt routine, which (RI or TI
or both) interrupt has to be cleared.

RI is set by the hardware, as soon as a character is received over the serial


port and is waiting in SBUF. TI is set by the hardware as soon as when sent,
SBUF is empty again. RI and TI must be reset again by software.

TF0 and TF1 will be set by the hardware, when a timer overflow past 0
takes place. By jumping into the interrupt routine TF0 and TF1 will be
automatically cleared by the hardware.

6.1 Interrupt logic Page 60

The external interrupts have a special feature: they can be changed to be


"edge triggered" with flags IT0 or IT1 (in TCON).

With level triggering (IT0 = 0, rsp. IT1 = 0) the inverted value of the port
pins _INT0 = P3.2 rsp. _INT1 = P3.3 are placed into IE0 or IE1 in state 5
of every cycle. Level triggering therefore has no value to set or clear the
flags IE0 and IE1 by software. The flags always reflect the status of the
inputs.

With edge triggering the flags IE0 or IE1 will first be set by the hardware,
when a negative edge occurs at _INT0 or _INT1. By jumping into the interrupt
routine IE0 or IE1 will automatically be cleared by the hardware. But they
can also be changed by the software.

TCON contains different flags for controlling the Timer and for the Interrupt
logic. The flags can be bit addressed:

+++++++++
| TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 | TCON DATA 88h
+++++++++

IT0 BIT 88h ; external INT0 are edge/_level triggered


IE0 BIT 89h ; external INT0 Flag
IT1 BIT 8Ah ; external INT1 are edge/_level triggered
IE1 BIT 8Bh ; external INT1 Flag
TF0 BIT 8Dh ; Timer 0 overflow Flag
TF1 BIT 8Fh ; Timer 1 overflow Flag

TR0 BIT 8Ch ; Timer 0 run


TR1 BIT 8Eh ; Timer 1 run

6.2 8051 Timer Page 61

6.2 8051 Timer:


----------------

The 8051 has two timer/counters: timer 0 and timer 1. Each timer consists
of two 8 bit registers. They can be set to 4 different running modes.

The timer will (when running) be incremented by 1 at every cycle. They can
also be used as a counter, and will be incremented depending on the count
input, by T0 or T1.

The mode is selected with the TMOD register. TMOD is not bit addressable.
The high nybble of TMOD selects the mode for Timer 1 and the low nybble for
Timer 0:

+++++++++
| GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 | TMOD DATA 89h
+++++++++

C/T = 0 --> Timer mode (increment by 1 every cycle)


C/T = 1 --> Counter Mode (increment by 1 for every negative edge at
port pin T0 = P3.4 or T1 = P3.5)

GATE = 0 --> Timer/Counter always running, when TRx = 1 (in TCON)


GATE = 1 --> Timer/Counter runs only when TRx = 1 and _INTx = 1
the interrupt input can act as a gate for the Timer/
Counter.

M1:M0 = 00 --> Mode 0: 13 bit Timer/Counter


The 8 bits from THx and the lowest 5 Bits from TLx serve
as counter.
M1:M0 = 01 --> Mode 1: 16 Bit Timer/Counter

M1:M0 = 10 --> Mode 2: 8 bit Timer/Counter with auto reload


TLx serves as counter. With every overflow the value
from THx will be loaded into TLx.

M1:M0 = 11 --> Mode 3: TL0 acts as an 8 bit timer/counter. TL0 uses


the usual control bits of Timer 0.
TH0 acts as another 8 bit timer/counter.
TH0 uses the control bits from Timer 1(_INT1 as Gate, T1
as counter input, TR1, TF1). Timer 1 is stationary when
it finds itself in mode 3.

When Timer 0 finds itself in Mode 3, TR1, T1 and _INT1 cannot control Timer
1 anymore. When Timer 1 overflows it does not set TF1 anymore and cannot
generate any more interrupts. Timer 1 can be stopped by switching it to Mode
3, otherwise it runs. Although no more control bits are assigned to Timer 1,
it may run when Timer 0 is in Mode 3, and is good for generating baud rate
for the serial port.

6.3 Serial Communications Page 62

6.3 Serial Communications


----------------------------

The 8051 can send and receive either synchronously or asynchronously over
the serial port. In asynchronous mode it can send and receive simultaneously.

The 8051 has separate registers for sending and for receiving. The contents
are separate from each other, but both use the same DATA address (SBUF DATA
99h).

The following diagram shows a simplified version of the function of the


serial port in asynchronous mode.

| ++
S |>| SBUF Tx-Shift +> TxD
o | +++
f | +++
t | SysTime >|| 16 |
w | Timer 1 >|++
a | Timer 2 >|| DPLL 16 ++
r | +++ |
e | ++ +++ |
|<| SBUF Rx ++ Rx-Shift Reg. ++< RxD
| ++ ++

When a character is written to SBUF (transmit), the port starts shifting the
data out into TxD. When all the bits are sent, the logic sets the
TI flag (BIT 99h in SCON). The shift clock comes from an internal 16 bit-
counter.
Received bits are first shifted into the receive Shift Register. When
all bits are received, the character is taken into SBUF (receive) and RI is
set. The shift clock comes from a DPLL, which is synchronised with
the received data.

The following diagram shows a simplified version of the function of the


serial port in synchronous mode.

| ++
S |>| SBUF Tx-Shift ++
o | ++ +++ |
f | SysTimer>| 6 ++ send |
t | ++ o|<> TxD
w | / receive |
a | | |
r | ++ +++ |
e |<| SBUF Rx ++ Rx-Shift Reg. ++<> RxD
| ++ ++

Send and receive shift functions the same way as in asynchronous mode. But
the data is sent and received at RxD. At TxD, the shift clock is sent or
synchronously received.

6.3 Serial Communications Page 63

6.3.1 Asynchronous Mode, Synchronous Mode:


-------------------------------------------

In synchronous mode the shift clock is synchronized with the data


transferred. The receiver uses as such the shift clock from the sender. The
transmission distance is limited, as over longer distances the phase
angle between data and clock can diverge.

In asynchronous mode a clock is not transmitted. The clock must be recovered


from the edges of the received data bits. This is done through a 16 bit
Digital Phase Locked Loop (DPLL). This is a 16 bit counter, which is
synchronised with the edges of the received data:

A negative edge at RxD causes the output of the DPLL to be set to 1.


It remains there for 8 DPLL cycles, then it goes to 0 and so on for 8
DPLL cycles. Every negative edge forces this synchronisation.

Over a Universal Asynchronous Receive Transmit port (UART), data is


transferred only on a character basis as defined in the case of 8051, of a PC
or of a terminal. Every character is led by a start bit (=0) and concluded by
1, 1 or 2 stopbits (=1). The start bit in combination with the stop bit
guarantees the identification of the start of a character upon reception and
the synchronisation of the DPLL.

The LSB (low bit) is always transmitted first. Sender and receiver must
agree in the number of stopbits. The baud rate should also agree, so that
during the transfer of a character the DPLL does not "run away" too far.
Example for transmitting the character 'A' = asc41h in asynchronous mode:

+ ++ ++ +
++ ++ ++
|Start| LSB | | | | | | | MSB |Stop |

6.3.2 8051 serial mode setting:


--------------------------------

The 8051 can run at a maximum of 1 MBit/s in synchronous mode. The maximum is
375 kBit/s in asynchronous mode.

The serial port can operate in 4 different modes. The mode is set in SCON
(Serial Control Register). SCON is bit addressable.

+++++++++
| SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI | SCON DATA 98h
+++++++++

6.3 serial port Page 64

SM0 (BIT 9Fh) and SM1 (BIT 9Eh) acts as mode setting.
SM2 (BIT 9Dh) enables special reception requirement.
REN (BIT 9Ch) is the Receiver Enable Flag.
TB8 (BIT 9Bh) is also the 9th bit sent.
In RB8 (BIT 9Ah) the 9th Bit is received.
TI (BIT 99h) is the Transmit Interrupt Flag.
RI (BIT 98h) is the Receive Interrupt Flag.

For the meaning and applications of these flags, see below.

Mode 0: Synchronous Mode with 1/12 Oscillator frequency (max. 1 MBit/s):


-------------------------------------------------------------------------
SM0:SM1 = 00

8 data bits (LSB first) are sent and received over RxD. The shift clock is
is sent or received over TxD. It is not possible to receive and send
simultaneously.

The shift clock is derived by sending in association with the system clock.
The shift clock corresponds to the cycle frequency (= 1 MHz at 12 MHz
oscillator). When SBUF (transmit) is once again empty, TI will be set.

To accept characters the receiver must be enabled. For this the software has
to set REN = 1 and RI = 0. The character will be received into an internal
shift register. Only when this is full, will the character be moved to SBUF
and RI set.
In Mode 0, SM2 = 0 must be chosen, TB8 and RB8 have no meaning.

Particulars of Mode 0:
----------------------

The shift clock TxD is low during State 3, 4 and 5 of the system clock
(see chapter 3.2 and 3.3). With the positive edge in the shift clock, the
value changes at RxD and the next bit is shifted out.

After a new character to be sent is written to SBUF, a full cycle passes first
before the shifting starts. After the last bit (MSB) of the character has
been shifted out, another 1 will be shifted behind it (so that RxD remains
undisturbed at 1), only then will TI be set. 10 cycles will pass after the
write SBUF event by the software.

During reception, the positive edge at TxD shifts the data into the receive
shift register. For this time period SBUF can still hold the previous data.
When all the bits are received, then will the hardware overwrite it with the
new character. After which RI = 0 is set. For REN = 0 (receiver not enabled)
or RI = 1 (SBUF still full), incoming data will not be received and will be
lost.

6.3 Serial Communications Page 65

Mode 1: Asynchronous mode with variable baud rate as 8 Bit UART:


------------------------------------------------------------------
SM0:SM1 = 01

A clock will not be sent, only the data. What is sent over TxD is 1 start
bit, then 8 data bits (LSB first) and 1 stop bit. When SBUF (transmit) is
empty again, TI will be set.

Receiving takes place over RxD. The clock will be recovered in the receiver
from the edges of the data. To receive characters we must have REN = 1
and RI = 0 (Receive enable). In addition, if SM2 = 1, the received stop bit
must in addition = 1 making it valid. That character is received in an
internal shift register. Only when this is full, will the value in SBUF be
transferred and RI set. The stop bit is registered in RB8.

Particulars of Mode 1:
----------------------
Sending starts with the first overflow of the clock generator after a
character has been written to SBUF. First, a start bit of 0 is sent, then the
next 8 bits of the character (LSB first). Finally a 1 is sent as a stop bit.
Then will TI = 1.

The reception starts with the first negative edge at RxD. The start bit
is watched out for in states 7, 8 and 9 of the shift clock count. It must
always be 0 (for data integrity, to mask out disturbances). If this is not
the case, or REN not = 1, the reception will be cancelled and the logic goes
back to the initial state (wait for negative edge).
After recognizing the start bit and REN = 1, the incoming bits will be moved
into the receive shift register. At this point in time old data can still
remain in SBUF, RI need not be 1 yet. The reception is completed upon
receiving the stop bit. Only when the following conditions are met, will
the character be placed into SBUF, RI = 1 be set and the stop bit written
into RB8.

RI = 0 and SM2 = 0
or RI = 0 and SM2 = 1 and Stopbit = 1.

Mode 1 shift clock:


-------------------
The shift clock used in sending is derived from a 16 digit counter, triggered
from the Timer1 overflow. The shift clock for receiving is also derived from
a DPLL, which is also triggered from the Timer1 overflow. If the SMOD bit in
PCON is cleared (SMOD = 0), the Timer1 output will in the first place have
been further divided by 2. The shift clock is given by the following formula:

Osci 1 SMOD + 1 1 Osci * (SMOD + 1)


BaudRate = * * * =
12 100h - TH1 2 16 384 * (100h - TH1)

| | | + 16 bit-counter / DPLL
| | + divide by 2
| + count value of Timer 1
+ Trigger for timer per cycle

6.3 Serial port Page 66

Alternatively, the 8052 can select the Timer2 overflow for triggering the
shift clock counter and/or the DPLL. If Timer2 is to be used for sending,
the bit TCLK in T2CON is set (see 8052 Timer). If Timer2 is to be used for
receiving, bit RCLK in T2CON is set. In this way sender and receiver can run
with different baud rates (one with Timer1 and the other with Timer2), but
they can also be the same: both from Timer1 or both from Timer2.

Mode 2: Asynchronous mode with fixed baud rate for 9 Bit UART:
---------------------------------------------------------------
SM0:SM1 = 10

No clock will be sent, only data. What is sent over TxD is 1 start bit, then
8 data bits (LSB first) the bit from TB8 and 1 stop bit. When SBUF (transmit)
is empty again, TI will be set.

Receiving takes place over RxD. The clock will be recovered in the receiver
from the edges of the data. To receive characters we must have REN = 1
and RI = 0 (Receive enable). If SM2 = 1, so additionally must the received 9th
bit = 1. That character is received in an internal shift register only. Only
when this is full will the value in SBUF be transferred and RI is set. The
stop bit will be put into RB8.
Details of Mode 2:
------------------
Sending begins with the first overflow of the clock generator after a
character has been written to SBUF. First a startbit of 0 is sent, then the
next 8 bits of the character (LSB first). After that the bit from TB8 is sent
and finally a 1 as stop bit. Then will TI = 1.

The reception starts with the first negative edge at RxD. The start bit
will be watched out for in states 7, 8 and 9 of the shift clock count. It
must always be 0 (for data security, to mask out disturbances). If this is
not the case, or REN not = 1, the reception will be cancelled and the logic
goes back to the initial state (wait for negative edge).

After recognizing the start bit and REN = 1, the incoming bits will be
shifted into the receive shift register. At this time, old data can remain in
SBUF-RI need not be 1 yet. The reception is completed upon receiving the stop
bit. Only when the following existing conditions are met, will the character
be placed into SBUF, RI = 1 be set and the stop bit written into RB8.

RI = 0 and SM2 = 0
or RI = 0 and SM2 = 1 and 9th Bit = 1.

6.3 Serial port Page 67

Mode 2 baud rate:


-----------------
The baud rate for sending/receiving is derived from a 16 digit counter/DPLL,
triggered by the system clock (= oscillator clock, max 6 MHz at 12 MHz
crystal). When the bit SMOD in PCON is cleared (SMOD=0), Timer1 will
additionally be divided by 2.
The baud rate is given by the following formula:

Osci SMOD + 1 1 Osci * (SMOD + 1)


BaudRate = * * =
2 2 16 64

| | + 16 bit counter / DPLL


| + divide by 2
+ System clock

Mode 3: Asynchronous mode with variable baud rate as 9 Bit UART:


-----------------------------------------------------------------
SM0:SM1 = 11

Transmission takes place as in mode 2, but the baud rate is derived as in


Mode 1.
In Modes 2 and 3 a field bus system can be built with the help of RB8, TB8 and
SM2. Several 8051 CPUs can be driven through a bus line. A suitable protocol
(e.g. master-slave) is necessary. A node, which has set SM2 = 0, receives all
characters sent over the bus . A node, with SM2 set = 1, receives only such
characters which are sent with TB8 = 1. So two nodes can communicate
together, without disturbing the others.

6.3.3 Interrupt Mode or Polled Mode:


-------------------------------------

When sending over the serial port, the next character can only be written into
SBUF after the old character is gone. As soon as SBUF (transmit) is empty, the
hardware sets the TI flag. The user can write the next character into SBUF
only when TI = 1.

As soon as a character is received over the serial port, the hardware sets
the RI flag. Only when RI = 1, is a valid character present in SBUF (receive).

The hardware sets only RI and TI, but does not clear them. However after a
reset, RI, TI as well as REN (SCON = 0) are cleared.

6.3 Serial Communications Page 68

Polled Mode:
------------

For correct functioning of the serial port, the software must observe the
following :

- only write to SBUF when TI is 1.


- after writing to SBUF then clear TI.
- before reading from SBUF, check RI.
- after reading from SBUF, clear RI.

Proceeding in this way, the following problem occurs: After a reset TI is 0


although SBUF (transmit) is empty. The hardware never sets it, since there is
no sending, and the end of transmission status never appears. The first
character to be sent may as such be written to SBUF, although TI is 0. It is
advisable to set TI to 1 soon after a reset.

Example for serial transmission in Polled Mode:


-----------------------------------------------

iniSCON:
CLR ES ; serial interrupt cleared
CLR ET1 ; Timer 1 interrupt cleared
MOV TH1, #-3 ; preload value for Timer 1 = -3
MOV TL1, TH1
SETB TR1 ; start Timer 1
ANL PCON, #7Fh ; SMOD = 0
MOV SCON, #52h ; Mode 1, SM2=0,TB8=0,RB8=0, TI=1, REN=1,RI=0
RET
sendeChar:
JNB TI, sendeChar ; wait until SBUF (transmit) is empty
MOV SBUF, A
CLR TI
RET

receiveChar:
JNB RI, receiveChar
MOV A, SBUF
CLR RI
RET

after a reset the serial port is initialised for 8 bit UART at 9600 baud
(with 11,059 MHz crystal) as above. The receiver is enabled and TI=1 is set.

Sending will wait until SBUF is empty. Then the character which is called up
by the subprogram is written into SBUF from the accumulator. TI must be
cleared by the software.

In the course of receiving, a wait also happens, until a character is


received. It is OK for the CPU not to be doing anything. Since the program
remains here in a loop, when no characters are received.

6.3 Serial Communications Page 69

Interrupt Mode:
---------------

With larger, more comprehensive programs, if the CPU must be processing other
routines, often the serial receiver can only be polled at certain particular
times. If polling is not done often enough, data can be lost. Sometimes it is
also not permitted to wait until a character can be sent. The solution is to
have the serial port running in interrupt mode.

With a set RI or TI flag, the hardware will generate an interrupt. For that,
the interrupt must be enabled (bit ES = 1). By jumping into the interrupt
routine (at CODE 0023h) RI and TI will not be cleared by the hardware. They
are to be cleared inside the interrupt routine by the software, otherwise
after the RETI the interrupt routine will again be activated.

Under normal conditions the send buffer is empty. When working with interrupts
TI cannot remain unchanged. As for code for send buffer empty, an extra flag
must be defined.

Example for serial transmission in interrupt mode:


----------------------------------------------------

TxEmpty BIT 0 ; as an example, the serial port


; is driven in asynchronous mode (Mode 2).
iniSCON: ; The reception takes place thru the interrupt.
SETB TxEmpty ; Send in polled mode. (TxEmpty flag)
ORL PCON, #80h ; SMOD = 1, so that 375 kBit/s at 12 MHz crystal
MOV SCON, #98h ; SM2=0, REN=1 and RI=0 enables receive
SETB ES ; TI is cleared, in its stead the flag
SETB EA ; TxEmpty is set.
RET ; The interrupt routine reads the character
; from SBUF and stores it in a ring buffer,
CSEG AT 0023h ; from where a main program retrieves it.
JNB RI, chkTxInt ; This digit might cause a jump to a
PUSH PSW ; command dispatch or similar routine.
PUSH ACC ; An example for a character
MOV A, R0 ; insert routine (Ringbuffer) is found
PUSH ACC ; in section 5.4.
MOV A, SBUF ; In any case, the interrupt routine must
CLR RI ; save the used registers and the flags
CALL putCharToBuf ; (here ACC, R0 and PSW).
POP ACC ; If TI is set, TxEmpty is set. TI will as
MOV R0, A ; such be cleared. The send routine polls
POP ACC ; TxEmpty instead of TI.
POP PSW ; Caution: Care is requested, when the send
chkTxInt: ; routine is part of an interrupt routine.
JNB TI, sintRet ; Then both TI and TxEmpty are to be polled,
SETB TxEmpty ; since no interrupt comes through and so
CLR TI ; TxEmpty will not be set.
sintRet:
RETI

6.3 Serial Communications Page 70

6.3.4 Baud Rate Table:


-----------------------

This table contains the control values used to obtain a specific baud rate.
For the equation see section 6.3.2

CrystalSM0:SM1 SMOD TH1 BaudRate

------------------------------------- With a 12 MHz crystal most of


12 MHz 00 X X 1 MBit/s the standard baud rates cannot
12 MHz 10 1 X 375 kBit/s be set exactly.
12 MHz 10 0 X 187.5 kBit/s
12 MHz 01 1 -1 62 500 Bit/s
12 MHz 01 1 -3 20 800 Bit/s Since the DPLL holds the phase
12 MHz 01 1 -7 8 929 Bit/s over 10 bit cells at the most,
12 MHz 01 1 -14 4 808 Bit/s it is enough that the baud rates
12 MHz 01 1 -26 2 404 Bit/s are accurate up to 4800 baud.
12 MHz 01 1 -52 1 202 Bit/s
12 MHz 01 1 -104 601 Bit/s
12 MHz 01 1 -208 300 Bit/s
12 MHz 01 0 -208 150 Bit/s BR in Mode 01 and 11 are the same

Crystal SM0:SM1 SMOD TH1 BaudRate


----------------------------------------- With a special crystal, baud
11.0592 MHz 01 1 -1 57 600 Bit/s rates up to 19200 baud
11.0592 MHz 01 1 -3 19 200 Bit/s can be set exactly.
11.0592 MHz 01 1 -6 9 600 Bit/s But now the CPU does not
11.0592 MHz 01 1 -12 4 800 Bit/s work at the maximal frequency
11.0592 MHz 01 1 -24 2 400 Bit/s and the time base which otherwise
11.0592 MHz 01 1 -48 1 200 Bit/s was 1 s for a cycle is lost.
11.0592 MHz 01 1 -96 600 Bit/s
11.0592 MHz 01 1 -192 300 Bit/s
11.0592 MHz 01 0 -192 150 Bit/s
Baud rates lower than 150 bit/s (with these crystals) are not obtainable. It
is possible to feed T1 with a clock and operate Timer 1 as a counter. With it
the following baud rate is given:

Count * (SMOD + 1)
BaudRate =
32 * (100h - TH1)

In order to obtain lower baud rates a further possibility exists with Timer 1
operating as a 16 bit timer. In addition, a Timer 1 interrupt routine is
installed, which writes a 16 bit reload value into TH1:TL1.

The 8052 permits more exact baud rates to be set with Timer 2 (see chapter
7.1).

7.1 The 8052 Page 71

7. Further controllers of the 8051 family:


------------------------------------------

7.1 The 8052:


-------------

Contrary to the 8051, the 8052 possesses a larger internal RAM, a larger
internal ROM and an additional timer: otherwise it is identical with the 8051.

internal RAM 8051: 128 Byte 00....7Fh


internal RAM 8052: 256 Byte 00...0FFh

internal ROM 8051: 4 kByte 0000...0FFFh ; 8031 and 8032 do not


internal ROM 8052: 8 kByte 0000...1FFFh ; have internal ROM
; 8751 and 8752 possess
; an internal EPROM

internal RAM:
-------------

In a stack overflow (SP over 0FFh), the SP will be further incremented.


This is shown at the internal RAM addresses from 00. In this way the stack
overwrites the register area. Thus, care should be taken that no stack
overflow occurs.

The internal RAM addresses 80h...FFh cannot be directly addressed. This


region can only be accessed indirectly (MOV @Ri, ..).

(compare also chapter 3.9)


7.1.2 additional SFR of the 8052:
----------------------------------

In the case of the 8052, several additional SFRs exist for control of Timer2:

T2CON DATA 0C8h


RCAP2L DATA 0CAh
RCAP2H DATA 0CBh
TL2 DATA 0CCh
TH2 DATA 0CDh

7.1.3 Timer 2:
---------------

Timer2 is a 16 bit counter. Its counter register is made up of TH2:TL2


(Timer2 High and Timer2 Low byte). T2CON (Timer2 Control) serves to control
the timers/counters.

7.1 The 8052 Page 72

An interrupt can be generated by a counter overflow. The jump address is at


002Bh. In addition the following bits in the interrupt enable and interrupt
priority register are defined:

ET2 BIT 0ADh


PT2 BIT 0BDh
Timer2 CODE 002Bh

Timer2 runs as a 16 bit counter/timer selectively with reload or capture


functions. Besides, Timer2 has a capture/reload register (RCAP2H:RCAP2L) in
addition to a 16 bit count register (TH2:TL2).

In the reload mode, an overflow or external trigger to Port1 input pin T2EX
will cause the value from RCAP2 to be loaded into the count register.

In capture mode an external trigger will cause the value in the count register
to be loaded into RCAP2.

When Timer2 operates as a timer, TH2:TL2 will be incremented by 1 every CPU


cycle (except as a baud rate generator: see RCLK, TCLK). When operating as
a counter it will increment on every negative edge signal at Port1 input pin T2.

T2EX BIT 091h ; = P1.1


T2 BIT 090h ; = P1.0

+++++++++
| TF2 | EXF2 | RCLK | TCLK | EXEN2 | TR2 | C_T2 | CP_RL2 | T2CON DATA 0C8h
+++++++++

CP_RL2 BIT 0C8h --> With CP_RL2 = 1 the capture mode is selected,
otherwise the reload mode. Reload mode will also be selected when Timer2 is
used as a baud rate generator for the serial port. (see also EXEN2, RCLK and
TCLK).

C_T2 BIT 0C9h --> With C_T2 = 1 Timer2 will operate as a counter, or else
as a timer.

TR2 BIT 0CAh --> Timer2 Run Flag

EXEN2 BIT 0CBh --> The external trigger input pin T2EX is only active with
EXEN2 = 1. Only then, and with a negative edge at T2EX, will a transfer take
place in RCAP2 (in Capture Mode) or a Reload (in Reload Mode).

TCLK BIT 0CCh --> When TCLK is set, the Timer2 overflow acts as a trigger for
the baud rate generator for the serial port when sending.

7.1 The 8052 Page 73

RCLK BIT 0CDh --> When RCLK is set, the Timer2 overflow acts as a trigger
for the baud rate generator (DPLL) for the serial port when receiving.

EXF2 BIT 0CEh --> External trigger interrupt flag. EXF2 will be set by
the hardware, after an overflow has occurred due to there being a negative
edge at T2EX (only when EXEN2 = 1). EXF2 must be cleared by software.

TF2 BIT 0CFh --> Timer2 overflow interrupt flag. TF2 will be set by the
hardware after an overflow from 0FFFFh to 0000 in TH2:TL2 occurs. TF2 must be
cleared by software.

Timer2 Interrupt:
-----------------

Through Timer2 an interrupt is processed, when TF2 or EXF2 are set. It is


enough that either one is set. The CPU saves the return address to the
stack and jumps to CODE address 002Bh. While jumping into the interrupt routine
TF2 and EXF2 are preserved, for only so can the interrupt routine detect what
causes the interrupt:

TF2 --> Timer2 overflow


or EXT2 --> external trigger and transfer

TF2 and EXF2 must be cleared by software (in the interrupt routine). Otherwise
after a RETI a renewed jump into the interrupt routine takes place .

TF2 and/or EXF2 may be cleared or set with software. If one of the two, EXF2
or TF2 is not used, it can be misused to produce a software interrupt.

7.1.4 Serial port with Timer2:


-----------------------------------------
If either TCLK and RCLK is set, Timer2 will act as a trigger for at least
one of the baud rate generators (send, receive or both) of the serial port.
Timer2 runs in the reload mode (independent of CP_RL2). In this mode, Timer2
will not be incremented every CPU cycle, rather once every system clock
(crystal frequency / 2). In this way it runs faster.

The prerequisite for the generation of the serial baud rates with Timer 2
is that the serial port must be running in mode 1 (SM0:SM1 = 01) or Mode 3
(SM0:SM1 = 11). By default the Timer1 overflow is used to trigger the
baud rate generators. When TCLK or/and RCLK is set, the Timer2 overflow will
be used for sending or receiving.

TCLK = 0 RCLK = 0 --> Timer1 for sending and receiving


TCLK = 0 RCLK = 1 --> Timer1 for sending and Timer2 for receiving
TCLK = 1 RCLK = 0 --> Timer2 for sending and Timer1 for receiving
TCLK = 1 RCLK = 1 --> Timer2 for sending and receiving.

7.1 The 8052 Page 74

When using Timer2 the following gives the baud rate :

Osci 1 1
BaudRate = * * ; RCAP2 = RCAP2H:RCAP2L
2 10000h - RCAP2 16

| | + 16 bit counter / DPLL


| + numeric value of Timer 2
+ trigger for timer every system clock

Baud rate table:


----------------

This table contains the control values for obtaining a given baud rate.
Compare also chapter 6.3.4. Here SM0:SM1 = 01 or 11.

Crustal: RCAP2 BaudRate


------------------------------
12 MHz -1 375 kBit/s With a 12 MHz crystal not all standard
12 MHz -2 187,5 kBit/s baud rates can here be set exactly
12 MHz -3 125 kBit/s either
12 MHz -4 93750 Bit/s
12 MHz -5 75000 Bit/s
12 MHz -6 62500 Bit/s 11,0592 MHz -3 115200 Bit/s
12 MHz -7 53571 Bit/s 11,0592 MHz -6 57600 Bit/s
12 MHz -9 41667 Bit/s
12 MHz -10 37500 Bit/s 11,0592 MHz -9 38400 Bit/s
12 MHz -20 18750 Bit/s 11,0592 MHz -18 19200 Bit/s
12 MHz -39 9615 Bit/s 11,0592 MHz -36 9600 Bit/s
12 MHz -78 4808 Bit/s 11,0592 MHz -72 4800 Bit/s
12 MHz -156 2404 Bit/s 11,0592 MHz -144 2400 Bit/s
12 MHz -312 1202 Bit/s 11,0592 MHz -288 1200 Bit/s
12 MHz -625 600 Bit/s
12 MHz -1250 300 Bit/s
12 MHz -2500 150 Bit/s
12 MHz -3409 110 Bit/s
12 MHz -5000 75 Bit/s

Adjustable by PC:

115200, 57600, 38400, 28800, 23040, 19200, 16457,

A negative number can be used in an assembler. But it can also be added up:
with -1 = 0FFFFh, -2 = 0FFFEh ....

Example for 1200 baud with Timer2:

CLR ES ; clear serial interrupt


CLR ET2 ; clear Timer 2 interrupt
MOV RCAP2H, #HIGH(-312) ; preload value for Timer 2
MOV RCAP2L, #LOW(-312)
MOV TH2, RCAP2H
MOV TL2, RCAP2L
MOV T2CON, #00110100b ; RCLK, TCLK, TR2
MOV SCON, #52h ; Mode 1, SM2=0,TB8=0,RB8=0, TI=1, REN=1,RI=0

A.1 ASCII Table: Page 75

A.1 ASCII Table:


-----------------

The following page shows the assignment of characters to numeric values


(ASCII table):

The values less than 20h (blank characters) in general are not printable, and
also many editors and text processing systems do not display them. There and
in data transmission they often act as control characters.
The important ones are:

BEL = Ring character (bell)


BS = backward delete (Back Space)
HT = horizontal TAB
VT = vertical Tab
CR = at the beginning of lines (Carriage Return)
LF = Line advance (Line Feed)
FF = new page (Form Feed)

Although a graphic character is also assigned to the characters under 20h, in


this table however, the character is not represented, rather the meaning for
data transmission is indicated (since there is problem anyway of viewing the
representation on many editors).

A.1 ASCII table Page 76

NUL 0 00 BEL 7 07 SO 14 0E NAK 21 15 FS 28 1C


SOH 1 01 BS 8 08 SI 15 0F SYN 22 16 GS 29 1D
STX 2 02 HT 9 09 DLE 16 10 ETB 23 17 RS 30 1E
ETX 3 03 LF 10 0A DC1 17 11 CAN 24 18 US 31 1F
EOT 4 04 VT 11 0B DC2 18 12 EM 25 19
ENQ 5 05 FF 12 0C DC3 19 13 SUB 26 1A
ACK 6 06 CR 13 0D DC4 20 14 ESC 27 1B

32 20 0 48 30 @ 64 40 P 80 50 ` 96 60
! 33 21 1 49 31 A 65 41 Q 81 51 a 97 61
" 34 22 2 50 32 B 66 42 R 82 52 b 98 62
# 35 23 3 51 33 C 67 43 S 83 53 c 99 63
$ 36 24 4 52 34 D 68 44 T 84 54 d 100 64
% 37 25 5 53 35 E 69 45 U 85 55 e 101 65
& 38 26 6 54 36 F 70 46 V 86 56 f 102 66
' 39 27 7 55 37 G 71 47 W 87 57 g 103 67
( 40 28 8 56 38 H 72 48 X 88 58 h 104 68
) 41 29 9 57 39 I 73 49 Y 89 59 i 105 69
* 42 2A : 58 3A J 74 4A Z 90 5A j 106 6A
+ 43 2B ; 59 3B K 75 4B [ 91 5B k 107 6B
, 44 2C < 60 3C L 76 4C \ 92 5C l 108 6C
- 45 2D = 61 3D M 77 4D ] 93 5D m 109 6D
. 46 2E > 62 3E N 78 4E ^ 94 5E n 110 6E
/ 47 2F ? 63 3F O 79 4F _ 95 5F o 111 6F

p 112 70 128 80 144 90 160 A0 # 176 B0


q 113 71 129 81 145 91 161 A1 # 177 B1
r 114 72 130 82 146 92 162 A2 # 178 B2
s 115 73 131 83 147 93 163 A3 | 179 B3
t 116 74 132 84 148 94 164 A4 + 180 B4
u 117 75 133 85 149 95 165 A5 + 181 B5
v 118 76 134 86 150 96 166 A6 + 182 B6
w 119 77 135 87 151 97 167 A7 + 183 B7
x 120 78 136 88 152 98 168 A8 + 184 B8
y 121 79 137 89 153 99 169 A9 + 185 B9
z 122 7A 138 8A 154 9A 170 AA | 186 BA
{ 123 7B 139 8B 155 9B 171 AB + 187 BB
| 124 7C 140 8C 156 9C 172 AC + 188 BC
} 125 7D 141 8D 157 9D 173 AD + 189 BD
~ 126 7E 142 8E 158 9E 174 AE + 190 BE
127 7F 143 8F 159 9F 175 AF + 191 BF

+ 192 C0 + 208 D0 224 E0 240 F0


+ 193 C1 + 209 D1 225 E1 241 F1 ASCII Table
+ 194 C2 + 210 D2 226 E2 242 F2 -----------
+ 199 C7 + 215 D7 231 E7 247 F7
+ 200 C8 + 216 D8 232 E8 248 F8
+ 201 C9 + 217 D9 233 E9 + 249 F9
+ 202 CA + 218 DA 234 EA 250 FA
+ 203 CB | 219 DB 235 EB 251 FB
+ 204 CC = 220 DC 236 EC 252 FC
= 205 CD | 221 DD 237 ED 253 FD
+ 206 CE | 222 DE 238 EE 254 FE
+ 207 CF = 223 DF 239 EF 255 FF

A.2 Instruction set Page 77

A.2 Instruction set in hexadecimal row order:


----------------------------------------------

Code Bytes Cycles Mnemonic

00 1 1 NOP 30 3 2 JNB bitAdr, codeAdr


01 2 2 AJMP codeaddr 31 2 2 ACALL codeAdr
02 3 2 LJMP codeaddr 32 1 2 RETI
03 1 1 RR A 33 1 1 RLC A
04 1 1 INC A 34 2 1 ADDC A, #wert
05 2 1 INC dataAddr 35 2 1 ADDC A, dataAdr
06 1 1 INC @R0 36 1 1 ADDC A, @R0
07 1 1 INC @R1 37 1 1 ADDC A, @R1
08 1 1 INC R0 38 1 1 ADDC A, R0
09 1 1 INC R1 39 1 1 ADDC A, R1
0A 1 1 INC R2 3A 1 1 ADDC A, R2
0B 1 1 INC R3 3B 1 1 ADDC A, R3
0C 1 1 INC R4 3C 1 1 ADDC A, R4
0D 1 1 INC R5 3D 1 1 ADDC A, R5
0E 1 1 INC R6 3E 1 1 ADDC A, R6
0F 1 1 INC R7 3F 1 1 ADDC A, R7

10 3 2 JBC bitAdr, codeAddr 40 2 2 JC codeAdr


11 2 2 ACALL codeAddr 41 2 2 AJMP codeAdr
12 3 2 LCALL codeAddr 42 2 1 ORL dataAdr, A
13 1 1 RRC A 43 3 2 ORL dataAdr, #value
14 1 1 DEC A 44 2 1 ORL A, #wert
15 2 1 DEC dataAddr 45 2 1 ORL A, dataAdr
16 1 1 DEC @R0 46 1 1 ORL A, @R0
17 1 1 DEC @R1 47 1 1 ORL A, @R1
18 1 1 DEC R0 48 1 1 ORL A, R0
19 1 1 DEC R1 49 1 1 ORL A, R1
1A 1 1 DEC R2 4A 1 1 ORL A, R2
1B 1 1 DEC R3 4B 1 1 ORL A, R3
1C 1 1 DEC R4 4C 1 1 ORL A, R4
1D 1 1 DEC R5 4D 1 1 ORL A, R5
1E 1 1 DEC R6 4E 1 1 ORL A, R6
1F 1 1 DEC R7 4F 1 1 ORL A, R7

20 3 2 JB bitAdr, codeAddr 50 2 2 JNC codeAdr


21 2 2 AJMP codeAddr 51 2 2 ACALL codeAdr
22 1 2 RET 52 2 1 ANL dataAdr, A
23 1 1 RL A 53 3 2 ANL dataAdr, #value
24 2 1 ADD A, #value 54 2 1 ANL A, #value
25 2 1 ADD A, dataAddr 55 2 1 ANL A, dataAdr
26 1 1 ADD A, @R0 56 1 1 ANL A, @R0
27 1 1 ADD A, @R1 57 1 1 ANL A, @R1
28 1 1 ADD A, R0 58 1 1 ANL A, R0
29 1 1 ADD A, R1 59 1 1 ANL A, R1
2A 1 1 ADD A, R2 5A 1 1 ANL A, R2
2B 1 1 ADD A, R3 5B 1 1 ANL A, R3
2C 1 1 ADD A, R4 5C 1 1 ANL A, R4
2D 1 1 ADD A, R5 5D 1 1 ANL A, R5
2E 1 1 ADD A, R6 5E 1 1 ANL A, R6
2F 1 1 ADD A, R7 5F 1 1 ANL A, R7

A.2 Instruction set Page 78

Code Bytes Cycles Mnemonic

60 2 2 JZ codeAddr 90 3 2 MOV DPTR, #value16


61 2 2 AJMP codeAddr 91 2 2 ACALL codeAdr
62 2 1 XRL dataAdr, A 92 2 2 MOV bitAdr, C
63 3 2 XRL dataAdr, #value 93 1 2 MOVC A, @A+DPTR
64 2 1 XRL A, #value 94 2 1 SUBB A, #value
65 2 1 XRL A, dataAddr 95 2 1 SUBB A, dataAddr
66 1 1 XRL A, @R0 96 1 1 SUBB A, @R0
67 1 1 XRL A, @R1 97 1 1 SUBB A, @R1
68 1 1 XRL A, R0 98 1 1 SUBB A, R0
69 1 1 XRL A, R1 99 1 1 SUBB A, R1
6A 1 1 XRL A, R2 9A 1 1 SUBB A, R2
6B 1 1 XRL A, R3 9B 1 1 SUBB A, R3
6C 1 1 XRL A, R4 9C 1 1 SUBB A, R4
6D 1 1 XRL A, R5 9D 1 1 SUBB A, R5
6E 1 1 XRL A, R6 9E 1 1 SUBB A, R6
6F 1 1 XRL A, R7 9F 1 1 SUBB A, R7

70 2 2 JNZ codeAddr A0 2 2 ORL C, /bitAddr


71 2 2 ACALL codeAddr A1 2 2 AJMP codeAddr
72 2 2 ORL C, bitAddr A2 2 1 MOV C, bitAddr
73 1 2 JMP @A+DPTR A3 1 2 INC DPTR
74 2 1 MOV A, #value A4 1 4 MUL AB
75 3 2 MOV dataAddr, #value A5 - - reserved
76 2 1 MOV @R0, #value A6 2 2 MOV @R0, dataAddr
77 2 1 MOV @R1, #value A7 2 2 MOV @R1, dataAddr
78 2 1 MOV R0, #value A8 2 2 MOV R0, dataAddr
79 2 1 MOV R1, #value A9 2 2 MOV R1, dataAddr
7A 2 1 MOV R2, #value AA 2 2 MOV R2, dataAddr
7B 2 1 MOV R3, #value AB 2 2 MOV R3, dataAddr
7C 2 1 MOV R4, #value AC 2 2 MOV R4, dataAddr
7D 2 1 MOV R5, #value AD 2 2 MOV R5, dataAddr
7E 2 1 MOV R6, #value AE 2 2 MOV R6, dataAddr
7F 2 1 MOV R7, #value AF 2 2 MOV R7, dataAddr

80 2 2 SJMP codeAddr B0 2 2 ANL C, /bitAddr


81 2 2 AJMP codeAddr B1 2 2 ACALL codeAddr
82 2 2 ANL C, bitAddr B2 2 1 CPL bitAddr
83 1 2 MOVC A, @A+PC B3 1 1 CPL C
84 1 4 DIV AB B4 3 2 CJNE A, #value, codeAddr
85 3 2 MOV dataAddr, dataAddr B5 3 2 CJNE A, dataAddr, codeAddr
86 2 2 MOV dataAddr, @R0 B6 3 2 CJNE @R0, #value, codeAddr
87 2 2 MOV dataAddr, @R1 B7 3 2 CJNE @R1, #value, codeAddr
88 2 2 MOV dataAddr, R0 B8 3 2 CJNE R0, #value, codeAddr
89 2 2 MOV dataAddr, R1 B9 3 2 CJNE R1, #value, codeAddr
8A 2 2 MOV dataAddr, R2 BA 3 2 CJNE R2, #value, codeAddr
8B 2 2 MOV dataAddr, R3 BB 3 2 CJNE R3, #value, codeAddr
8C 2 2 MOV dataAddr, R4 BC 3 2 CJNE R4, #value, codeAddr
8D 2 2 MOV dataAddr, R5 BD 3 2 CJNE R5, #value, codeAddr
8E 2 2 MOV dataAddr, R6 BE 3 2 CJNE R6, #value, codeAddr
8F 2 2 MOV dataAddr, R7 BF 3 2 CJNE R7, #value, codeAddr

A.2 Instruction set Page 79

Code Bytes Cycles Mnemonic


C0 2 2 PUSH dataAddr E0 1 2 MOVX A, @DPTR
C1 2 2 AJMP codeAddr E1 2 2 AJMP codeAddr
C2 2 1 CLR bit Addr E2 1 2 MOVX A, @R0
C3 1 1 CLR C E3 1 2 MOVX A, @R1
C4 1 1 SWAP A E4 1 1 CLR A
C5 2 1 XCH A, data Addr E5 2 1 MOV A, data Addr
C6 1 1 XCH A, @R0 E6 1 1 MOV A, @R0
C7 1 1 XCH A, @R1 E7 1 1 MOV A, @R1
C8 1 1 XCH A, R0 E8 1 1 MOV A, R0
C9 1 1 XCH A, R1 E9 1 1 MOV A, R1
CA 1 1 XCH A, R2 EA 1 1 MOV A, R2
CB 1 1 XCH A, R3 EB 1 1 MOV A, R3
CC 1 1 XCH A, R4 EC 1 1 MOV A, R4
CD 1 1 XCH A, R5 ED 1 1 MOV A, R5
CE 1 1 XCH A, R6 EE 1 1 MOV A, R6
CF 1 1 XCH A, R7 EF 1 1 MOV A, R7

D0 2 2 POP dataAddr F0 1 2 MOVX @DPTR, A


D1 2 2 ACALL codeAddr F1 2 2 ACALL codeAddr
D2 2 1 SETB bitAddr F2 1 2 MOVX @R0, A
D3 1 1 SETB C F3 1 2 MOVX @R1, A
D4 1 1 DA A F4 1 1 CPL A
D5 2 2 DJNZ dataAddr, codeAddr F5 2 1 MOV dataAddr, A
D6 1 1 XCHD A, @R0 F6 1 1 MOV @R0, A
D7 1 1 XCHD A, @R1 F7 1 1 MOV @R1, A
D8 2 2 DJNZ R0, code Addr F8 1 1 MOV R0, A
D9 2 2 DJNZ R1, codeAddr F9 1 1 MOV R1, A
DA 2 2 DJNZ R2, codeAddr FA 1 1 MOV R2, A
DB 2 2 DJNZ R3, codeAddr FB 1 1 MOV R3, A
DC 2 2 DJNZ R4, codeAddr FC 1 1 MOV R4, A
DD 2 2 DJNZ R5, codeAddr FD 1 1 MOV R5, A
DE 2 2 DJNZ R6, codeAddr FE 1 1 MOV R6, A
DF 2 2 DJNZ R7, codeAddr FF 1 1 MOV R7, A

You might also like