You are on page 1of 85

MICROCONTROLLERS

Parameshwara.s

UNIT 1
MICRPROCESSOR AND MICROCONTROLLER
Introduction
Microprocessor: A Microprocessor is a general-purpose digital computer Central
Processing Unit. Although popularly known as a Computer On Chip. Below block
diagram shows the Microprocessor CPU.

Fig.1 Three Basic Elements of a Microprocessor


A microprocessor has three basic elements, as shown above. The ALU performs all
arithmetic computations, such as addition, subtraction and logic operations (AND, OR,
etc). It is controlled by the Control Unit and receives its data from the Register Array.
The Register Array is a set of registers used for storing data. These registers can be
accessed by the ALU very quickly. Some registers have specific functions - we will deal
with these later.
The Control Unit controls the entire process. It provides the timing and control
signals for getting data into and out of the registers and the ALU and it synchronizes the
execution of instructions.
The above block diagram can be broken down further, as shown below.

Fig.2

E&C Dept, NIE,MYSORE

MICROCONTROLLERS

Parameshwara.s

Two of the special function registers are shown at the top. These are the instruction
register and the program counter and are used together with the instruction decoder in the
execution cycle.
As was said earlier, the system program is stored in ROM. The program counter
is used for storing the position of the next instruction.
The instruction register is used for storing the current instruction.
The instruction decoder decodes the instruction (ie; it determines, from the
instruction, what operation to perform).
The Execution Cycle
What is meant by execution? It is the CPU's performance of an operation, as dictated
by the current instruction. When an embedded system is powered up (e.g.; you switch on
your mobile phone) the CPU fetches the first instruction from ROM. It then figures out
what operation it must perform, as dictated by the instruction. It performs the operation
and then gets the next instruction from ROM, performs the appropriate operation as
governed by this instruction, then gets the next instruction, and so on.
More specifically, on power up, the location of the first instruction in ROM is loaded
into the program counter (PC). The CPU then fetches the instruction from the location
pointed to by the PC and stores this instruction in the instruction register (IR). The
instruction decoder and control unit decode the instruction and initiate and control the
operation (the actual operation is carried out by the ALU). Then the program counter is
increased, so that it points to the next instruction in ROM and the process is repeated.
To make a complete microcomputer, one must add Memory, I/O devices etc, below fig
shows the Microcomputer block diagram.

Fig.3 Basic Microprocessor System/Microcomputer block Diagram

E&C Dept, NIE,MYSORE

MICROCONTROLLERS

Parameshwara.s

As we shall see, much of the work performed by the CPU involves reading from and
writing to memory. There are three busses involved in accessing memory: the address
bus, the data bus and the control bus.
Read Cycle
The steps involved in the read cycle are:
CPU places address on address bus.
Control signals memory - address on address bus is valid.
Memory chip fetches data from location specified by the address and places on
the data bus.
A control signal CPU - data on data bus is valid.
CPU takes data from data bus
Write Cycle
The steps involved in the write cycle are:
CPU places address on address bus.
Control signals memory - address on address bus is valid.
CPU places data on the data bus.
Control signals memory - data on data bus is valid.
Memory chip takes data from data bus and places it in the location specified by
the address.
An embedded system is made up of the basic functional blocks shown above. The
Central Processing Unit (CPU) is the microprocessor and can be thought of as the
system's brain. Memory, input ports and output ports are connected to the microprocessor
through an address bus, a data bus and a control bus. Ports are physical interfaces through
which data is sent to and from external peripherals such as keyboard, monitor etc.

Program Memory and Data Memory


There are many different kinds of memory used in embedded systems and new kinds are
being developed all the time. However, we can split memory into two types; RAM and
ROM
RAM stands for random access memory. There are two features of RAM which
distinguish it from ROM:
o RAM is read/write - data can be written to and read from RAM.
o RAM is volatile - data is lost once the power to a RAM chip is lost.
Random access refers to the fact that data from any location in the memory chip is
accessible at any time (you simply put the desired address on the address bus). However,
RAM is actually a poor choice of name for this type of memory (its name is rooted in
history) because it does not refer to its main features and it may lead you to believe other
types of memory are not random access. A memory chip is of little use if it's not random
access.
ROM stands for read only memory. As with RAM, it is random access but it
differs from RAM in two ways:

E&C Dept, NIE,MYSORE

MICROCONTROLLERS
o

Parameshwara.s

ROM, as the name suggests, is read only. You cannot write to a ROM
chip. How then, you may ask, do you get data onto a ROM chip? A ROM
chip must be programmed, but once programmed; it cannot be (easily)
changed.
ROM is non-volatile - when power is removed from the chip data is not
lost.

There are many types of ROM available; PROM, EPROM, EEPROM and Flash are
the most common and we will deal with each at a later date.
Which do we use, RAM or ROM?
The obvious advantage of RAM over ROM is the fact that data can be written to it as
well as read from it. The obvious advantage of ROM over RAM is the fact that data is not
lost on power down. So which is used in embedded systems?
The answer is both.
RAM is used for storing data that is used by the system.
For example, if you wish to heat some food and you set the timer on
your microwave oven for two minutes, this piece of data (2 minutes) is stored
in RAM and used by the system to count down to zero.
o

Another example is the time and date on a VCR. This is also stored in
RAM and is lost once you unplug the VCR. You then need to reset the
time when you plug it in again.

ROM is used for storing the system program. The program is the set of step-bystep instructions for the system to operate.
o If we take the microwave example again; the program tells the oven what
it should do when the user sets a time and presses the 'start' button. If this
data was lost once we unplugged the oven it would be useless. Therefore,
the program is stored in ROM. And since the program doesn't change it
does not matter that we cannot write to the chip. In fact, for safety reasons,
it is better that we cannot write to the chip; we might, accidentally (ie; a
bug in the program) write over some of the program and corrupt the
system.

Therefore, we should always keep in mind the two types of memory. RAM for data,
ROM for the program.
Microcontroller:

E&C Dept, NIE,MYSORE

MICROCONTROLLERS

CPU

Parameshwara.s

Memory
ROM

Subsystems:
Timers, Counters, Analog
Interfaces, I/O interfaces

RAM

I/O

A single chip
Fig.4 Basic building blocks of Microcontroller.
Above fig shows the diagram of a typical microcontroller, which is a true computer
on chip. The design incorporates all of the features found in a Microprocessor CPU. it has
added the other features needed to make a complete computer i.e. ROM, RAM, I/O
interfaces, Counters, Timers.
A Microcontroller is a general purpose device, but one that is meant to read data,
performs limited calculations on that data, and controls its environment based on those
calculations. The prime use of the MC is to control the operation of a machine using a
fixed program that is stored in ROM and that does not change over the lifetime of the
system.
What's the difference between a microprocessor and a microcontroller?
A microprocessor system consists of a microprocessor with memory, input ports and
output ports connected to it externally. A microcontroller is a single chip containing a
microprocessor, memory, input ports and output ports. Since all four blocks reside on the
one chip, a microcontroller is much faster than a microprocessor system.
Microprocessor
CPU is stand-alone, RAM, ROM, I/O, timer are separate
Designer can decide on the amount of ROM, RAM and I/O ports.
expansive
versatility
general-purpose

E&C Dept, NIE,MYSORE

MICROCONTROLLERS

Parameshwara.s

Microcontroller
CPU, RAM, ROM, I/O and timer are all on a single chip
fix amount of on-chip ROM, RAM, I/O ports
for applications in which cost, power and space are critical
single-purpose
RISC AND CISC Architecture
CISC: The two most common types of computers are Complex Instruction Set Computer
(CISC) and the Reduced Instruction Set Computer (RISC).
The features of CISC computer are listed as follows:

Large number of instructions.


Execution time for each instruction may be different.
Execution time for an instruction may be taken several clock cycles.
Single instruction will perform a complex operation.
Efficient use of memory space.
Robustness of instruction set given priority over speed of execution.
Works faster for complex instructions but may be slow for simple tasks.
Emphasis on complex hardware to store a large instruction set.
Number of instructions per program is minimized.

The most common examples of CISC architecture are:


Intel 8080, 80286, 80386, Pentium
Motorola 68000
Zilog Z80.
RISC: Reduced Instruction Set Computer refers to a type of microprocessor architecture
that utilizes a small but highly optimized set of instructions. The design features of RISC
Processors are follows.
One cycle execution time: Most instructions are executed in one clock cycle. This
design optimization of each instruction follows techniques called Pipelining.
Pipelining: Different parts of an instruction are executed simultaneously.
Large register set: The architecture uses a large number of registers to handle
data instead of relying on the memory storage.
Reduced complexity in hardware.
Variables and intermediate results stored in registers.
Complex operations are performed as a series of simple RISC instructions.
Instructions are of fixed length and format.
Emphasis on software for each task.
Program consists of large code size.

E&C Dept, NIE,MYSORE

MICROCONTROLLERS

Parameshwara.s

Only load and store instructions arefer to the memory and may take more than one
clock cycle.
Harvard and Von-Neumann CPU Architecture:

Memory
Address Bus
CPU

Data Bus

Program
+ Data

Von Neumann
Architecture

Memory
Address Bus
CPU

Program

Fetch Bus

Harvard
Architecture

Address Bus
Data Bus

Data
Fig.5

The key feature of the computer architecture developed by Princeton University was
that the computer had common memory for storing the control program as well as
variables and other data structures. E chief scientist for this project was Von-Neumann.
As a name of developer this architecture is best known as Von-Neumann architecture.
Above Fig shows the block diagram of Von-Neumann architecture. It consists of
CPU, memory. In this architecture it is not possible to fetch instruction code and data
simultaneously. However, it is possible to fetch the next instruction when current
instruction is executing. This feature is commonly known as Pre-fetching.
Harvards architecture suggested to have separate memory banks for program storage
(code memory), the processor stack and variable RAM (data memory), as shown in fig.
The Harvard architecture has an advantage of executing instructions in fewer instructions
cycles than Princeton (Von-Neumann) architecture. This is because a much greater
amount of instruction parallelism can be achieved in the Harvard architecture due to
separate memory banks.
Besides the advantage of greater amount of parallelism in Harvard architecture, VonNeumann architecture was preferred by scientist because of the unreliability of
technology of that time. They found single memory architecture more suitable of
computers. Single memory architecture allows greater flexibility in developing software;
primarily contents are accessible to the programmer along with the data.
E&C Dept, NIE,MYSORE

MICROCONTROLLERS

Parameshwara.s

The 8051 architecture consists of these specific features:


Eight bit CPU with register A(Accumulator) and B.
16-bit program counter (PC) and Data pointer (DPTR).
8-bit Program Status Word (PSW).
8-bit Stack pointer (SP).
Internal ROM 0 to 4K.
Internal RAM of 128 bytes:
4-Register Banks, each containing 8-registers
16 bytes, which may be addressed at the bit level.
8 bytes of general-purpose data memory.
32 Input/Output pins arranged as four 8-bit ports: P0-P3.
E&C Dept, NIE,MYSORE

MICROCONTROLLERS

Parameshwara.s

Two 16-bit Timer/Counters: T0 and T1


Full duplex serial data receiver/transmitter: SBUF.
Control Registers: TCON, TMOD, SCON, PCON, IP and IE.
2 external and 3 internal interrupt sources.
Oscillator and Clock circuits.

8051 Programming Model

Fig 7 Programming Model of 8051.


The Accumulator:
The Accumulator, as its name suggests, is used as a general register to accumulate
the results of a large number of instructions. It can hold an 8-bit (1-byte) value and is
the most versatile register the 8051 has due to the shear number of instructions that make

E&C Dept, NIE,MYSORE

MICROCONTROLLERS

Parameshwara.s

use of the accumulator. More than half of the 8051s 255 instructions manipulate or use
the accumulator in some way.
For example, if you want to add the number 10 and 20, the resulting 30 will be stored
in the Accumulator. Once you have a value in the Accumulator you may continue
processing the value or you may store it in another register or in memory.
The "R" registers:
R1, etc.

The "R" registers are a set of eight registers that are named R0,

These registers are used as auxiliary registers in many operations. To continue with
the above example, perhaps you are adding 10 and 20. The original number 10 may be
stored in the Accumulator whereas the value 20 may be stored in, say, register R4. To
process the addition you would execute the command:
ADD A, R4
After executing this instruction the Accumulator will contain the value 30.
You may think of the "R" registers as very important auxiliary, or "helper", registers. The
Accumulator alone would not be very useful if it were not for these "R" registers.
The "R" registers are also used to temporarily store values. For example, lets say you
want to add the values in R1 and R2 together and then subtract the values of R3 and R4.
One way to do this would be:
MOV A,R3 ;Move the value of R3 into the accumulator
ADD A,R4 ;Add the value of R4
MOV R5,A ;Store the resulting value temporarily in R5
MOV A,R1 ;Move the value of R1 into the accumulator
ADD A,R2 ;Add the value of R2
SUBB A,R5 ;Subtract the value of R5 (which now contains R3 + R4)
As you can see, we used R5 to temporarily hold the sum of R3 and R4. Of course, this
isnt the most efficient way to calculate (R1+R2) - (R3 +R4) but it does illustrate the use
of the "R" registers as a way to store values temporarily.
The B Register: The "B" register is very similar to the Accumulator in the sense that it
may hold an 8-bit (1-byte) value.
The "B" register is only used by two 8051 instructions: MUL AB and DIV AB. Thus, if
you want to quickly and easily multiply or divide A by another number, you may store the
other number in "B" and make use of these two instructions.
Aside from the MUL and DIV an instruction, the B register is often used as yet another
temporary storage register much like a ninth "R" register.

E&C Dept, NIE,MYSORE

10

MICROCONTROLLERS

Parameshwara.s

The Data Pointer (DPTR): The Data Pointer (DPTR) is the 8051s only user-accessible
16-bit (2-byte) register. The Accumulator, "R" registers, and "B" register are all 1-byte
values.
DPTR, as the name suggests, is used to point to data. It is used by a number of commands
which allow the 8051 to access external memory. When the 8051 accesses external
memory it will access address indicated by DPTR.
While DPTR is most often used to point to data in external memory, many programmers
often take advantage of the fact that its the only true 16-bit register available. It is often
used to store 2-byte values which have nothing to do with memory locations.
The Program Counter (PC): The Program Counter (PC) is a 2-byte address which tells
the 8051 where the next instruction to execute is found in memory. When the 8051 is
initialized PC always starts at 0000h and is incremented each time an instruction is
executed. It is important to note that PC isnt always incremented by one. Since some
instructions require 2 or 3 bytes the PC will be incremented by 2 or 3 in these cases.
The Program Counter is special in that there is no way to directly modify its value. That
is to say, you cant do something like PC=2430h. On the other hand, if you execute LJMP
2430h youve effectively accomplished the same thing.
It is also interesting to note that while you may change the value of PC (by executing a
jump instruction, etc.) there is no way to read the value of PC. That is to say, there is no
way to ask the 8051 "What address are you about to execute?" As it turns out, this is not
completely true: There is one trick that may be used to determine the current value of PC.
This trick will be covered in a later chapter.
The Stack Pointer: The Stack Pointer, like all registers except DPTR and PC, may hold
an 8-bit (1-byte) value. The Stack Pointer is used to indicate where the next value to be
removed from the stack should be taken from.
When you push a value onto the stack, the 8051 first increments the value of SP and then
stores the value at the resulting memory location.
When you pop a value off the stack, the 8051 returns the value from the memory location
indicated by SP and then decrements the value of SP.
This order of operation is important. When the 8051 is initialized SP will be initialized to
07h. If you immediately push a value onto the stack, the value will be stored in Internal
RAM address 08h. This makes sense taking into account what was mentioned two
paragraphs above: First the 8051 will increment the value of SP (from 07h to 08h) and
then will store the pushed value at that memory address (08h).
SP is modified directly by the 8051 by six instructions: PUSH, POP, ACALL, LCALL,
RET, and RETI. It is also used intrinsically whenever an interrupt is triggered.

E&C Dept, NIE,MYSORE

11

MICROCONTROLLERS

Parameshwara.s

The Pin diagram of 8051

P1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
RST
(RXD)P3.0
(TXD)P3.1
(INT0)P3.2
(INT1)P3.3
(T0)P3.4
(T1)P3.5
(WR)P3.6
(RD)P3.7
XTAL2
XTAL1
GND

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

8051
(8031)

40
39
38
37
36
35
34
33
32
31
30
29
28
27
26
25
24
23
22
21

Vcc
P0.0(AD0
P
) 0.1(AD1)
P0.2(AD2
P
) 0.3(AD3)
P0.4(AD4)
P0.5(AD5)
P0.6(AD6)
P0.7(AD7)
EA/VPP
ALE/PROG
PSEN
P2.7(A15)
P2.6(A14
)P2.5(A13
)P2.4(A12
)P2.3(A11)
P2.2(A10)
P2.1(A9)
P2.0(A8)

Fig.8 Pin diagram of 8051

Input/Output Pins, Ports and Circuits


8051 Microcontroller's pins
Pins 1-8: Port 1 Each of these pins can be configured as input or output.
Pin 9: RS Logical one on this pin stops microcontrollers operating and erases the
contents of most registers. By applying logical zero to this pin, the program starts
execution from the beginning. In other words, a positive voltage pulse on this pin resets
the microcontroller.
Pins10-17: Port 3 Similar to port 1, each of these pins can serve as universal input or
output . Besides, all of them have alternative functions:

E&C Dept, NIE,MYSORE

12

MICROCONTROLLERS

Parameshwara.s

Pin 10: RXD Serial asynchronous communication input or Serial synchronous


communication output.
Pin 11: TXD Serial asynchronous communication output or Serial synchronous
communication clock output.
Pin 12: INT0 Interrupt 0 input
Pin 13: INT1 Interrupt 1 input
Pin 14: T0 Counter 0 clock input
Pin 15: T1 Counter 1 clock input
Pin 16: WR Signal for writing to external (additional) RAM
Pin 17: RD Signal for reading from external RAM
Pin 18, 19: X2, X1 Internal oscillator input and output. A quartz crystal which determines
operating frequency is usually connected to these pins. Instead of quartz crystal, the
miniature ceramics resonators can be also used for frequency stabilization.
Pin 20: GND Ground
Pin 21-28: Port 2 If there is no intention to use external memory then these port pins are
configured as universal inputs/outputs. In case external memory is used then the higher
address byte, i.e. addresses A8-A15 will appear on this port. It is important to know that
even memory with capacity of 64Kb is not used ( i.e. note all bits on port are used for
memory addressing) the rest of bits are not available as inputs or outputs.
Pin 29: PSEN If external ROM is used for storing program then it has a logic-0 value
every time the microcontroller reads a byte from memory.
Pin 30: ALE Prior to each reading from external memory, the microcontroller will set the
lower address byte (A0-A7) on P0 and immediately after that activates the output ALE.
Upon receiving signal from the ALE pin, the external register (74HCT373 or 74HCT375
circuit is usually embedded) memorizes the state of P0 and uses it as an address for
memory chip. In the second part of the microcontrollers machine cycle, a signal on this
pin stops being emitted and P0 is used now for data transmission (Data Bus). In this way,
by means of only one additional (and cheap) integrated circuit, data multiplexing from
the port is performed. This port at the same time used for data and address transmission.
Pin 31: EA By applying logic zero to this pin, P2 and P3 are used for data and address
transmission with no regard to whether there is internal memory or not. That means that
even there is a program written to the microcontroller, it will not be executed, the
program written to external ROM will be used instead. Otherwise, by applying logic one

E&C Dept, NIE,MYSORE

13

MICROCONTROLLERS

Parameshwara.s

to the EA pin, the microcontroller will use both memories, first internal and afterwards
external (if it exists), up to end of address space.
Pin 32-39: Port 0 Similar to port 2, if external memory is not used, these pins can be used
as universal inputs or outputs. Otherwise, P0 is configured as address output (A0-A7)
when the ALE pin is at high level (1) and as data output (Data Bus), when logic zero (0)
is applied to the ALE pin.
Pin 40: VCC Power supply +5V
Input/Output Ports (I/O Ports)
All 8051 microcontrollers have 4 I/O ports, each consisting of 8 bits which can be
configured as inputs or outputs. This means that the user has on disposal in total of 32
input/output lines connecting the microcontroller to peripheral devices.
A logic state on a pin determines whether it is configured as input or output: 0=output,
1=input. If a pin on the microcontroller needs to be configured as output, then a logic
zero (0) should be applied to the appropriate bit on I/O port. In this way, a voltage level
on the appropriate pin will be 0.
Similar to that, if a pin needs to be configured as input, then a logic one (1) should be
applied to the appropriate port. In this way, as a side effect a voltage level on the
appropriate pin will be 5V (as it is case with any TTL input). This may sound a bit
confusing but everything becomes clear after studying a simplified electronic circuit
connected to one I/O pin.

Fig.8
Input/Output Pin: This is a simplified overview of what is connected to a pin inside the
microcontroller. It concerns all pins except those included in P0 which do not have
embedded pull up resFig.9
Output pin:
Logic zero (0) is applied to a bit in the P register. By turning output FE transistor on, the
appropriate pin is directly connected to ground.

E&C Dept, NIE,MYSORE

14

MICROCONTROLLERS

Parameshwara.s

Fig.10
Input pin:
A logic one (1) is applied to a bit in the P register. Output FE transistor is turned off. The
appropriate pin remains connected to voltage power supply through a pull-up resistor of
high resistance.
Port 0: It is specific to this port to have a double purpose. If external memory is used
then the lower address byte (addresses A0-A7) is applied on it. Otherwise, all bits on this
port are configured as inputs or outputs.
Another characteristic is expressed when it is configured as output. Namely, unlike other
ports consisting of pins with embedded pull-up resistor (connected by its end to 5 V
power supply), this resistor is left out here. This, apparently little change has its
consequences:

Fig.11
If any pin on this port is configured as input then it performs as if it floats. Such
input has unlimited input resistance and has no voltage coming from inside.

Fig.12
When the pin is configured as output, it performs as open drain, meaning that by
writing 0 to some ports bit, the appropriate pin will be connected to ground (0V). By

E&C Dept, NIE,MYSORE

15

MICROCONTROLLERS

Parameshwara.s

writing 1, the external output will keep on floating. In order to apply 1 (5V) on this
output, an external pull-up resistor must be embedded.
Port 1: This is a true I/O port, because there are no role assigning as it is the case with
P0. Since it has embedded pull-up resistors it is completely compatible with TTL circuits.
Port 2: Similar to P0, when using external memory, lines on this port occupy addresses
intended for external memory chip. This time it is the higher address byte with addresses
A8-A15. When there is no additional memory, this port can be used as universal inputoutput port similar by its features to the port 1.
Port 3: Even though all pins on this port can be used as universal I/O port, they also have
an alternative function. Since each of these functions use inputs, then the appropriate pins
have to be configured like that. In other words, prior to using some of reserve port
functions, a logical one (1) must be written to the appropriate bit in the P3 register. From
hardwares perspective, this port is also similar to P0, with the difference that its outputs
have a pull-up resistor embedded.
Current limitations on pins
When configured as outputs (logic zero (0)), single port pins can "receive" current of
10mA. If all 8 bits on a port are active, total current must be limited to 15mA (port P0:
26mA). If all ports (32 bits) are active, total maximal current must be limited to 71mA.
When configured as inputs (logic 1), embedded pull-up resistor provides very weak
current, but strong enough to activate up to 4 TTL inputs from LS series.
External Memory: In order to satisfy the programmers permanent hunger for Data
Memory, producers have embedded an additional memory block of 128 locations into the
latest versions of the 8051 microcontrollers. Naturally, its not so simpleThe problem is
that electronics performing addressing has 1 byte (8 bits) on disposal and due to that it
can reach only the first 256 locations. In order to keep already existing 8-bit architecture
and compatibility with other existing models a little trick has been used.
Using trick in this case means that additional memory block shares the same
addresses with existing locations intended for the SFRs (80h- FFh). In order to
differentiate between these two physically separated memory spaces, different ways of
addressing are used. A direct addressing is used for all locations in the SFRs, while the
locations from additional RAM are accessible using indirect addressing.

E&C Dept, NIE,MYSORE

16

MICROCONTROLLERS

Parameshwara.s

How to extend memory?


In case on-chip memory is not enough, it is possible to add two external memory chips
with capacity of 64Kb each. I/O ports P2 and P3 are used for their addressing and data
transmission.

Fig.13 External Memory Connection.


From the users perspective, everything functions quite simple if properly connected
because the most operations are performed by the microcontroller itself. The 8051
microcontroller has two separate reading signals RD# (P3.7) and PSEN#. The first one is
activated byte from external data memory (RAM) should be read, while another one is
activated to read byte from external program memory (ROM). These both signals are
active at logical zero (0) level. A typical example of such memory extension using special
chips for RAM and ROM is shown on the previous picture. It is called Hardward
architecture.
Even though the additional memory is rarely used with the latest versions of the
microcontrollers, it will be described here in short what happens when memory chips are
connected according to the previous schematic. It is important to know that the whole
process is performed automatically, i.e. with no intervention in the program.

E&C Dept, NIE,MYSORE

17

MICROCONTROLLERS

Parameshwara.s

When the program during execution encounters the instruction which resides in
external memory (ROM), the microcontroller will activate its control output ALE
and set the first 8 bits of address (A0-A7) on P0. In this way, IC circuit
74HCT573 which "lets in" the first 8 bits to memory address pins is activated.
A signal on the pin ALE closes the IC circuit 74HCT573 and immediately
afterwards 8 higher bits of address (A8-A15) appear on the port. In this way, a
desired location in additional program memory is completely addressed. The only
thing left over is to read its content.
Pins on P0 are configured as inputs, the pin PSEN is activated and the microcon
troller reads content from memory chip. The same connections are used both for
data and lower address byte.

Similar occurs when it is a needed to read some location from external Data Memory.
Now, addressing is performed in the same way, while reading or writing is performed via
signals which appear on the control outputs RD or WR.
Note: Counter and Timers, Serial Data Input/Output, Interrupts are will study in detail in
Unit 5, 6, 7 respectively.

E&C Dept, NIE,MYSORE

18

MICROCONTROLLERS

Parameshwara.s
UNIT 2

Addressing modes and Operations


Instruction Set Summary
Instructions tell the processor which operation to carry out. For example, MOV A, #5EH
tells the processor to move the data 5EH to the accumulator.
Instructions result in the processor performing some operation on some data (the data
being #5EH in the example above). The instruction above is an example of what's known
as immediate addressing. The reason for this is because the data immediately follows the
instruction in code memory.
However, it is not always adequate to store the data in code memory itself. If we needed
to read the information from a keyboard, for example, we would need to use something
other than immediate addressing.
There are eight different addressing modes in the 8051.
Opcode and Operand
The first byte of an instruction is known as the opcode (operation code) because this is
the byte that is decoded by the processor - from this code the processor can work out
what operation it must perform.
For a one-byte instruction there is only the opcode.
For a two-byte instruction the second byte is the operand. The operand can be data or an
8-bit address.
For a three-byte instruction the second and third bytes make up the operand. A two-byte
operand is usually a 16-bit address, as we shall see when we look at long addressing
Addressing Mode: An "addressing mode" refers to how you are addressing a given
memory location. In summary, the addressing modes are as follows, with an example of
each:
Immediate Addressing MOV A,#20h
Direct Addressing
MOV A,30h
Indirect Addressing
MOV A,@R0
External Direct
MOVX A,@DPTR
Code Indirect
MOVC A,@A+DPTR
Each of these addressing modes provides important flexibility.
Immediate Addressing
Immediate addressing is so-named because the value to be stored in memory immediately
follows the operation code in memory. That is to say, the instruction itself dictates what
value will be stored in memory.
For example, the instructions:
MOV A, #20h
MOV DPTR, #0ABCDH
MOV R3, #1CH
E&C Dept, NIE,MYSORE

; Copy immediate data 20H to register A


; Copy immediate data ABCDH to register DPTR
; Copy immediate data 1CH to register R3
19

MICROCONTROLLERS

Parameshwara.s

Immediate addressing is very fast since the value to be loaded is included in the
instruction. However, since the value to be loaded is fixed at compile-time it is not very
flexible.
Direct Addressing
Direct addressing is so-named because the value to be stored in memory is obtained by
directly retrieving it from another memory location. For example:
MOV A, 30h
MOV R0, 12H
MOV 8CH, R7
MOV 3AH, #3AH
MOV 0A8H, 77H

; Copy data from the RAM location 30H to A


; Copy data from the RAM location 12H to R7
; Copy data from register R7 to Timer 0 High byte
; Copy immediate data 3AH to RAM location 3AH
; Copy data from RAM location 77H to IE register

Direct addressing is generally fast since, although the value to be loaded isnt included
in the instruction, it is quickly accessible since it is stored in the 8051s Internal RAM. It
is also much more flexible than Immediate Addressing since the value to be loaded is
whatever is found at the given address--which may be variable.
Also, it is important to note that when using direct addressing any instruction which
refers to an address between 00h and 7Fh is referring to Internal Memory. Any instruction
which refers to an address between 80h and FFh is referring to the SFR control registers
that control the 8051 microcontroller itself.
The obvious question that may arise is, "If direct addressing an address from 80h
through FFh refers to SFRs, how can I access the upper 128 bytes of Internal RAM that
are available on the 8051?" The answer is: You cant access them using direct addressing.
As stated, if you directly refer to an address of 80h through FFh you will be referring to
an SFR. However, you may access the 8051s upper 128 bytes of RAM by using the next
addressing mode, "indirect addressing."
Indirect Addressing
Indirect addressing is a very powerful addressing mode which in many cases provides an
exceptional level of flexibility. Indirect addressing is also the only way to access the extra
128 bytes of Internal RAM found on an 8051.
Indirect addressing appears as follows:
MOV A, @R0
MOV @R1, #35H
MOV @R0, A

; Copy the content of the address in R0 to the A register


; Copy the immediate data 35H to the address in R1 register
; Copy the content of the A register to address in R0.

E&C Dept, NIE,MYSORE

20

MICROCONTROLLERS

Parameshwara.s

This instruction causes the 8051 to analyze the value of the R0 register. The 8051 will
then load the accumulator with the value from Internal RAM which is found at the
address indicated by R0.
For example, lets say R0 holds the value 40h and Internal RAM address 40h holds the
value 67h. When the above instruction is executed the 8051 will check the value of R0.
Since R0 holds 40h the 8051 will get the value out of Internal RAM address 40h (which
holds 67h) and store it in the Accumulator. Thus, the Accumulator ends up holding 67h.
Indirect addressing always refers to Internal RAM; it never refers to an SFR. Thus, in a
prior example we mentioned that SFR 99h can be used to write a value to the serial port.
Thus one may think that the following would be a valid solution to write the value 1 to
the serial port:
MOV R0, #99h
; Load the address of the serial port
MOV @R0, #01h ; Send 01 to the serial port -- WRONG!!
This is not valid. Since indirect addressing always refers to Internal RAM these two
instructions would write the value 01h to Internal RAM address 99h on an 8052. On an
8051 these two instructions would produce an undefined result since the 8051 only has
128 bytes of Internal RAM.
External Direct
External Memory is accessed using a suite of instructions which use what I call "External
Direct" addressing. I call it this because it appears to be direct addressing, but it is used to
access external memory rather than internal memory.
There are only two commands that use External Direct addressing mode:
MOVX A, @DPTR
MOVX @DPTR , A
As you can see, both commands utilize DPTR. In these instructions, DPTR must first be
loaded with the address of external memory that you wish to read or write. Once DPTR
holds the correct external memory address, the first command will move the contents of
that external memory address into the Accumulator. The second command will do the
opposite: it will allow you to write the value of the Accumulator to the external memory
address pointed to by DPTR.
External Indirect
External memory can also be accessed using a form of indirect addressing which I call
External Indirect addressing. This form of addressing is usually only used in relatively
small projects that have a very small amount of external RAM. An example of this
addressing mode is:
MOVX @R0, A

E&C Dept, NIE,MYSORE

21

MICROCONTROLLERS

Parameshwara.s

Once again, the value of R0 is first read and the value of the Accumulator is written to
that address in External RAM. Since the value of @R0 can only be 00h through FFh the
project would effectively be limited to 256 bytes of External RAM. There are relatively
simple hardware/software tricks that can be implemented to access more than 256 bytes
of memory using External Indirect addressing; however, it is usually easier to use
External Direct addressing if your project has more than 256 bytes of External RAM.
The letter C is added to the MOV Mnemonic to highlight the use of the opcodes for
moving data from the source address in the code ROM to the A register
Examples:
MOVC A, @A+DPTR

;Copy the byte, found at the ROM address formed by


adding A and the DPTR, to A

MOVC A, @A+PC

; Copy the byte, found at the ROM address formed by


Adding A and the PC, to A

Fig.14External Addressing using MOVX and MOVC:

E&C Dept, NIE,MYSORE

22

MICROCONTROLLERS

Parameshwara.s

PUSH and POP Opcodes:


The PUSH and POP opcodes specify the direct address of the data. The data moves
between an area of internal RAM, known as the stack, and the specified direct address.
The stack pointer special function register (SP) contains the address in RAM where data
from the source will be pushed, or where data to be poped to the destination address is
found. The SP register actually is used in the indirect addressing mode but is not named
in the mnemonic. It is implied that the SP holds the indirect address whenever Pushing or
Poping. Fig shows the stack pointer as data is Pushed or poped to the stack area in
internal RAM.
A PUSH opcode copies data from the source address to the stack. SP is incremented by
1 before the data is copied to the internal RAM location contained in SP so that the data
is stored from low address to high address in the internal RAM. The stack grows up in
memory as it is pushed. Excessive Pushing can make the stack exceed 7FH, after which
point data is lost.

E&C Dept, NIE,MYSORE

23

MICROCONTROLLERS

Parameshwara.s

A POP opcode copies data from stack to the destination address. SP is decremented by 1
after data is copied from the stack RAM address to the direct destination to ensure that
data placed on the stack is retrieved in the same order as it was stored.

PUSH

add

POP

add

; Increment SP; copy the data in add to the internal RAM

; copy the data from the internal RAM address contained in SP to add;
Decrement the SP.
Example: MOV 81H, #30H
; copy the immediate data 30h to the SP
MOV R0, #0ACH
; copy the immediate data ACh to the R0
PUSH 00H
; SP=31h; address 31h contais the ACh
PUSH 00H
; SP=32h; address 32h contais the ACh
POP
01H
; SP=31h; register R1 now contain the number ACh
POP 80H
; SP=30h; port 0 latch now contain the number Ach
DATA Exchange:
Exchange instructions actually move data in two directions, from source to destination
and from destination to source. All addressing modes except immediate may be used in
the XCH instruction.
XCH
XCH
XCH
XCH

A, Rr
A, add
A, @Rp
A, @Rp

Byte level logical Operations:


The byte-level logical operations use all four addressing modes for the source of a data
bytes. The A register or a direct address in internal RAM is the destination of the logical
operation result.
Note that no flags are affected by the byte-level logical operations unless the direct RAM
address is the PSW.
ANL
ANL
ANL
ANL

A, #n
A, add
A, Rr
A, @Rp

E&C Dept, NIE,MYSORE

ANL add, A
ANL add, #n

24

ORL
ORL
ORL
ORL
ORL
ORL

A, #n
A, add
A, Rr
A, @Rp
add, A
add, #n

XRL
XRL
XRL
XRL
XRL
XRL

A, #n
A, add
A, Rr
A, @Rp
add, A
add, #n

CLR A
CPL A
Bit level logical operations:
Certain internal RAM and SFRs can be addressed by their byte addresses or by the
address of each bit within a byte. Bit addressing is very convenient when you wish to
alter a single bit of a byte.
Internal RAM bit addresses: The available of Individual bit addresses in internal RAM
makes the use of the RAM very efficient when storing bit information.
The corresponding between byte and bit address is shown in fig 7 Programming model of
8051. (Refer back page).
SFR Bit Addresses: All SFRs may be addressed at byte level by using the direct address
assigned to it, but not all of the SFRs are addressable at the bit level. The corresponding
between byte and bit address is shown in fig 7 Programming model of 8051. (Refer back
page).
The following lists the Boolean bit level operations.
ANL C, b
; AND C and the addressed bit; put the result in C.
ANL C, /b
; AND C and compliment of the addressed bit; put the result in C; the
addressed bit is not altered.
ORL C, b
; OR C and the addressed bit; put the result in C.
ORL C,/b
; OR C and compliment of the addressed bit; put the result in C; the
addressed bit is not altered.
CPL C
; complement the C
CPL b
; complement the addressed bit
CLR C
; Clear the C flag to 0
CLR b
; Clear the addressed bit b to 0
MOV C, b ; copy the addressed bit to C
MOV b, C ; copy the C flag to addressed bit
SETB C
; set the flag to 1
SETB b
; set the addressed bit to 1.

Rotate and Swap operations:


The ability to rotate data is useful for inspecting bits of a byte without using individual
opcodes. The A register can be rotated one bit position to the left or right with or without
including the C flag in the rotation.
RR A
This instruction is rotate right the accumulator. Its operation is illustrated below:

Each bit is shifted one location to the right, with bit 0 going to bit 7.
RL A
Rotate left the accumulator.

Each bit is shifted one location to the left, with bit 7 going to bit 0.
Rotating through the Carry
There are two instructions that, in effect, create a 9-bit rotate register.
RRC
Rotate right through the carry.

Each bit is shifted one location to the right, with bit 0 going into the carry bit in the PSW,
while the carry was at goes into bit 7 (ie; if the carry was set prior to the execution of
RRC A, then bit 7 of the accumulator will contain 1 after execution of RRC A. Similarly, if
the carry was clear prior to execution of RRC A, then bit 7 of the accumulator will contain
0 after execution of RRC A).
RLC A
Rotate left through the carry.

Each bit is shifted one location to the left, with bit 7 going into the carry bit in the PSW,
while the carry goes into bit 0.
SWAP A

High Nibble

Low Nibble

Interchange the nibbles of register A; put the high nibble in the low nibble position and
the low nibble in the high nibble position.
Arithmetic Operations:
Incrementing and Decrementing: the simplest arithmetic operations involve adding or
subtracting a binary 1 and a number. These simple operations become very powerful
when coupled with the ability to repeat the operation that is to increment or decrement
until a desired result is reached. Register, direct, and indirect addressing may be
incremented or decremented. No math flags are affected.
The following are the Increment and decrement Mnemonics:
INC
INC
INC
INC
INC
DEC
DEC
DEC
DEC

A
Rr
add
@Rp
DPTR.
A
Rr
add
@Rp

Addition: All addition is done with the A register as the destination of the result. All
addressing modes may be used for the source.
The following lists the addition Mnemonics:
ADD
ADD
ADD
ADD

A, #n
A, Rr
A, add
A, @Rp

The following list is the add with carry mnemonics:


ADDC A, #n
ADDC A, Rr
ADDC A, add
ADDC A, @Rp

Subtraction: subtraction can be done by taking the twos complement of the number to
be subtracted, the subtrahend, and adding it to another number, the minuend. Register A
is the destination address for subtraction. All addressing modes may be used for source
addresses. The commands treat the carry flag as a borrow and always subtract the carry
flag as part of the operation.
The following lists the Subtraction Mnemonics:
SUBB A, #n
SUBB A, add
SUBB A, Rr
SUBB A, @Rp
Multiplication: Multiplication operation uses registers A and B as both source and
destination addresses for the operation.
Mnemonic is
MUL AB ; multiply A by B ; put the low-order byte of the product in A, put the high
Order byte in B
Division: Division operation uses registers A and B as both source and destination
addresses for the operation.
Mnemonic is
DIV AB
; divide A by B; put the integer part of quotient in register A and the integer
Part of the remainder in B.
Decimal Arithmetic: Most 8051 applications involve adding intelligence to machine
where the hexadecimal Numbering system works naturally. There are instances, however,
when application involves interacting with humans, who insist on using the decimal
number system.
Mnemonic is
DA A ; Adjust the sum of two packed BCD numbers found in A register; leave the
Adjusted number in A.

UNIT 3
Jump and Call Instructions
A jump or call instruction can replace the contents of the program counter with a new
program address number that causes program execution to begin at the code located at the
new address. The difference, in bytes, of this new address from the address in the
program where the jump or call is located is called the range of the jump or call.
Jump or call instructions may have one of three ranges: a relative range of + 127d, -128d
bytes from the instruction following the jump or call instruction, an absolute range on the
same 2K byte page as the instruction following the jump or call, or a long range of any
address from 0000h to FFFFh, any where in program memory. Fig 15 shows the relative
range of all the jump instructions.

Fig 15

Relative Range: Jumps that replaces the program counter contents with a new address
that is greater than the address of the instruction following the jump by 127d or less than
the address of the instruction following the jump by 128d are called relative ump.
Relative jumping has two advantages. 1. Only 1 byte of data need be specified, either
in positive format for jumps ahead in the program or in 2s compliment negative format
for jumps behind. The jump address displacement byte can then be added to the PC to get
the absolute address. Specifying only 1 byte saves program bytes and speeds up program
execution.
2. The program that is written using relative jumps can be located anywhere in the
program address space.
The disadvantage of using relative addressing is the requirement that all address
jumped be within a range of +127d, -128d bytes of the jump instruction. This range is not
a serous problem. Most jumps form program loops over short code range that are within
the relative range. If jumps beyond the relative range are needed, then a relative jump can
be done to another relative jump until the desired address is reached.
Short Absolute Range: Absolute range makes use of the concept of dividing memory
into logical divisions called pages. Program memory may be regarded as one continuous
stretch of address from 0000h to FFFFh. Or it may be divided into a series of pages of
any convenient binary size, such 256 bytes, 2K, and 4K and so on.
Absolute range addressing has the same advantage as relative addressing; fewer bytes are
needed and code is relocateble as long as the relocated code begins at the start of a page.
Long Absolute Range: Address that can access the entire program space from 0000h to
FFFFh use long-range addressing. Long range addresses require more bytes of code to
specify and are relocatable only at the beginning of 64K pages. Long range addressing
has the advantage of using entire program address space available to the 8051. it most
likely to be used in large programs.
Bit Jump: Bit jump all operate according to the status of the Carry flag in the PSW or
the status of any bit addressable location. All bit jumps are relative to the program
counter.
Bit Jump Instructions are:
JC radd
; jump relative if the carry flag is set to 1
JNC add
; jump relative if the carry flag is reset to 0
JB b, radd
; jump relative if address bit is set to 1
JNB b, radd
; jump relative if address bit is is reset to 0
JBC b, radd
; jump relative if address bit is set, and clear the addressable bit to 0.

Byte Jumps: Byte jumps jump instructions that test bytes of data behave as bit jumps.
If the condition that is tested is true, the jump is taken, if the condition is false, the
instruction after the jump is executed. All bytes jumps are relative to the program counter.
CJNE A, add, radd ; compare the contents of the A register with the contents of the
address; if they are not equal, then jump to the relative address; set carry flag to 1 if a is
less than the contents of the direct address; otherwise, set the carry flag to 0.
CJNE A, #n, radd: compare the contents of the A register with the immediate number
if they are not equal, then jump to the relative address; set carry flag to 1 if a is less than
the contents of the direct address; otherwise, set the carry flag to 0.
CJNE @Rp, #n, radd: compare the contents of the Rp register with the immediate
number; if they are not equal, then jump to the relative address; set carry flag to 1 if a is
less than the contents of the direct address; otherwise, set the carry flag to 0.
DJNZ Rn, radd: Decrement the register Rn by 1 and jump to the relative address if the
result is not 0; no flags are affected.
DJNZ add, radd: : Decrement the direct address by 1 and jump to the relative address
if the result is not 0; no flags are affected unless the direct address is the PSW.
JZ radd: jump to the relative address if A is 0; the flag and the A register are not
changed.
JNZ radd: jump to the relative address if A is not 0; the flag and the A register are not
changed.
This instruction is prefect for the time delay program, as detailed below.
MOV R0, 0FFH
DJNZ R0,$
The $ Operator
Most assemblers use the $ character as a pointer to the current program location.
Therefore, the instruction DJNZ R0, $ means - decrement the contents of R0 and if the
result is non-zero jump back to this line. In this way, the contents of R0 are continuously
decremented until they reach zero.
Longer Delays
As stated above, the longest single-loop delay is achieved by initialising the decrement
register (ie; the register that will be decremented) to FFH. To achieve longer delays we
can use multiple-loop time delays, as detailed in the flow chart below.

The inner loop (nested loop) takes 255 iterations before R1 reaches 0. When this happens,
the loop is exited and R0 is decremented. If R0 is not equal to zero the program jumps
back to the line that loads R1 with FFH again. Another 255 iterations of the nested loop
must occur before R0 is decremented again. Therefore, for every one iteration of the
outer loop there are 255 iterations of the inner loop.
We control the length of the time delay by changing the value loaded into R0. If R0 is
initialized to 03H, then the overall number of iterations is 3 * 255 = 765.
The maximum number of iteration for a two-loop time delay is 255 * 255 = 65025.
Calling a Subroutine from within a Subroutine
To write a three-loop delay we could create two nested loops inside a third outer loop as
detailed in the flowchart below.

Take note that the inner two loops are identical to the maximum two-loop delay shown
above. Therefore, if we write the three-loop delay in this manner we must rewrite the twoloop delay and test it. This is not an efficient programming practice. It would be better if
we reused our two-loop delay as detailed in the flowchart below.

The inner two-loop delay is replaced by a call to our original maximum two-loop delay.
In this manner we are reusing the code that was written and tested earlier.
The code for the above three-loop delay is:
DELAY3:
MOV R2,#0A0H
Loop: CALL DELAY2
DJNZ R2, Loop
RET
And the Code for the DELAY2 is:
DELAY2 :
MOV R0,#0FFH
LoadR1:
MOV R1, #0FFH
DJNZ R1, $
DJNZ R0, LoadR1
RET
Calling the three-loop delay will therefore result in 10 * 255 * 255 iterations.
We can now use our two delays for flashing the LED at something other than a 50% duty
cycle.
start:
SETB P1.0
CALL DELAY
CLR P1.0
CALL DELAY
JMP start

The above program sets the least significant bit of port 1 and then calls the two-loop
delay, after which it clears the least significant bit of port 1 and calls the three-loop delay.
The three-loop delay itself calls the two-loop delay ten times. Therefore, the LED (on
P1.0) will be off for approximately ten times longer than it is on.
Subroutines and the Stack
We have already looked at calling a subroutine in the previous section. Now we will look
at the actual call instructions and the effect they have on the stack.
Unconditional Jumps: unconditional jumps do not test any bit or byte to determine
whether the jump should be taken. The jump always taken.
JMP @A + DPTR : jump to the address formed by adding A to the DPTR; this is an
unconditional jump and will always be done; the address can be anywhere in program
memory; A the DPTR, and the flags are unchanged.
AJMP sadd : jump to a absolute short range address sadd ;this is an unconditional jump
and is always taken; and the flags are unchanged.
LJMP ladd : jump to a absolute long range address ladd ;this is an unconditional jump
and is always taken; and the flags are unchanged.
SJMP sadd : jump to a absolute relative address radd ;this is an unconditional jump and
is always taken; and the flags are unchanged.
NOP: Do nothing and go to the next instruction; NOP is used to waste time in a software
timing loop, or to leave room in a program for later additions; no flags are affected.
Calls and Subroutine: Changing execution of program by checking the external
conditions by moving data from the port pins to a location and jumping on the conditions
of the port pin data. This technique is called polling.
Another method of changing program execution is using interrupt signals on certain
external pins or internal registers to automatically cause a branch to a smaller program
that deals with the specific situation. When the event that caused the interruption has been
dealt with, the program resumes at the point in the program where the interruption took
place. Interrupt action can also be generated using software instructions named calls.
Subroutine: A subroutine is a program that may be used many times in the execution of
a larger program. The subroutine could be written into the body of the main program.
Everywhere it is needed, resulting in the fastest possible code execution.
Calls and the Stack: A call, whether hardware or software initiated, causes a jump to the
address where the called subroutine is located. At the end of the subroutine the program
resumes operation at the opcode address immediately following the call.

The stack area of internal RAM is used to automatically store the address, called the
return address, of the instruction found immediately after the call. The stack pointer
register holds the address of the last space used on the stack.
Fig 16 diagrams the following sequences of events:

Fig.16 Storing and Retrieving the return address.


1. A call opcode occurs in the program software, or an interrupt is generated in the
hardware circuitry.
2. The return address of the next instruction after the call instruction of interrupt is
found in the program counter.
3. The return address bytes are pushed on the stack, low byte first.
4. The stack pointer is incremented for each push on the stack.
5. The subroutine address is placed in the program counter.
6. The subroutine executed.
7. A RET opcode is encountered at the end of the subroutine.
8. Two pop operations restore the return address to the PC from the stack area in
internal RAM.
9. The stack pointer is decremented for each address byte pop.
Calls and Returns: Calls use short or long range addressing; returns have no addressing
mode specified but are always long range.
ACALL
sadd: call the subroutine located on the same page as the address of the
opcode immediately following the ACALL instruction; push the address of the instruction
immediately after the call on the stack.

LCALL ladd: call the subroutine located any where in program memory space; push
the address of the instruction immediately after the call on the stack.
RET: POP 2 bytes from the stack into the program counter.

Examples:1. To find Average of N numbers;


The Main Program using 0: Directive that indicates to the assembler which register bank
is being used (in case bank 0).
MOV R0, #30H
MOV R1, #05H
CALL average
;the subroutine
average:
PUSH PSW
PUSH AR0
PUSH AR1
MOV B, R1
CLR A
Loop: ADD A, @R0
INC R0
DJNZ R1
DIV AB
POP R1
POP R0
POP PSW
RET
The PSW should always be pushed onto the stack. The PSW contains the carry bit, the
parity bit, the overflow bit, etc. These bits should be saved on the stack so that when
returning from the subroutine they will have the same values as they had when entering
the subroutine.
R0 and R1 are also saved on the stack because their values are changed by the subroutine.
Notice AR0 and AR1 are used instead of R0 and R1. If you look at the you will see why
this is so. The PUSH instruction and the POP instruction take as an operand an 8-bit
address from 00H to FFH. The instruction PUSH PSW is changed by the assembler to
PUSH D0H (D0H is the address of the PSW). In the same way, PUSH AR0 is replaced by
PUSH 00 (00 is the address of R0 if the register bank being used is the default register
bank).
This is simply a convenience to the programmer. The programmer could write PUSH 01
to push R1 onto the stack. But the code is more readable as PUSH AR1.
For this to work, the programmer must tell the assembler which register bank is being
used. The first line of code does this: using 0

1. Write an ALP to Move a block of data ( N=5) from location 8035h to another
memory location 8045h.
org 0000H
mov dph,#80h
mov r0,#35h
mov r1,#45h
mov r3,#05h
back:mov dpl,r0
movx a,@dptr
mov dpl,r1
movx @dptr,a
inc r0
inc r1
djnz r3,back
here:sjmp here
end
Result: BE 8035: 01 02 03 04 05AE 8045:01 02 03 04 05.
2. Write an ALP to interchange a block of data location 30h and the 40h.
org 00h
mov r0,#30h
mov r1,#40h
mov r2,#05h
back: mov a,@r0
xch a,@r1
mov @r0,a
inc r0
inc r1
djnz r2,back
here:sjmp here
end
Result: BE : 30h:01 02 03 04 05
40h:06 07 08 09 0A

AE: 30h; 06 07 08 09 0A
40: 01 02 03 04 05

3. Write an ALP to interchange a block of data of location 8060h and 8070h.

org 0000h
mov dph,#80h
mov r0,#60h
mov r1,#70h
mov r2,#06h
back:mov dpl,r0
movx a,@dptr
mov r4,a
mov dpl,r1
movx a,@dptr
xch a,r4
movx @dptr,a
mov a,r4
mov dpl,r0
movx @dptr,a
inc r0
inc r1
djnz r2,back
here:sjmp here
end
Result:

BE 8060h: 01 02 03 04 05
8070h: 06 07 08 09 0A

AE: 8060h:06 07 08 09 0A
8070h:01 02 03 04 05

4. Write an ALP to find the Smallest of N-numbers, the numbers are stored in
starting address 8000h and store the result in next location of last element
org 0000h
mov dptr,#8000h
mov r0,#05
movx a,@dptr
mov r1,a
back:inc dptr
movx a,@dptr
clr c
movx a,@dptr
mov r2,a
subb a,r1
jnc next
mov a,r2
mov r1,a
next:djnz r0,back
mov a,r1
inc dptr
movx @dptr,a
here:sjmp here

end
Result: BE: 8000h: 06 07 04 02 03

AE: 8000h: 06 07 04 02 03 02

5. Write an ALP to find the Largest of N-numbers, the numbers are stored in starting
address 8000h and store the result in next location of last element
org 0000h
mov dptr,#8000h
mov r0,#05
movx a,@dptr
mov r1,a
back: inc dptr
clr c
movx a,@dptr
mov r2,a
subb a,r1
jc next
mov a,r2
mov r1,a
next:djnz r0,back
mov a,r1
inc dptr
movx @dptr,a
here:sjmp here
end
Result: BE: 8000h: 06 07 04 02 03
AE: 8000h: 06 07 04 02 03 07
6. Write an ALP to arrange the number in ascending /Descending order the given
numbers are stored from location 8000h.
org 0000h
mov r0,#05h
again:mov dptr,#8000h
mov r1,#05h
back:mov r2,dpl
movx a,@dptr
mov b,a
inc dptr
movx a,@dptr
cjne a,0f0h,next
ajmp skip
next:jnc skip
// for descending order Jc
mov dpl,r2

movx @dptr,a
inc dptr
mov a,0f0h
movx @dptr,a
skip:djnz r1,back
djnz r0,again
here:sjmp here
end
Result: BE: 8000h: 06 07 04 02 03

AE: 8000h: 02 03 04 06 07

7. Write an ALP to perform the operation of a Hexadecimal Up counter.


org 00h
mov a,#00h
back:acall delay
inc
jnz back
here:sjmp here
delay:mov r1,#0ffh
dec2:mov r2,#0ffh
dec1:mov r3,#0ffh
next:djnz r3,next
djnz r2,dec1
djnz r1,dec2
ret
end
8. Write an ALP to perform the operation of a BCD Up counter.
org 00h
mov a,#00h
back:acall delay
add a,#01h
da a
jnz back
here:sjmp here
delay:mov r1,#0ffh
dec2:mov r2,#0ffh
dec1:mov r3,#0ffh
next:djnz r3,next
djnz r2,dec1
djnz r1,dec2
ret
end
10. Write an ALP to perform the operation of a BCD Down counter

org 00h
mov a,#99h
back:acall delay
add a,#99h
da a
jz back
here :sjmp here
delay: mov r1,#0ffh
dec2 :mov r2,#0ffh
dec1:mov r3,#0ffh
next:djnz r3,next
djnz r2,dec1
djnz r1,dec2
ret
end
11. Write an ALP to perform the following operation
If X=00; perform the operation A+B
Else if X=01perform the operation A-B.
Else if X=02 perform the operation A*B.
Else if X=03 perform the operation A/B.
org 0000h
mov r0,#40h
mov r1,#41h
mov a,@r1
inc r1
mov b,@r1
cjne @R0,#00,next
add a,b
sjmp last
next:cjne @r0,#01,nxt1
subb a,b
jnc dn
mov b,#0ffh
dn:sjmp last
nxt1:cjne @r0,#02,nxt2
mul ab
sjmp last
nxt2:cjne @r0,#03,nxt3
div ab
sjmp last
nxt3:mov a,#00h
mov b,#00h
last:inc r0

mov @r0,a
inc r0
mov @r0,b
here:sjmp here
end
Result: BE: 1. 40h: 00 07 04
2. 40h: 01 04 07
3. 40h: 02 03 03
4. 40h: 03 03 06

AE: 40h: 00 0B 00
40h: 01 03 00
40h: 02 09 00
40h: 03 02 00

12. Three 8-bit Nos X , N1 and N2 are stored in internal RAM locations 20h,21h,and
22h respectively. Write an ALP to completing the following.
If X=00: perform N1 AND N2.
If X=01: perform N1 OR N2.
If X=02: perform N1 XOR N2. Else result is 00. The result location is 23h.
Org 00h
Mov R0,#20h
Movx a, @R0
Inc R0
Mov a,R0
Mov b,a
Inc R0
Mov a,@R0
Cjne R1,#00,0r1
Anl a,b
Sjmp last
Or1: Cjne r1,#01,xor1
Orl a,b
Sjmp last
Xor1: Cjne r1,#02,other
Xrl a,b
Other: Clr a
Last : Inc r0
Mov @r0,a
Here:Sjmp here
End
Result: BE: 20h: 00 02 03
20h: 01 02 03
20h: 02 02 03
20h: 03 02 03

AE: 20h: 00 02 03 02
20h: 01 02 03 03
20h: 02 02 03 01
20h: 03 02 03 00

13. Two 8- bit Nos N1 and N2 are stored in external memory location X and Y
Respectively write an ALP to compare the two No;s, reflect your result as if
N1<N2 set LSB of the RAM as 2Fh. If N1>N2 set MSB of location 2Fh. If
N1==N2, clear bouth LSB and MSB of bit addressable memory location 2Fh.
Org 00h
Mov dptr, #8000h
Movx a,@dptr
Mov b,a
Inc dptr
Movx a, @dptr
Cjne a,0f0,next
Clr 7fh
Clr 78h
Sjmp last
Next:Jnc sett
Setb 7fh
Sjmp last
Sett:Setb 78h
Sjmp last
Last: sjmp last
End
Result: BE: 8000h: 06 07
8000h: 07 06
8000h: 06 06

AE: 2Fh: 01
AE: 2Fh: 80
AE: 2Fh: 81

1. An array of elements stored in location 4000h, Write an ALP to sort out the
EVEN and ODD numbers in location 5000h onwards and ODD numbers is
location 6000h onwards.
org 00h
mov r0,#0ah
mov r1,#00h
mov r2,#40h
mov r3,#00h
mov r4,#50h

mov r5,#00h
mov r6,#60h
back:mov dpl,r1
mov dph,r2
movx a,@dptr
jb acc.0,next
mov dpl,r3
mov dph,r4
movx @dptr,a
inc r3
sjmp next1
next:mov dpl,r5
mov dph,r6
movx @dptr,a
inc r5
next1:inc r1
djnz r0,back
here:sjmp here
end
Result: BE: 4000h: 06 07 04 02 03 08 05 01 09 0A
AE: 5000h: 07 03 05 09 6000h: 06 04 02 08 0A
2. Write an ALP to perform the Conversion of an 8-bit BCD number to
Hexadecimal.
org 00h
mov a,#45
anl a,#0f0h
swap a
mov b,#0ah
mul ab
mov r0,a
mov a,#45h
anl a,#0fh
add a,r0
here:sjmp here
end
AE: A= 3F
3. Write an ALP to Convert BCD to ASCII.
org 00h
mov r0,#30h

mov a,@r0
mov r1,a
anl a,#0fh
add a,#30H
inc r0
mov @r0,a
mov a,r1
anl a,#0f0h
swap a
add a,#30h
inc r0
mov @r0,a
here:sjmp here
end
Result: BE: 30h: 06

AE: 30h: 36

4. Write an ALP to perform the Conversion of a 8-bit Hexadecimal number to BCD


number.
org 00h
mov a,#0ffh
mov dptr,#9000h
mov b,#0ah
div ab
xch a,b
movx @dptr,a
xch a,b
mov b,#0ah
div ab
xch a,b
inc dptr
movx @dptr,a
xch a,b
inc dptr
movx @dptr,a
here:sjmp here
end
Result: BE: 9000h: 00 00 00

AE: 8000h: 05 05 02

5. Write an ALP to Convert Hexadecimal to ASCII.


org 00h
mov r0,#40h
mov a,@r0

mov r3,a
anl a,#0fh
acall ascii
inc r0
mov @r0,a
mov a,r3
anl a,#0f0h
swap a
acall ascii
inc r0
mov @r0,a
here:sjmp here
ascii:mov r4,a
subb a,#0ah
mov a,r4
jnc skip
sjmp last
skip:add a,#07h
last:add a,#30h
ret
end
Result: BE: 40h: 0B

AE: 40h: 42

6. Write an ALP to generate Fibonacci series up to N Th term.


org 00h
mov r0,#10
mov r1,#20h
mov @r1,#0
inc r1
mov @r1,#1
back:mov a,@r1
dec r1
add a,@r1
inc r1
inc r1
mov @r1,a
cjne @r1,#08h,back
here:sjmp here
end
Result: AE: 20h: 00 01 01 02 03 05 08
7. Write an ALP to the Square Root of the given number. and store the result in R2

org 0000h
mov r1,#00
back:mov a,r1
mov b,a
mul ab
cjne a,#64,next
sjmp last
next:inc r1
sjmp back
last:mov a,r1
mov r2,a
here:sjmp here
end
AE: R2= 08
19. Write an ALP to search the given number is present in the array on N numbers
org 0000h
mov dptr,#2000h
mov r1,#00h
mov r2,#00h
mov r3,#05h
back:movx a,@dptr
cjne a,#66h,next
mov r1,dpl
mov r2,dph
sjmp last
next:inc dptr
djnz r3,back
last:mov a,r1
mov dptr,#2200h
movx @dptr,a
mov a,r2
inc dptr
movx @dptr,a
here:sjmp here
end
Result: BE: 2000h: 06 66 04 02 03

AE: 2200h: 01 20

20. Write an ALP to Find the Nos of 0s and 1s are present in a byte of data.
org 0000h
mov r0,#50h
mov r3,#00h
mov r4,#00h

mov r5,#08h
mov a,@r0
back:rrc a
jc skip
inc r4
sjmp last
skip: inc r3
last: djnz r5,back
mov a,r3
inc r0
mov @r0,a
inc r0
mov a,r4
mov @r0,a
here:sjmp here
end
Result: BE: 50h: 06

AE: 50h: 02 06 02

UNIT 4
8051 Programming in C
Why Program the 8051 in C?
Compilers produce the hex files that we download into the ROM of the microcontroller.
The size of the hex file produced by the compiler is one of the main concerns of
microcontroller programmers, for two reasons.
1. Microcontrollers have limited on-chip ROM.
2. The code space for the 8051 is limited to 64K bytes.
The following are some of the major reasons for writing program in C instead of
Assembly.

It is easier and less time consuming to write in C than Assembly.


C is easier to modify and update.

You can use code available in function libraries.

C code is portable to other microcontrollers with little or no modification.

C data types for the 8051


Unsigned char: Since the 8051 is an 8-bit microcontroller, the character data type is the
most natural choice for many applications. The unsigned char is an 8-bit data type that
takes a value in the range of 0 255. It is one of the most widely used data types for the
8051.
Signed char: the signed char is an 8-bit data type that the most significant bit to represent
the or + value. As result, we have only 7 bits for the magnitude of the signed number,
giving us values from -128 to +127.
Note: if do not use key word unsigned, the default is signed value.

Unsigned int: The unsigned data type is a 16-bit data type that a value in the range of 0
to 65535. in the 8051, unsigned int is used to define 16-bit variables such as memory
addresses. It is also set counter values of more than 256.
Signed int: signed int is a 16-bit data type that uses most significant bit to represent the
or + value. As a result, we have only 15 bits for the magnitude of the number, or values
from -32,768 to +32,767.
sbit(single bit): The sbit keyword is a widely used 8051 C data type designed
specifically to access single-bit addressable registers. It allows access to the single bit of
the SFR registers.
Bit and sfr: the bit data type allows access to single bits of bit-addressable memory
spaces 20h-2Fh. Notice that while the sbit data type is used for bit-addressable SFR.
To access the byte-size SFR register, we use sfr data type.
Examples:
1. Write an 8051 C program to send values 00-FF to port P1.
Solution:
#include<reg51.h>
void main (void)
{
unsigned char z;
for (z = 0 ; z <= 255 ; z++)
P1 = z;
}
2. Write an 8051 C program to send hex values for ASCII characters of 1, 2, 3, 4, 5, A, B,
C and D to port P1.
Solution:
#include<reg51.h>
void main (void)
{
unsigned char mynum[] = 012345ABCD ;
unsigned char z;
for (z = 0 ; z <= 255 ; z++)
P1 = mynum[z];
}

3. Write an 8051 C program to toggle all the bits of P1 continuously.


Solution:
#include<reg51.h>
void main (void)
{
for ( ; ; )
P1 = 0x55;
P1 = 0xAA;
}
}
4. Write an 8051 C program to send values of -4 to +4 to port P1.
Solution:
#include<reg51.h>
void main (void)
{
char mynum[] = {+1,-1,+2,-2,+3,-3,+4,-4};
unsigned char z;
for (z = 0 ; z <= 8 ; z++)
P1 = mynum[z];
}
5. Write an 8051 C program to toggle the bit D0 of the P150000 times.
Solution:
#include<reg51.h>
sbit mybit = P1^0;
void main (void)
{
unsigned int z;
for (z = 0 ; z <= 50000 ; z++)
{
mybit = 0;
mybit = 1;
}
}
Time Delays: there are two ways to create a time delay in 8051 C.

Using a simple for loop.


Using the 8051 timers.

In either case, when we write a time delay we must use the oscilloscope to measure the
duration of our time delay.

In creating a time delay using a for loop, three factors that can affect the accuracy of the
delay.
1. The number of machine cycles and the number of clock periods per machine cycle
vary among different versions of the 8051/52 microcontroller. While the original
8051/52 design used 12 clock periods per machine cycle, many of the newer
generations of the 8051 use the fewer clock per machine cycle. For example the
DS5000 uses 4 clock periods per machine cycle, while the DS89C420 uses only one
clock per machine cycle.
2. The crystal frequency connected to the X1-X2 input pins. The duration of the clock
period for the machine cycles is a function of this crystal frequency.
3. Compiler choice. The third factor that affects the time delay is the compiler used to
compiler the C program. When we program in Assembly language, we can control the
exact instructions and sequences used in the delay subroutine. In the case of C
programs, it is the C compiler that converts the C statements and functions to
Assembly language instructions. As a result different compilers produce different
code.
Example .
1. Write an 8051 C program to toggle the all the bits of P2 continuously with a 250msec.
Solution:
#include<reg51.h>
Void msdelay (unsigned int );
void main (void)
{
for ( ; ;)
{
P0 = 0x55;
P2 = 0x55;
Msdelay(250);
P0 = 0xAA;
P2 = 0xAA;
Msdelay(250);
}}
void Msdelay(unsigned int itime)
{
unsigned int i, j;
for ( I = 0; i< itime ; i++)
for ( j = 0; j< 1275 ; j++) }

2. LEDs are connected to bits P1 and P2. Write an 8051 C program that shows the count
from 0 to FFh on the LEDs.
Solution:
#include<reg51.h>
#define LED P2
void main (void)
{
P1 = 00;
LED = 0;
for ( ; ;)
{ P1++;
LED++;}}
3. Write an 8051 C program to get a byte of data from P1, wait second, and then send it
to P2.
Solution:
#include<reg51.h>
void msdelay (unsigned int);
void main (void)
{
unsigned char mybyte;
P1 = 0xFF;
while (1)
{
mybyte = P1;
msdelay (500);
P2 = mybyte;
}
}
void msdelay (unsigned int itime);
{ unsigned int i , j;
for (i = 0 ; i <= itime ; i++)
for (j= 0 ; j <= 1275 ; j++)
}
4. Write an 8051 C program to get a byte of data from P1, wait second, and then send it
to P2.
Solution:
#include<reg51.h>
void main (void)

{
unsigned char mybyte;
P0 = 0xFF;
while (1)
{
mybyte = P0;
ef ( mybyte< 100 )
P1 = mybyte;
else
P2 = mybyte;
}
}
5. Write an 8051 C program to toggle only bit P2.4 continuously without the rest of the
bits of P2.
Solution:
#include<reg51.h>
sbit mybit = P2^4;
void main (void)
{
for ( ; ;)
{
mybit = 1;
mybit = 0;
}}
6. Write an 8051 C program to monitor bit P1.5.if it is high, send 55H to P0; otherwise,
send AAH to P2.
Solution:
#include<reg51.h>
sbit mybit = P1^5;
void main (void)
{
mybit = 1;
for ( ; ;)
{
if(mybit = = 1);
P0 = 0x55;
else
P2 = 0xAA;
}}

7. A door sensor is connected to the P1.1 pin, and a buzzer is connected to P1.7. write an
8051 C program to monitor the door sensor, and when it opens, sound the buzzer. You
can sound the buzzer by sending a square wave of a few hundred Hz.
Solution:
#include<reg51.h>
void msdelay (unsigned int);
sbit dsensor = P1^1;
sbit Buzzer = P1^7;
void main (void)
{dsensor = 1;
while = 0;
msdelay(200);
buzzer = 1;
msdelay(200);
}
}
void msdelay (unsigned int itime)
{
unsigned int i, j;
for ( i = 0; i< itime ; i++)
for ( j = 0; j< 1275 ; j++)
}
8. The data pins of an connected to P1. the information is latched into the LCD whenever
its Enable pin goes from high to low. Write an 8051 C program to send the Earth is but
one country to this LCD.
Solution:
#include<reg51.h>
#define LCDdata P1
sbit En = P2^0;
void main (void)
{
unsigned char message[] = the Earth is but one country ;
unsigned char z;
for ( z = 0; z<28;z++)
{ LCDdata = message[z] ;
En = 1;
En = 0;
}}
9. Write an 8051 C program to toggle all the bits 0f P0, P1, and P2 continuously with a
250msec delay. Use the sfr keyword to decline the port addresses.

Solution:
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr P2 = 0xA0;
void msdelay (unsigned int);
void main (void)
{
P0 = 0x55;
P1 = 0x55;
P2 = 0x55;
msdelay (250);
P0 = 0xAA;
P1 = 0xAA;
P2 = 0xAA;
msdelay (250);
}}
void msdelay (unsigned int itime)
{
unsigned int i, j;
for ( i = 0; i< itime ; i++)
for ( j = 0; j< 1275 ; j++)
}
Bit-wise operators in C:
While every C programmer is familiar with the logical operators AND (&&), OR (||),and
NOT (!), many C programmers are less familiar with the bitwise operators AND ( & ),
OR ( | ),EX-OR ( ^ ),Inverter ( ~ ), shift Right ( >> ), and shift left ( << ). These bit-wise
operators are widely used in software engineering for embedded systems and control.
A
0
0
1
1

B
0
1
0
1

AND
A&B
0
0
0
1

OR
A|B
0
1
1
1

EX-OR
A^B
0
1
1
0

Inverter
Y = ~B
1
0

10. Write an 8051 C program to toggle all the bits 0f P0 and P2 continuously with a
250msec delay. Use the Inverter operator.
Solution:
#include<reg51.h>
void msdelay (unsigned int);
void main (void)
{
P0 = 0x55;

P2 = 0x55;
while (1)
{
P0 = P0;
P2 = ~P2;
msdelay(200);
}
}
void msdelay (unsigned int itime)
{
unsigned int i, j;
for ( i = 0; i< itime ; i++)
for ( j = 0; j< 1275 ; j++)
}
Bit-wise shift operation in C:
There are two bit-wise shift operators in C: 1. shift right ( >> ), and 2. shift left ( << ).
Their format in C is as follows:
Data >> number of bits to be shifted right
Data << number of bits to be shifted left.
The following shows some examples of shift operators in C
1. 0x9A >> 3 = 0x13 // shifting right 3 times//
2. 0x77 >> 4 = 0x07 // shifting right 4 times//
3. 0x6 << 4 = 0x60 // shifting right 4 times//
11. Write an 8051 C program to toggle all the bits 0f P0, P1, and P2 continuously with a
250msec delay. Use the EX-OR operator.
Solution:
#include<reg51.h>
void msdelay (unsigned int);
void main (void)
{
P0 = 0x55;
P1 = 0x55;
P2 = 0x55;
while (1)
{
P0 = P0^0xFF;
P1 = P1^0xFF;
P2 = P2^0xFF;
msdelay (250);

}}
void msdelay (unsigned int itime)
{
unsigned int i, j;
for ( i = 0; i< itime ; i++)
for ( j = 0; j< 1275 ; j++) ;
}
12. Write an 8051 C program to get bit P1.0 and send it to P2.7 after inverting it.
Solution:
#include<reg51.h>
sbit inbit = P1^0;
sbit outbit = P2^7;
bit membit;
void main (void)
{
for ( ; ;)
{
membit = 1;
outbit = ~membit;
}}
13. Write an 8051 C program to read the P1.0 and P1.1 bits and issue an ASCII character
to P0 according to the following table.
P1.1

P1.0

Send 0 to P0

Send 1 to P0

Send 2 to P0

Send 3 to P0

Solution:
#include<reg51.h>
void msdelay (unsigned int);
void main (void)
{
unsigned char z;
z = P1;

z = z & 0x3;
switch (z)
{
Case (0):
{
P0 = 0 ;
break;
}
Case (1):
{
P0 = 1 ;
break;
}
Case (2):
{
P0 = 2 ;
break;
}
Case (3):
{
P0 = 3 ;
break;
}}}
Data Conversion Program in 8051 C:
14. Write an 8051 C program to convert packed BCD 0x29 to ASCII and display the
bytes on P1 and P2.
Solution:
#include<reg51.h>
void main (void)
{
unsigned char x, y, z;
unsigned char mybyte = 0x29;
x = mybyte & 0x0F
P1 = x | 0x30;
Y = mybyte & 0xF0;
Y = y >> 4;
P2 = y | 0x30;
}
15. Write an 8051 C program to convert ASCII digits of 4 and 7 to packed BCD and
display them on P1.
Solution:

#include<reg51.h>
void main (void)
{
unsigned char bcdbyte;
unsigned char w = 4;
unsigned char z = 7;
w = w & 0x0F;
w = w<<4;
z = z & 0x0F;
bcdbyte = w | z ;
P1 = bcdbyte;
}

16. Write an 8051 C program to convert 11111101 (FD Hex) to decimal and the digits on
P0. P1 and P2.
Solution:
#include<reg51.h>
void main (void)
{
unsigned char x, binbyte, d1,d2,d3;
binbyte = 0xFD;
x = binbyte / 10 ;
d1 = binbyte % 10 ;
d2 = x % 10 ;
d3 = x / 10;
P0 = d1;
P1 = d2;
P2 = d3;
}
17. Write a C program to send out the value 44H serially one bit at a via P1.0. the LSB
should go out first.
Solution:
#include<reg51.h>
sbit p1b0 = P1^0;
sbit regALSB = ACC^0;
void main (void)
{
unsigned char conbyte = 0x44;
unsigned char x;
ACC = conbyte;
For ( x = 0 ; x<8 ; x++)

{
P1b0 = regALSB;
ACC ACC << 1;
}
}
18. Write a C program to bring in a byte of data serially one bit at a time via P1.0. The
LSB should come in first.
Solution:
#include<reg51.h>
sbit p1b0 = P1^0;
sbit regALSB = ACC^0;
void main (void)
{
unsigned char conbyte = 0x44;
unsigned char x;
ACC = conbyte;
For ( x = 0 ; x<8 ; x++)
{
P1b0 = regALSB;
ACC ACC << 1;
}
}

UNIT 5

Timer/Counter Programming in 8051


Counters and Timers
The 8051 microcontrollers have 2 timer counters called T0 and T1. As their names
tell, their main purpose is to measure time and count external events. Besides, they can be
used for generating clock pulses used in serial communication, i.e. Baud Rate.
Timer T0
As it is shown in the picture below, this timer consists of two registers TH0 and TL0.
The numbers these registers include represent a lower and a higher byte of one 16-digit
binary number.

This means that if the content of the timer 0 is equal to 0 (T0=0) then both registers it
includes will include 0. If the same timer contains for example number 1000 (decimal)
then the register TH0 (higher byte) will contain number 3, while TL0 (lower byte) will
contain decimal number 232.

Formula used to calculate values in registers is very simple:


TH0 256 + TL0 = T
Matching the previous example it would be as follows :
3 256 + 232 = 1000

Since the timers are virtually 16-bit registers, the greatest value that could be written to
them is 65 535. In case of exceeding this value, the timer will be automatically reset and
afterwards that counting starts from 0. It is called overflow. Two registers TMOD and
TCON are closely connected to this timer and control how it operates.
Timer 1
Referring to its characteristics, this timer is a twin brother to the Timer 0. This means
that they have the same purpose, their operating is controlled by the same registers
TMOD and TCON and both of them can operate in one of 4 different modes.

TMOD Register (Timer Mode)


This register selects mode of the timers T0 and T1. As illustrated in the following picture,
the lower 4 bits (bit0 - bit3) refer to the timer 0, while the higher 4 bits (bit4 - bit7) refer
to the timer 1. There are in total of 4 modes and each of them is described here in this
book.

Bits of this register have the following purpose:

GATE1 starts and stops Timer 1 by means of a signal provided to the pin INT1
(P3.3):
o 1 - Timer 1 operates only if the bit INT1 is set
o 0 - Timer 1 operates regardless of the state of the bit INT 1
C/T1 selects which pulses are to be counted up by the timer/counter 1:
o 1 - Timer counts pulses provided to the pin T1 (P3.5)
o 0 - Timer counts pulses from internal oscillator
T1M1,T1M0 These two bits selects the Timer 1 operating mode.

T1M1

T1M0

Mode

Description

13-bit timer

16-bit timer

8-bit auto-reload

Split mode

GATE0 starts and stops Timer 1, using a signal provided to the pin INT0 (P3.2):
o 1 - Timer 0 operates only if the bit INT0 is set
o 0 - Timer 0 operates regardless of the state of the bit INT0
C/T0 selects which pulses are to be counted up by the timer/counter 0:
o 1 - Timer counts pulses provided to the pin T0(P3.4)
o 0 - Timer counts pulses from internal oscillator
T0M1,T0M0 These two bits select the Timer 0 operating mode.
T0M1

T0M0

Mode

Description

13-bit timer

16-bit timer

8-bit auto-reload

Split mode

TCON - Timer Control Register


This is also one of the registers whose bits directly control timer operating.
Only 4 of all 8 bits this register has are used for timer control, while others are used for
interrupt control which will be discussed later.

TF1 This bit is automatically set with the Timer 1 overflow


TR1 This bit turns the Timer 1 on
o 1 - Timer 1 is turned on
o 0 - Timer 1 is turned off
TF0 This bit is automatically set with the Timer 0 overflow.
TR0 This bit turns the timer 0 on
o 1 - Timer 0 is turned on
o 0 - Timer 0 is turned off

Programming 8051 Timers


Mode 1 Programming:
The following are the characteristics and operations of mode 1:
1. It is a 16-bit timer; therefore, it allows values of 0000 to FFFFH to be loaded into
the timers registers TL and TH.
2. After TH and TL are loaded with a 16-bit initial value, the timer must be started.
This is done by SETB TR0 for Timer 0 and SETB TR1 for Timer 1.
3. After the timer is started, it starts to count up. It counts up until it reaches its limit
of FFFFH. When it rolls over from FFFFH to 0000H, it sets high a flag bit called
TF (Timer flag). This timer flag can be monitored. When this timer flag is raised,
one option would be to stop the timer with instructions CLR TR0 or CLR
TR1 for timer 0 and timer 1, respectively.
4. After the timer reaches its limit and rolls over, in order to repeat the process the
registers TH and TL must be reloaded with the original value and TF must be
reset to 0.

Steps to program in mode 1:


To generate a time delay, using the timers mode 1 the following steps are taken.

1. Load the TMOD value register indicating which time is to be used and which
timer mode is selected.
2. Load registers TL and TH with initial count value.
3. Start the Timer.
4. Keep monitoring the timer flag (TF) with the JNB TFx, target instruction to
see if it is raised. Get out of the loop when TF becomes high.
5. Stop the Timer.
6. Clear the TF flag for the next round.
7. Go back to step 2 to load TH and TL again.

Timer delay calculation:


In Hex;

(FFFF YYXX + 1) * system clock period


Where YY XX are TH, TL initial values respectively.

In Decimal;

(65536 NNNNN) * system clock period


Where NNNNN initial value in decimal

Mode 0 Programming:
Mode 0 is exactly like mode 1 except that it is a 13-bit timer instead of 16-bit. The
13-bit counter can hold values between 0000 to 1FFFH in TH TL. Therefore the
timer its reaches maximum of 1FFFH, it rolls over to 0000, and TF is raised.
Mode 2 Programming:
The following are the characteristics and operations of mode 2.
1. It is an 8-bit timer; therefore, it allows only values of 00 to FFH to be loaded
into the timers register TH.
2. After TH is loaded with 8-bit value, the 8051 gives a copy of it to TL. Then
the timer must be started. This is done by the instruction SETB TR0 for
timer 0 and SETB TR1 for timer 1. this is like mode 1.

3. After the timer is started, it starts to count up by incrementing the TL register.


It counts up until it reaches its limit of FFH. When it rolls over from FFH to
00, it sets high the TF. If we are Timer 0, TF0 goes high, if we are using timer
1, TF1 is raised.
4. When the TL register rolls from FFH to 00 and is set to 1, TL reloaded
automatically with the original value kept by the TH register. To repeat the
process, we must simply clear TF and let it go without any needed by the
programmer to reloaded the original value. This makes mode 2 an auto-reload,
in contrast with mode 1 in which the programmer has to reload TH and TL.

Steps to Program in Mode 2:


To generate a time delay using the timers mode 2, take the following steps.
1. Load the TMOD value register indicating which timer is to be used, and
select the timer mode.
2. Load the TH register with the initial count value.
3. Start the timer.
4. Keep monitoring the timer flag (TF) with the JNB TFx, target instruction to
see whether it is raised. Get out of the loop when TF becomes high.
5. Clear the Flag.
6. Go back to step 4, since mode 2 is auto-reload.
Timer delay calculation:
In Hex;

(FF XX + 1) * system clock period


Where XX is the TH initial value.

In Decimal;

(256 NNN) * system clock period


Where NNN initial value in decimal

How to measure pulses?

Suppose it is needed to measure the duration of an event, for example how long some
device has been turned on? Look at the picture of the timer and pay attention to the
purpose of the bit GATE0 (which resides in the TMOD register). If this bit is cleared then
the state on the pin P3.2 does not affect the timer operating. If GATE0 = 1 the timer will
operate as far as the pin P3.2 has logic one (1) value. If this pin is supplied with 5V
through some external switch at the moment the device is being turned on, the timer will
measure duration of its operating, which actually was the aim.
How to count up pulses?
This time, the answer lies in the register TCON, and bit C/T0 respectively. Similar to the
previous example, this bit brings into an external signal. If the bit is cleared everything
occurs in the same way as in the previous examples and the timer counts pulses from
oscillator of defined frequency, i.e. measures the time that went by. If the bit is set, the
timer input is provided with pulses from the pin P3.4 (T0). Since these pulses do not have
some definite time or order, it is not possible to measure time by counting them. For that
reason, this timer is turned into the counter. The highest frequency that could be
measured by such a counter is 1/24 frequency of used quartz-crystal.
Accessing timer registers in C
1. Write a 8051 C program to toggle all the bits of port P1 continuously with some delay
in between. Use Timer 0, 16-bit mode to generate the delay.
Solution:

#include<reg51.h>
Void T0Delay(void);
Void main (void)
{
P1=0x55;
T0Delay();
P1=0xAA;
T0Delay ();
} }
Void T0Delay ()
{
TMOD = 0x01;
TL0 = 0x00;
TH0 = 0x35;
TR0 = 1;
While (TF0 = = 0);
TR0 =0;
TF0= 0;
}
Calculation: FFFFH 3500H = CAFFH = 51967 + 1 = 51968
51968 * 1.085 s = 56.384 is the approximate Delay.

2. Write an 8051 C program to toggle only bit P1.5 continuously every 50ms. Use
Timer0, mode 1 (16-bit) to create the delay.
Solution:
#include<reg51.h>
Void T0M1delay (void);
Sbit mybit = P1^5;
Void main (void)
{
While (1)
{
mybit = ~mybit;
T0M1delay();
}}
Void T0M1delay (void)
{
TMOD = 0x01;
TL0 = 0x0FD;
TH0 = 0x4B;

TR0 = 1;
While (TF0==0);
TR0 = 0;
TF0 = 0;
}
Calculation: FFFFH 4BFDH = B402H = 46082 + 1 = 46083
Time delay = 46083 * 1.085 s = 50ms.
3. Write an 8051 C program to toggle all bits of P2 continuously every 500ms. Use Timer
1, mode 1 to create the delay.
Solution:
#include<reg51>
Void T1delay (void);
Void main (void)
{
Unsigned char x;
P2 = 0x55;
While (1)
{
P2 = ~P2;
For (x=0; x<20; x++)

T1delay();
}}
Void T1delay (void)
{
TMOD = 0x10;
TL1 = 0xFE;
TH1 = 0xA5;
TR1 = 1;
While (TF1 == 0);
TR1 = 0;
TF1 = 0;
}
Calculation:
FFFFH A5FEH = 23042 (decimal)
23042 * 1.085 s = 25ms and then 20 * 25ms = 500ms.

4. Write an 8051 C program to toggle only pin P1.5 continuously every 250ms. Use
Timer 0, mode 2 to create the delay.
Solution:
#include<reg51.h>
Void T0M2delay (void);
Sbit mybit = P1^5;
Void main (void)
{
Unsigned char x, y;
While (1)
{
mybit = ~mybit;
for (x = 0 ; x = 250 ; x++)
for ( y = 0; y = 36 ; y++ )
T0M2delay ();
}
}
Void T0M2delay (void)
{
TMOD = 0x02;
TH0 = -23;
TR0 = 1;
While (TF0 == 0);
TR0 = 0;
TF0 = 0;
}
Calculation:
256 23 = 233
23 * 1.085s = 25s and 25s * 250 * 40(36) = 250ms.
5. Write an 8051 C program to create a frequency of 2500Hz on pin P2.7. Use Timer 1,
mode 2 to create the delay.
Solution:
#include<reg51.h>
Void T1M2delay (void);
Sbit mybit = P2^7;
Void main (void)
{
Unsigned char x;
While (1)
{
mybit = ~mybit;
T1M2delay ();
}}

Void T1M2delay (void)


{
TMOD = 0x20;
TH1 = -184;
TR1 = 1;
While (TF1 == 0);
TR1 = 0;
TF1 = 0;
}
Calculation:
1/2500 = 400s
400s/2 = 200s
200s/1.085s = 184.
6. Assume that a 1 Hz external clock is being fed into pin T0 (P3.4). write a C program
for counter 0 in mode 1 to count the pulses and display the TH0 and TL0 registers on P2
and P1, respectively.
Solution:
#include<reg51.h>
Void main (void)
{
T0 = 1;
TMOD = 0x05;
TL0 = 0;
TH0 = 0;
While (1)
{
Do
{ TR0 = 1;
P1 = TL0;
P2 = TH0;
}
While (TF0==0);
TR0=0;
TF0=0;
}}
7. A switch is connected to pin P1.2 write an 8051 C program to monitor SW and
create the following frequencies on pin P1.7.
Solution:
#include<reg51.h>
Void T1M2delay (void);
Sbit mybit = P1^5;
Sbit SW=P1^7;

Void T0M1delay (unsigned char);


Void main (void)
{ SW = 1; while (1)
{
mybit = ~mybit;
if (SW==0)
T0M1delay (0);
Else
T0M1delay (1);
}}
Void T0M1delay (unsigned char C );
{ TNOD =0x01;
If (C==0)
{
TL0=0x67; TH0=0xFC;}
Else {
TL0=0x9A; TH0=0xFD; }
TR0=1;
While (TF0==0)
{
TR0=0; TF0=0; }
Calculation:
FC67H=64617
65536 64615 = 921
921 * 1.085s = 999.285 s.
1/999.285 s * 2 = 500Hz
8. Assume that a 2Hz external clock is being fed into pin T1 (P3.5). Write a C program
for counter 0 in mode 2 to display the count in ACII. The 8bit binary count must be
converted to ASCII. Display the ASCII digits on P0, P1 and P2 where P0 has the least
significant digit. Set the initial value of TH0 to 0.
Solution:
#include<reg51.h>
Void BintoASCII (unsigned char)
Void main (void)
{ unsigned char value;
T1 = 1;
TMOD = 0x06;
TH0 = 0;
While (1)
{
do
{ TR0 = 1;
value = TL0;
BintoASCII(value);

}
While (TF0==0);
TR0=0;
TF0=0;
}}
Void BintoASCII (unsigned char value)
{ unsigned char x,d1,d2,d3;
x = value/10;
d1 = value % 10;
d2 = x % 10;
d3 = x / 10 ;
P0 = 30 /d1; P1=30/d2; P2=30/d3 }
9. Assume that a 60Hz external clock is being fed into pin T0 (P3.4). write a C program
for counter 0 in mode 2 to display the seconds and minutes on P1 and P2, respectively.
Solution:
#include<reg51.h>
Void ToTime (unsigned char)
Void main (void)
{ unsigned char value;
T0 = 1;
TMOD = 0x06;
TH0 =-60;
While (1)
{
do
{ TR0 = 1;
sec = TL0;
ToTime (value);
}
While (TF0==0);
TR0=0;
TF0=0;
}}
Void ToTime (unsigned char value)
{ unsigned char sec, min;
min = value/60;
sec = value % 10;
P1=sec; P2=min; }

UNIT 6
8051 SERIAL COMMUNICATION
Basics of Serial Communication:
The fact that serial communication uses a single data line instead of the 8-bit data line of
parallel communication not only makes much cheaper but also enables two computers
located in two different cities to communicate over the telephone.
For serial communication to work, the byte of the data must be converted to serial bits
using a parallel to serial out shift register, and then it can be transmitted over a single data
line. This also means that receiving end must be a serial in parallel out shift register to
receive serial data and back them into a byte. Of course, if data is to be transferred on the
telephone line, it must be converted from 0s and 1s to audio signals. This conversion is
performed by a peripheral device called modem. This stands for modulator/demodulator.
Serial communication uses two methods, asynchronous and synchronous. The
Synchronous method transfers a block of data at a time, while the Asynchronous method
transfers a single byte at a time.
Simplex: if data is transmitted in one direction is referred to simplex.
Transmitter

Receiver

Half duplex: if data is transmitted one way at a time, it is referred to as half duplex.

Transmitter

Transmitter

Receiver

Receiver

Full Duplex: if the data can go both ways at the same time, it is full duplex.
Transmitter

Receiver

Receiver

Transmitter

Asynchronous serial communication and data framing:


The data coming in at the receiving end of the data in a serial data transfer is all 0s and
1s it is difficult to make sense of the data unless the sender and receiver agree on set of
rules, a protocol, on how the data is packed, how many bits constitute a character, and
when the data begin and ends.

Start and Stop bit:

Asynchronous serial communication is widely used for character-oriented transmissions,


while block-oriented data transfers use the synchronous method. In the asynchronous
method, each character is placed between start and stop bits. This is called framing. The
start bit is always one bit, but stop bit can be one or two bits. The start bit always Low 0
and stop bit is High 1
Data transfer Rate:
The rate of data transfer in serial data communication is stated in bps (bit per second).
Another widely used terminology for bps is baud rate.
Serial Data Input/Output
One of the features that make this microcontroller so powerful is an integrated UART,
better known as a serial port. It is a duplex port, which means that it can transmit and
receive data simultaneously. Without it, serial data sending and receiving would be
endlessly complicated part of the program where the pin state continuously is being
changed and checked according to strictly determined rhythm. Naturally, it does not
happen here because the UART resolves it in a very elegant manner. All the programmer
needs to do is to simply select serial port mode and baud rate. When the programmer is
such configured, serial data sending is done by writing to the register SBUF while data
receiving is done by reading the same register. The microcontroller takes care of all issues
necessary for not making any error during data exchange.

Serial port should be configured prior to being used. That determines how many bits one
serial word contains, what the baud rate is and what the pulse source for
synchronization is. All bits controlling this are stored in the SFR Register SCON (Serial
Control).
SCON Register (Serial Port Control Register)

SM0 - bit selects mode

SM1 - bit selects mode


SM2 - bit is used in case that several microcontrollers share the same interface. In
normal circumstances this bit must be cleared in order to enable connection to
function normally.
REN - bit enables data receiving via serial communication and must be set in
order to enable it.
TB8 - Since all registers in microcontroller are 8-bit registers, this bit solves the
problem of sending the 9th bit in modes 2 and 3. Simply, bits content is sent as the
9th bit.
RB8 - bit has the same purpose as the bit TB8 but this time on the receiver side.
This means that on receiving data in 9-bit format, the value of the last (ninth)
appears on its location.
TI - bit is automatically set at the moment the last bit of one byte is sent when the
USART operates as a transmitter. In that way processor knows that the line is
available for sending a new byte. Bit must be clear from within the program!
RI - bit is automatically set once one byte has been received. Everything
functions in the similar way as in the previous case but on the receive side. This is
line a doorbell which announces that a byte has been received via serial
communication. It should be read quickly prior to a new data takes its place. This
bit must also be also cleared from within the program.

As seen, serial port mode is selected by combining the bits SM0 and SM2:
SM0

SM1

Mode

Description

Baud Rate

8-bit Shift Register 1/12 the quartz frequency

8-bit UART

Determined by the timer 1

9-bit UART

1/32 the quartz frequency (1/64 the quartz


frequency)

9-bit UART

Determined by the timer 1

Programming the 8051 to transfer data serially:


In programming the 8051 to transfer character bytes serially, the following steps to be
taken.
1. The TMOD register is loaded with the value 20h, indicating the use of Timer 1 in
mode 2.
2. The TH1 is loaded the value which set the baud rate for serial data transfer.
3. The SCON register is loaded with the value 50H, indicating serial mode 1, where
8-bit data is framed with start and stop bits.
4. TR1 is set to 1 to start timer 1.

5. The character byte to be transferred serially is written into the SBUF register.
6. The TI flag bit is monitored with the use of the instruction JNB TI, xx to see if
the character has been transferred completely.
7. To transfer the next character, go to step 5.
Programming the 8051 to receive data serially:
In programming the 8051 to receive character bytes serially, the following steps to be
taken.
1. The TMOD register is loaded with the value 20h, indicating the use of Timer 1 in
mode 2.
2. The TH1 is loaded the value which set the baud rate for serial data transfer.
3. The SCON register is loaded with the value 50H, indicating serial mode 1, where
8-bit data is framed with start and stop bits and receive enable is turned on.
4. TR1 is set to 1 to start timer 1.
5. RI is cleared with the CLR RI instruction.
6. The RI flag bit is monitored with the use of the instruction JNB RI, xx to see if
the character has been received yet.
7. When RI is raised, SBUF has the byte. Its contents are moved into a safe place.
8. To receive the next character, go to step 5.
Examples:
3. Write a program to transfer a letter Y serially at 9600 baud
continuously and also to send a letter N through port 0 which is
connected to a display device.
Solution: MOV
MOV
MOV
SETB
AGAIN : MOV
HERE : JNB
CLR
MOV
SJMP

TMOD, #20H ; Timer 1, mode 2


TH1, #-3
; 9600 baud rate.
SCON, #50H ; 8-Bit, 1 stop bit, REN enabled.
TR1
; start Timer 1
SBUF, #Y ; transfer Y serially.
TI, HERE ; wait for transmission to be over.
TI
; Clear the TI for next
Transmission.
P0, #N
; move N to P0.
AGAIN
; Repeat.

2. Write a program to receive the data which has been sent in serial
form and send it out to port 0 in parallel form. Also save the data at
RAM location 60H.
Solution: MOV
MOV
MOV
SETB
CLR
HERE : JNB
MOV
MOV
MOV

TMOD, #20H ; Timer 1, mode 2


TH1, #-3
; 9600 baud rate.
SCON, #50H ; 8-Bit, 1 stop bit, REN enabled.
TR1
; start Timer 1
RI
; Clear the RI for reception
RI, HERE ; wait for character to come in
A, SBUF
; move received data into A
P0, A
; move it to P0.
60H, A
; move it to RAM location 60H.

Serial port Programming in C:


1. Write a C program for the 8051 to transfer the letter A serially at 4800 baud
continuously. Use 8-bit data and 1 stop bit.
Solution:
#include< reg51>
void main (void)
{
TMOD = 0x20;
TH1 = 0xFA;
SCON = 0x50;
TR1 = 1;
while (1)
{SBUF = A;
while (TI= = 0);
TI = 0;
}}
2. Write an 8051 C program to transfer the message YES serially at 9600 baud. 8-bit
data, 1 stop bit. Do this continuously.
Solution:
#include< reg51>
void sertx(unsigned char);
void main (void)

{
TMOD = 0x20;
TH1 = 0xFD;
SCON = 0x50;
TR1 = 1;
while (1)
{
Sertx(Y);
Sertx(E);
Sertx(S);
}}
void sertx(unsigned char x);
{
SBUF = x;
while (TI= = 0);
TI = 0;
}
3. Program the 8051 in C to receive bytes of data serially and put them in P1. set the baud
at 4800, 8-bit data and 1 stop bit.
Solution:
#include< reg51>
void main (void)
{
TMOD = 0x20;
TH1 = 0xFA;
SCON = 0x50;
TR1 = 1;
while (1)
{
while (RI= = 0);
mybyte = SBUF;
P1 = mybyte;
RI = 0;
}}
3. Write an 8051 C program to send two different strings to the serial port. Assuming that
SW connected to pin P2.0, monitor its status and make a decision as follows:
SW = 0; send your first name, SW = 1; send your last name. Assume XTAL =
11.0592MHz, baud rate of 9600, 8-bit data, 1stop bit.
Solution:
#include< reg51>
sbit mysw = P2^0;
void main (void)

{ unsigned char z;
unsigned char fname[] = sathish;
Unsigned char lname[] = .T
TMOD = 0x20;
TH1 = 0xFD;
SCON = 0x50;
TR1 = 1;
if (mysw = 0)
{
for (z = 0 ; z<7; z++)
{
SBUF = fname[z];
while (TI= = 0);
TI = 0;
}}
else
{
for (z = 0 ; z<2; z++)
{ SBUF = lname[z];
while (TI= = 0);
TI = 0;
}}}
4. Write an 8051 C Program to send the two messages Normal Speed and High speed
to the serial port. Assuming that SW is connected to pin P2.0, its status and the baud rate
as follows;
SW = 0 28800 baud rate, SW = 156K baud rate, Assume that XTAL = 11.0592 MHz for
both cases.
Solution:
#include< reg51>
sbit mysw = P2^0;
void main (void)
{ unsigned char z;
unsigned char mess1[] = Normal speed;
Unsigned char mess2[] = High speed ;
TMOD = 0x20;
TH1 = 0xFF;
SCON = 0x50;
TR1 = 1;
if (mysw = 0)
{
for (z = 0 ; z<12; z++)
{
SBUF = mess1[z];
while (TI= = 0);

TI = 0;
}}
else
{
PCON = PCON | 0x080;
for (z = 0 ; z<10; z++)
{ SBUF =mess2[z];
while (TI= = 0);
TI = 0;
}}}
Programming the second serial Port:
Many of the new generations of the 8051 microcontrollers come two serial ports. The
DS89C4x0 and DS80C320 are among them.
DS89C4x0 second serial port: the second serial port of the DS89C4x0 uses pins P1.2
and P1.3 for the Rx and Tx lines, respectively. Notice that the first and second serial ports
are designated as Serial #0 and Serial #1, respectively.
SFR Byte addresses for DS89C4x0 Serial ports
SFR

First serial Port

Second serial Port

SCON

SCON0 = 98H

SCON1= C0H

SBUF

SBUF0 = 99H

SBUF1 = C1H

TL

TL1 = 8BH

TL1 = 8BH

TH

TH1 = 8DH

TH1 = 8DH

TCON

TCON0 = 88H

TCON0 = 88H

PCON

PCON = 87H

PCON = 87H

5. Write a C program for the DS89C4x0 to transfer letter A serially at 4800 baud
continuously. Use the second serial port with 8-bit data and 1 stop bit. We can only use
timer 1 to set the baud rate.
Solution:
#include< reg51>
sfr SBUF1 = 0xC1;
sfr SCON1 = 0xC0;

sbit TI1 = 0xC1;


void main (void)
{
TMOD = 0x20;
TH1 = 0xFA;
SCON = 0x50;
TR1 = 1;
while (1)
{ SBUF1 = A;
while (TI1= = 0);
TI1 = 0;
}}
6. Write a C program for the DS89C4x0 to receive data via second serial port and put
them in P1.baud rate at 9600, 1 stop bit. We can only us8-bit data and 1 stop bit. Use
timer 1 for baud rate generation.
Solution:
#include< reg51>
sfr SBUF1 = 0xC1;
sfr SCON1 = 0xC0;
sbit RI1 = 0xC1;
void main (void)
{
Unsigned char mybyte;
TMOD = 0x20;
TH1 = 0xFD;
SCON = 0x50;
TR1 = 1;
while (1)
while (RI = = 0);
mybyte = SBUF1;
P2 = mybyte;
RI1 = 0;
}}