You are on page 1of 96

Embedded System:

An Embedded system can be defined as a computing device that can do a specific


focused job. Applications such as the air-conditioner, VCD player, DVD player, printer,
fax machine, mobile phone etc. are examples of embedded systems.

Each of these applications will have a processing unit and special hardware to meet
the specific requirements of the application along with the embedded software that is
executed by the processor for meeting that specific requirement of the job. The embedded
software is also called as "firmware".

In contrast the desktop/ laptop computer is general purpose computer. We can use
it for a variety of applications such as playing games, word processing, accounting,
software development and so on. Where as the software in the embedded systems are
always fixed.

Characteristics of Embedded Systems:


 Embedded systems do a very specific task; they can't be programmed to do
different things.
 Embedded systems have limited resources, particularly the memory. Generally,
they do not have secondary storage device such as the CDROM or the floppy
disk.
 Embedded systems have to work against some deadlines. A specific job has to
complete with in the specific time.
 Embedded systems are constrained for power. As many embedded systems
operate through a battery, the power consumption has to be very low.
 Embedded systems need to be highly reliable. Once in while, pressing
ALT+CRTL+DEL is ok in your desktops, but you can't afford to reset your
embedded system.
 Some embedded systems have to operate in the extreme environmental conditions
such as very high temperatures and humidity.

What is a Microcontroller?
A microcontroller (often abbreviated MCU) is a single computer chip (integrated
circuit) that executes a user program, normally for the purpose of controlling some
device. Hence the name “Microcontroller”.

The program is normally contained either in a second chip, called an EPROM, or


within the same chip as the microcontroller itself. A microcontroller is normally found in
devices such as microwave ovens, automobiles, keyboards, CD players, cell phones,
VCRs, security systems, time & attendance clocks, etc.

Microcontrollers are used in devices that require some amount of computing


power but don’t require as much computing power as that provided by a complex (and
expensive) 486 or Pentium system which generally requires a large amount of supporting
circuitry (large motherboards, hundreds of megabytes of RAM, hard drives, hard drive
controllers, video cards, etc). A microwave oven just does not need that much computing
power.

Microcontroller-based systems are generally smaller, more reliable, and cheaper.


They are ideal for the types of applications described above where cost and unit size are
very important considerations. In such applications it is almost always desirable to
produce circuits that require the smallest number of integrated circuits, that require the
smallest amount of physical space, require the least amount of energy, and cost as little as
possible.

Note: A Microcontroller is a small CPU with many support devices built into the single
chip. Self Contained (CPU, RAM, ROM, I/O pins, timers, interrupt sources, serial port,
A/D and D/A interfaces etc). A microcontroller is designed such that for an application or
Task Specific (Not a general-purpose computer).

Microprocessor verses. Microcontroller

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.

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

Criteria in Choosing a Microcontroller:


1. Meeting the computing needs of the task efficiently and cost effectively
• speed, the amount of ROM and RAM, the number of I/O ports and timers,
size, packaging, power consumption
• easy to upgrade
• cost per unit
2. Availability of software development tools
• assemblers, debuggers, C compilers, emulator, simulator, technical support
3. Wide availability and reliable sources of the microcontrollers.
Facts responsible for success of microcontrollers:

Their powerful, cleverly chosen electronics is able to control a variety of processes and
devices (industrial automatics, voltage, temperature, engines, etc) independently or by
means of I/O instruments such as switches, buttons, sensors, LCD screens, relays...etc

 Their low cost makes them suitable for installing in places which attracted no
such interest in the past. This is the fact accountable for today's market being
swamped with cheap automatons and "intelligent" toys.
 Writing and loading a program into microcontroller requires practically no
previous schooling. All that is required is: any PC (software is very friendly and
intuitive) and one simple device (programmer) for loading a written program into
microcontroller.

So if you are into electronics, you will undoubtedly want to master the great potential of
microcontrollers and put it to good use.

How does microcontroller work?

Although there are plenty of different microcontrollers and programs available, they all
share a lot in common between them. This means that if you master one model, you will
be able to handle them all eventually.

Typical scenario goes something like this:

1. Power is off and all is still... Program is loaded, everything is set, with no
indications of what is about to take place...
2. As soon as the power is on, it all happens too quickly to follow! First one to
register the change is the control logic. It halts all the circuits except the quartz
oscillator. First few milliseconds pass in hurried preparations and loading of
parasitic capacitances...
3. As voltage reaches its maximum, oscillator frequency stabilizes. SFR registers are
loaded with bits indicating the states of the subsystems, and all the pins are
designated as input. Impulse sequence starts dictating the pace and the electronics
is now fully operational. From this point on, time is measured in microseconds
and nanoseconds.
4. Program counter is reset to zero address of the program memory. Instruction is
sent from this address to the instruction decoder where it is interpreted and
executed promptly.
5. Program counter is incremented by one as the whole process plays out again...
(several millions of times per second)

Obviously, it all works at tremendous speeds, and is also pretty simple. But it would not
be especially useful if it was not for additional systems which round out the MCU:

Read Only Memory (ROM)

ROM is the memory which stores the program to be executed. Apparently, its size
dictates the maximal program length. It can be internal or external with respect to the
microcontroller. Both options have their pros and cons; external memory chip makes the
microcontroller cheaper and allows for longer programs. At the same time, number of
available free pins is reduced as external ROM uses MCU's I/O ports. Internal ROM is
usually smaller and more costly but it provides more possibilities for connecting to the
outside world. ROM spans from 512 bytes to 64kB, which is an equivalent to the number
of possible program instructions.

Random Access Memory (RAM)

RAM is used for temporary storage of data during runtime. RAM memory does not retain
its stored information when the power is interrupted. RAM spans from tens of bytes to
several kilobytes.

EEPROM Memory

EEPROM is a special kind of memory not available with all MCUs. Its contents can be
changed during runtime (as with RAM), but is also saved after the power is off (as with
ROM).

SFR Registers

Special Function Registers are special elements of RAM, their purpose predefined by the
manufacturer. Each of these registers is named and controls a certain subsystem of MCU.
For example: by writing zeros and ones to the SFR register which controls an I/O port,
each of these pins can be designated as input or output (each register bit corresponds to
one of the port pins).

Program Counter

This is the "engine" which starts the program and points to the memory address of the
instruction to be executed. Immediately upon its execution, the value of counter
increments by 1. Due to this automatic increase, program executes one instruction at a
time, just the way it was written. However... value of a counter can be changed anytime
with a "jump" to a new program memory location as a result. This is how routines and
branch instructions are carried out. Upon performing a jump to the specified destination,
Program Counter increase carries on steadily, +1, +1, +1...

Control Logic

As the name implies, this is the "Big Brother" which supervises and controls every aspect
of operations within MCU, and it cannot be manipulated. It comprises several parts, the
most important ones including:

 Instructions Decoder – part of the electronics which "recognizes" different


program instructions and directs the other circuits accordingly.
 Arithmetical Logical Unit (ALU) – is in charge of all mathematical and logical
operations over data. Capabilities of this circuit are represented through the so
called "instruction set" which is different for every MCU.
 Accumulator – a special SFR register highly interconnected with ALU. It can be
described as a working desk for performing operations on data (adding, shifting,
etc). Also, this is the register which holds the result of the operation. Of SFR
registers, Status Register is specifically associated with the accumulator. It
monitors the status of the accumulator's content at all times (is zero, is greater
than zero, etc).

Register

Register is a byte physically realized as electronic component, and represents a basic


memory cell. Beside the 8 bits available to the user, there is also an address part not
readily accessible.
 ROM and RAM registers are nameless and are usually peers.
 SFR registers are named (differently with different MCUs) and each has its role.

When writing a code for MCU in one of the higher programming languages, each register
can be given an arbitrary name, which proved to be useful.

I/O Ports

To be of any practical use, microcontroller needs to be connected to other electronics and


to the environs. For this purpose, every MCU has one or more registers (also known as
ports) which are connected to the pins on its case. Why I/O? Because every pin can be
designated as eiher input or output to suit user's needs.

Oscillator

This is the rhythm section of the miniature orchestra. Stable pace provided by this
instrument allows harmonious and synchronous functioning of all other parts of MCU.
Commonly, oscillator frequency is stabilized using a quartz-crystal or a ceramic
resonator. It can also work without an element for stabilizing frequency (as RC
oscillator). Note that instructions are executed at a rate several times slower than the pace
dictated by the oscillator. This happens because instructions take several steps to be
accomplished (execution period of different instructions may vary on different MCUs).
Therefore, if your system uses 20MHz quartz-crystal, execution period of one program
instruction will not be 50 ns, but more likely 200, 400 or” whole” 800 ns.

Timers

Majority of programs utilizes these miniature electronic "stopwatches". Commonly,


timers are 8 or 16-bit registers whose value automatically increases upon an impulse. If
timer is stimulated by an internal MCU oscillator, it can be used for measuring time
between two occurrences (register value at the start of measuring = T1, register value at
the end of measuring = T2, elapsed time = T2-T1). If timer is triggered by impulses from
an external source, instrument behaves like a counter.

In both cases, filling the register resets the counter and the occurrence is recorded in a
particular bit of SFR register (Overflow flag). This makes possible to measure longer
time periods. Also, if enabled, this flag can cause an interrupt for breaking the program
and carrying out a designated routine (see the image).

Watchdog Timer

The name itself implies the role of this instrument. It is a timer with input connected to an
independent MCU RC oscillator. If Watchdog is enabled, MCU is reset every time it
overflows, and the program execution starts anew (much as if the power had just been
turned on). The idea is to prevent that from happening by means of special instruction.
Whole concept is based upon a fact that every program technically "goes around", i.e.
executes within a number of simpler or more complex loops. If, beside the regular
instructions, key places in the program were added an instruction for resetting the
Watchdog, its safeguard function would pass unnoticed. If, for some reason, (in industrial
environment, electrical interference is common) Program Counter "gets stuck" at a
memory location with no return, the ever-increasing Watchdog Timer eventually
overflows and voila - MCU is reset.
A/D Converter

Another convenient instrument not available with all MCUs. Usually there are several
separate channels so that multiple analog values can be measured simultaneously.
Commonly, converters are 8, 10, or 12-bit and this is sufficient for most tasks.

Stack

Stack is a special part of RAM for storing the current value of Program Counter, so that
program could "know" where to pick up after the interrupt routine. It can be multi-
leveled, i.e. routines can be executed within other routines.

Power Supply Circuit

Two features of the MCU power supply circuit deserve your attention:

 Brown out – this is a potentially dangerous state which occurs during the
shutdown or in situations when voltage "oscillates" on the edge of the allowed
range due to strong interference. Since microcontroller comprises a number of
elements with various voltage ranges, this can cause their uncontrolled behavior.
To prevent this from happening, brown out reset circuit is included within MCU.
If voltage drops below the specified value for high-voltage elements of MCU,
brown out promptly resets the entire electronics.
 Reset pin – frequently marked as MCLR (Master Clear Reset) is used for
"external" reset of microcontroller by bringing the logical zero or one (depending
on the MCU). If not preinstalled, a simple external brown out reset circuit can be
connected to this pin.

What is 8051 and 8052?

Features of Intel 8051:

 4KB of Flash memory for storing the program.


 128 bytes of internal RAM for storing variables.
 32 I/O lines.
 Two 16-bit timers / counters.
 6 interrupt sources.
 Programmable UART serial communication.

Features of Intel 8052:

 8KB of Flash memory for storing the program.


 256 bytes of internal RAM for storing variables.
 32 I/O lines.
 Three 16-bit timers / counters.
 8 interrupt sources.
 Programmable UART serial communication.

Derivative Chips
Intel wisely licensed their MCU core to other semiconductor firms. This allowed
the architecture to become an industry-wide standard. Now, more than 20 years later,
dozens of semiconductor companies produce microcontrollers that are based on the
original 8051 and 8052 core. The term derivative chip, will refer to any 8051 or 8052-
compatible MCU that is produced by any semiconductor firm. There are currently
hundreds of derivative chips produced by dozens of semiconductor firms. A derivative
chip will generally (but not always) be able to execute a standard 8051 or 8052 program
without modification.

Major companies producing 8051 and 8052 controller derivatives:

Intel,
Atmel,
Philips,
Siemens,
Dallas,
National Semiconductors. etc
Block diagram and Pin configuration of 8051:

 1–8: Port 1; Each of these pins can be used as either input or output according to
your needs. Also, pins 1 and 2 (P1.0 and P1.1) have special functions associated
with Timer 2.
 9: Reset Signal; high logical state on this input halts the MCU and clears all the
registers. Bringing this pin back to logical state zero starts the program anew as if
the power had just been turned on. In another words, positive voltage impulse on
this pin resets the MCU. Depending on the device's purpose and environs, this pin
is usually connected to the push-button, reset-upon-start circuit or a brown out
reset circuit (covered in the previous chapter). The image shows one simple
circuit for safe reset upon starting the controller. It is utilized in situations when
power fails to reach its optimal voltage.
 10-17: Port 3; As with Port 1, each of these pins can be used as universal input or
output. However, each pin of Port 3 has an alternative function:
 Pin 10: RXD - serial input for asynchronous communication or serial
output for synchronous communication.
 Pin 11: TXD - serial output for asynchronous communication or clock
output for synchronous communication
 Pin 12: INT0 - input for interrupt 0
 Pin 13: INT1 - input for interrupt 1
 Pin 14: T0 - clock input of counter 0
 Pin 15: T1 - clock input of counter 1
 Pin 16: WR - signal for writing to external (add-on) RAM memory
 Pin 17: RD - signal for reading from external RAM memory
 18-19: X2 and X1; Input and output of internal oscillator. Quartz crystal
controlling the frequency commonly connects to these pins. Capacitances within
the oscillator mechanism (see the image) are not critical and are normally about
30pF. Instead of a quartz crystal, miniature ceramic resonators can be used for
dictating the pace. In that case, manufacturers recommend using somewhat higher
capacitances (about 47 pF). New MCUs work at frequencies from 0Hz to
50MHz+.
 20: GND; Ground
 21- 28: Port 2; If external memory is not present, pins of Port 2 act as universal
input/output. If external memory is present, this is the location of the higher
address byte, i.e. addresses A8 – A15. It is important to note that in cases when
not all the 8 bits are used for addressing the memory (i.e. memory is smaller than
64kB), the rest of the unused bits are not available as input/output.
 29: PSEN; MCU activates this bit (brings to low state) upon each reading of byte
(instruction) from program memory. If external ROM is used for storing the
program, PSEN is directly connected to its control pins.
 30: ALE; Before each reading of the external memory, MCU sends the lower
byte of the address register (addresses A0 – A7) to port P0 and activates the
output ALE. External register (74HCT373 or 74HCT375 circuits are common),
memorizes the state of port P0 upon receiving a signal from ALE pin, and uses it
as part of the address for memory chip. During the second part of the mechanical
MCU cycle, signal on ALE is off, and port P0 is used as Data Bus. In this way, by
adding only one cheap integrated circuit, data from port can be multiplexed and
the port simultaneously used for transferring both addresses and data.
 31: EA; Bringing this pin to the logical state zero (mass) designates the ports P2
and P3 for transferring addresses regardless of the presence of the internal
memory. This means that even if there is a program loaded in the MCU it will not
be executed, but the one from the external ROM will be used instead. Conversely,
bringing the pin to the high logical state causes the controller to use both
memories, first the internal, and then the external (if present).
 32-39: Port 0; Similar to Port 2, pins of Port 0 can be used as universal
input/output, if external memory is not used. If external memory is used, P0
behaves as address output (A0 – A7) when ALE pin is at high logical level, or as
data output (Data Bus) when ALE pin is at low logical level.
 40: VCC; Power +5V

Input – Output (I/O) Ports

Every MCU from 8051 family has 4 I/O ports of 8 bits each. This provides the user with
32 I/O lines for connecting MCU to the environs. Unlike the case with other controllers,
there is no specific SFR register for designating pins as input or output. Instead, the port
itself is in charge: 0=output, 1=input. If particular pin on the case is needed as output, the
appropriate bit of I/O port should be cleared. This will generate 0V on the specified
controller pin. Similarly, if particular pin on the case is needed as input, the appropriate
bit of I/O port should be set. This will designate the pin as input, generating +5V as a side
effect (as with every TTL input).

Port 0

Port 0 has two fold role: if external memory is used, it contains the lower address byte
(addresses A0-A7), otherwise all bits of the port are either input or output. Another
feature of this port comes to play when it has been designated as output. Unlike other
ports, Port 0 lacks the "pull up" resistor (resistor with +5V on one end). This seemingly
insignificant change has the following consequences:

 When designated as input, pin of Port 0 acts as high impedance offering the
infinite input resistance with no "inner" voltage.
 When designated as output, pin acts as "open drain". Clearing a port bit grounds
the appropriate pin on the case (0V). Setting a port bit makes the pin act as high
impedance. Therefore, to get positive logic (5V) at output, external "pull up"
resistor needs to be added for connecting the pin to the positive pole.

Therefore, to get one (5V) on the output, external "pull up" resistor needs to be added for
connecting the pin to the positive pole.
Port 1

This is "true" I/O port, devoid of dual function characteristic for Port 0. Having the "pull
up" resistor, Port 1 is fully compatible with TTL circuits.

Port 2

When using external memory, this port contains the higher address byte (addresses A8–
A15), similar to Port 0. Otherwise, it can be used as universal I/O port.

Port 3

Beside its role as universal I/O port, each pin of Port 3 has an alternate function. In order
to use one of these functions, the pin in question has to be designated as input, i.e. the
appropriate bit of register P3 needs to be set. From a hardware standpoint, Port 3 is
similar to Port 0.

Note: As can be seen from the individual descriptions of the ports, they all share highly
similar structure. However, you need to consider which task should be assigned to which
port. For example: if utilizing port as output with high level (5V), avoid using Port 0 as
its pins cannot produce high logical level without an additional resistor connected to
+5V(pull up resistors).

Memory

During the runtime, microcontroller uses two different types of memory: one for holding
the program being executed (ROM memory), and the other for temporary storage of data
and auxiliary variables (RAM memory). Depending on the particular model from 8051
family, this is usually few kilobytes of ROM and 128/256 bytes of RAM. This amount is
built-in and is sufficient for common tasks performed "independently" by the MCU.
However, 8051 can address up to 64KB of external memory. These can be separate
memory blocks, (separate RAM chip and ROM chip) totaling 128KB of memory on
MCU which is a real programming goody.

ROM memory

First models from 8051 family lacked the internal program memory, but it could be
added externally in a form of a separate chip. These MCUs can be recognized by their
mark which begins with 803 (e.g. 8031 or 8032). New models have built-in ROM,
although there are substantial variations. With some models internal memory cannot be
programmed directly by the user. Instead, the user needs to proceed the program to the
manufacturer, so that the MCU can be programmed (masked) appropriately in the process
of fabrication. Obviously, this option is cost-effective only for large series. Fortunately,
there are MCU models ideal for experimentation and small specialized series. Many
manufacturers deliver controllers that can be programmed directly by the user. These
come in a ceramic case with an opening (EPROM version) or in a plastic case without an
opening (EEPROM version). This book deals with one of the latter models that can be
programmed via simple programmer, even if the chip has already been mounted to the
designated device.

RAM memory

As previously stated, RAM is also called as Data memory used for storing temporary data
and auxiliary results generated during the runtime. Apart from that, RAM comprises a
number of registers: hardware counters and timers, I/O ports, buffer for serial connection,
etc. With older versions, RAM spanned 256 locations, while new models feature
additional 128 registers. First 256 memory locations form the basis of RAM (addresses 0
– FFh) of every 8051 MCU. Locations that are available to the user span addresses from
0 to 7Fh, i.e. first 128 registers, and this part of RAM is split into several blocks as can be
seen in the image below.
 First block comprises 4 "banks" of 8 registers each, marked as R0 - R7. To
address these, the parent bank has to be selected.
 Second memory block (range 20h – 2Fh) is bit-addressable, meaning that every
belonging bit has its own address (0 to 7Fh). Since the block comprises 16 of
these registers, there is a total of 128 addressable bits. (Bit 0 of byte 20h has bit
address 0, while bit 7 of byte 2Fh has bit address 7Fh).
 Third is the group of available registers at addresses 2Fh – 7Fh (total of 80
locations) without special features or a preset purpose.

Extra Memory Block

To satisfy the programmers' ever-increasing demands for RAM, latest 8051 models were
added an extra memory block of 128 locations. But it is not all that simple... The problem
lies in the fact that the electronics which addresses RAM employs 1 byte (8 bits),
reaching only the first 256 locations. Therefore, a little trick had to be applied in order to
keep the existing 8-bit architecture for the sake of compatibility with older models. The
idea is to make the additional memory block share the addresses with the existent
locations intended for SFR registers (80h - FFh). For distinguishing these two physically
separate memory areas, different methods of addressing are used: if SFR registers are in
question, direct addressing is used; for extra RAM locations, indirect addressing is used.

Memory Expanding

In case the built-in amount of memory (either RAM or ROM) is not sufficient for your
needs, there is always an option of adding two external 64KB memory chips. When
added, they are addressed and accessed via I/O ports P2 and P3. From user's point of
view it's all very simple, because if properly connected most of the job is carried out
automatically by MCU.

8051 MCU has two separate read signals, RD# (P3.7) and PSEN#. The first one is active
when reading byte from the external data memory (RAM), and the second one is active
when reading byte from the external program memory (ROM). Both signals are active on
low logical level. The following image shows a typical scheme for such expansion using
separate chips for RAM and ROM, known as Harvard architecture.
Memory can be also mapped as a single block, functioning as both data memory and
program memory simultaneously (only one memory chip is used). This approach is
known as Von Neumann architecture. To be able to read the same block using RD# or
PSEN#, these two signals were combined via logical AND. In this way, output of AND
circuit is low if any of the two inputs is low.

Using the Harvard architecture effectively doubles MCU memory, but


that's not the only advantage offered by the method. Keeping the
program code separated from the data makes the controller more
reliable since there is no writing to the program memory.
Although 8051 and 8052s contain a small amount of on-chip RAM and ROMs, External
RAM and ROMs are also supported.

As the name suggests, External RAM is any random access memory that is found
off-chip. Since the memory is off-chip the assembly language instructions to access it are
slower and less flexible. For example, to increment an Internal RAM location by 1
requires only 1 instruction and 1 instruction cycle. To increment a 1-byte value stored in
External RAM requires 4 instructions and 7 instruction cycles. In this case, external
memory is 7 times slower and requires 4 times as much program memory! What External
RAM loses in speed and flexibility it gains in quantity. While Internal RAM is normally
limited to 256 bytes in 8052 and 128 bytes with 8051s, the 8052 supports External RAM
and External ROM up to 64K bytes.

Programming Tip: Since memory is restricted to 64K, 8051 programs are limited to 64K.
Some compilers offer ways to get around this limit when used with specially wired
hardware and a technique known as memory banking. However, without such special
compilers and hardware, programs are limited to 64K.

Hardware Tip: Some manufacturers such as Dallas, Intel and Philips have special 8051
derivatives that can address several megabytes of memory

SFR Registers (Special Function Registers)

SFR registers can be seen as a sort of control panel for managing and monitoring the
microcontroller. Every register and each of the belonging bits has its name, specified
address in RAM and strictly defined role (e.g. controlling the timer, interrupt, serial
connection, etc). Although there are 128 available memory slots for allocating SFR
registers, the basic core shared by 8051 MCUs has but 22 registers. The rest has been left
open intentionally to allow future upgrades while retaining the compatibility with earlier
models. This fact makes possible to use programs developed for obsolete models long
ago.
Accumulator

Accumulator is a general purpose register which stores runtime results. Before


performing any operation upon an operand, operand has to be stored in the accumulator.
Results of arithmetical operations (performed by ALU) are also stored in the
accumulator. When transferring data from one register to another, it has to go through the
accumulator. Due to its versatile role, this is the most frequently used register, essential
part of every MCU.
"R" registers (R0 - R7)

Although not true SFR registers, "R" registers deserve to be mentioned at this point. They
are located within one of the 4 banks in RAM, and like the accumulator, serve for
temporary storage of variables and runtime results. Two bits of PSW register are in
command which bank will hold "R" registers.

Note: Since registers are called upon by the name during the writing of program,
programmer needs not to know their exact addresses. When compiled (translated into hex
code comprehensible to the controller), program will automatically replace register
names with the appropriate addresses.

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 implicitly by two 8052 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.
Other instructions can use this register as a secondary accumulator (A).

P0, P1, P2, P3 - I/O Ports

If external memory and system for serial communication are not used, user has 4 ports
(32 I/O lines) at disposal for communicating to the environs. Every port bit corresponds
to one of the pins on the casing, thus controlling the voltage on output (0 or 5V). Vice
versa, while reading, voltage on input pins is interpreted into bit logic on port. At the
same time, state of port bit designates the pin as input or output: zero for output, one for
input.

After reset, all port bits are set, designating all corresponding pins as input.
Stack Pointer (SP)

The number in Stack Pointer points to the location of the last "valid" address within the
Stack. With the beginning of every new routine, Stack Pointer increases by 1; upon return
from routine, SP decreases by 1. After reset (or turning the power on), this register
contains number 7, meaning that the amount of RAM allocated to Stack begins from this
memory location. If another value is written to SP, entire Stack moves to the new
specified location.

Program Status Word (PSW)

Program Status Word is one of the most important SFR registers, and is used for
managing program during the runtime. ALU automatically makes changes to certain bits
of this register.

 P (bit 0) - Parity bit. If numeral in accumulator is even, bit is automatically set


(1), otherwise it's cleared (0). It is commonly used in data transfers via serial
connection.
 - (bit 1) - This bit is intended for the upcoming MCU models and shouldn't be
used.
 OV (bit 2) - Overflow bit. If result of arithmetical operation exceeds 255
(decimal), OV is set (1), otherwise it's cleared (0).
 RS1, RS0 (bits 3 and 4) - Register select. Masking these bits stores registers R0 -
R7 into one of the 4 banks in RAM, according to the following table.

RS1 RS0 Location in RAM


0 0 Bank 0 00h-07h
0 1 Bank 1 08h-0Fh
1 0 Bank 2 10h-17h
1 1 Bank 3 18h-1Fh


 F0 (bit 5) - Flag 0. An all-purpose flag.
 AC (bit 6) - Auxiliary Carry Flag, used only for operations with BCD (Binary
Coded Decimals).
 CY (bit 7) - Carry Flag. Auxiliary (ninth) bit for arithmetical and shift
operations.

Data Pointer

Data Pointer actually consists of two registers: DPH (Data Pointer High) and DPL (Data
Pointer Low). Data Pointer's 16 bits are used for addressing external memory. Since this
is the only 16-bit register available to programmer, it is commonly used for temporary
storage of data and runtime results not related to memory locations.

The Stack
The stack is a last in, first out (LIFO). Storage area that exists in Internal RAM. It is used
by the 8052 to store values that the user program manually pushes onto the stack as well
as to store the return addresses for CALLs and interrupt service routines (more on these
topics later). The stack is defined and controlled by a Special Function Register called the
Stack Pointer, or SP. SP, as a standard 8-bit SFR, holds a value between 0 and 255 that
represents the Internal RAM address of the end of the current stack. If a value is removed
from the stack, it will be taken from the Internal RAM address pointed to by SP and SP
will subsequently be decremented by 1. If a value is pushed onto the stack, SP will first
be incremented and then the value will be inserted in Internal RAM at the address now
pointed to by SP. SP is initialized to 07h when an 8052 is first booted. This means the
first value to be pushed onto the stack will be placed at Internal RAM address 08h (07h +
1), the second will be placed at 09h, etc.

Programming Tip: By default, the 8052 initializes the Stack Pointer (SP) to 07h when the
microcontroller is booted. This means that the stack will start at address 08h and expand
upwards. If you will be using the alternate register banks (banks 1, 2 or 3) you must
initialize the stack pointer to an address above the highest register bank you will be using,
otherwise the stack will overwrite your alternate register banks. Similarly, if you will be
using bit variables it is usually a good idea to initialize the stack pointer to some value
greater than 2Fh to guarantee that your bit variables are protected from the stack. We will
talk about the register banks and Bit Memory below.

2.3.1.3 Register Banks


The 8052 uses 8 "R" registers which are used in many of its instructions. These "R"
registers are numbered from 0 through 7 (R0, R1, R2, R3, R4, R5, R6, and R7) and are
generally used to assist in manipulating values and moving data from one memory
location to another. For example, to add the value of R4 to the Accumulator, we would
execute the following assembly language instruction:

ADD A,R4

Thus if the Accumulator (A) contained the value 6 and R4 contained the value 3, the
Accumulator would contain the value 9 after this instruction was executed. However, as
the memory map shows, the "R" Register R4 is really part of Internal RAM. Specifically,
R4 is address 04h of Internal RAM. This can be seen in the bright green section of the
memory map. Thus the above instruction accomplishes the same thing as the following
operation:

ADD A,04H

This instruction adds the value found in Internal RAM address 04h to the value of the
Accumulator, leaving the result in the Accumulator. Since R4 is really Internal RAM
address 04h, the above instruction effectively accomplishes the same thing as the
previous ADD instruction.
But watch out! As the memory map shows, the 8052 has four distinct register banks.
When the 8052 is first booted up register bank 0 (addresses 00h through 07h) is used by
default. However, your program

may instruct the 8052 to use one of the alternate register banks; i.e., register banks 1, 2, or
3. In this case, R4 will no longer be the same as Internal RAM address 04h. For example,
if your program instructs the 8052 to use register bank 1, register R4 will now be
synonymous with Internal RAM address 0Ch. If you select register bank 2, R4 is
synonymous with 14h, and if you select register bank 3 it is synonymous with address
1Ch. Setting or clearing the bits RS0 and RS1 in the Program Status Word (PSW) Special
Function Register selects the register bank. For example:
MOV PSW,#00H ; sets register bank 0
MOV PSW,#08H ; sets register bank 1
MOV PSW,#10H ; sets register bank 2
MOV PSW,#18H ; sets register bank 3

The above instructions will make more sense after we cover the topics of Special
Function Registers. The concept of register banks adds a great level of flexibility to the
8052, especially when dealing with interrupts (we'll talk about interrupts later). However,
always remember that the register banks really reside in the first 32 bytes of Internal
RAM.

Programming Tip: If you only use the first register bank (i.e. bank 0), you may use
Internal RAM locations 08h through 1Fh for your own use. If you plan to use register
banks 1, 2, or 3, be very careful about using addresses below 20h as you may end up
overwriting the value of "R" registers from other register banks.
Bit Memory
The 8052, being a communications and control-oriented microcontroller that often has to
deal with “ON” and “off” situations, gives the developer the ability to access a number of
bit variables directly with simple instructions to set, clear, and compare these bits. These
variables may be either 1 or 0. There are 128 bit variables available to the developer,
numbered 00h through 7Fh. The developer may make use of these variables with
commands such as SETB and CLR. For example, to set bit number 24h(hex) to 1 you
would execute the instruction:

SETB 24H

It is important to note that Bit Memory, like the Register Banks above, is really a part of
Internal RAM. Infact, the 128 bit variables occupy the 16 bytes of Internal RAM from
20h through 2Fh. Thus, if you write the value FFh to Internal RAM address 20h you’ve
effectively set bits 00h through 07h. That is to say that the instruction:

MOV 20H,#0FFH

is equivalent to the instructions:

SETB 00H
SETB 01H
SETB 02H
SETB 03H
SETB 04H
SETB 05H
SETB 06H
SETB 07H
As illustrated above, Bit Memory isn’t really a new type of memory. It’s really just a
subset of Internal RAM. Since the 8052 provide special instructions to access these 16
bytes of memory on a bit-by-bit basis it is useful to think of it as a separate type of
memory. But always keep in mind that it is just a subset of Internal RAM--and that
operations performed on Internal RAM can change the values of the bit variables.

Programming Tip: If your program does not use bit variables you may use Internal RAM
locations 20h through 2Fh for your own use. If you plan to use bit variables be very
careful about using addresses from 20h through 2Fh as you may end up overwriting the
value of your bits.

Programming Tip: By default, the 8052 initialize the Stack Pointer (SP) to 07h when the
microcontroller is booted. This means that the stack will start at address 08h and expand
upwards. If you will be using the alternate register banks (banks 1, 2 or 3) you must
initialize the stack pointer to an address above the highest register bank you will be using,
otherwise the stack will overwrite your alternate register banks. Similarly, if you will be
using bit variables it is usually a good idea to initialize the stack pointer to some value
greater than 2Fh to guarantee that your bit variables are protected from the stack.

While Bit Memory 00h through 7Fh are for developer-defined functions in their
programs, Bit Memory 80h and above are used to access certain SFRs (see below) on a
bit-by-bit basis. For example, if output lines P0.0 through P0.7 are all clear (0) and you
want to turn on the P0.1 output line you may either execute:
MOV P0,#02H

or you may execute:

SETB 81H

Both of these instructions accomplish the same thing. However, using the SETB
command will turn on the P0.0 line without affecting the status of any of the other P0
output lines. The MOV command effectively turns off all the other output lines which, in
some cases, may not be acceptable. When dealing with bit addresses of 80h and above
remember that the bits refer to the bits of corresponding SFRs that are divisible by 8. This
is a complicated way of saying that bits 80h through 87h refer to bits 0 through 7 of SFR
80h. Bits 88h through 8Fh refer to bits 0 through 7 of SFR 88h. Bits 90h through 97F
refer to bits 0 through 7 of 90h, etc.

2.3.2 Special Function Register (SFR) Memory


Special Function Registers (SFRs) are areas of memory that control specific functionality
of the 8052 MCU. For example, four SFRs permit access to the 8052.s 32 input/output
lines (8 lines per SFR). Another SFR allows a program to read or write to the 8052.s
serial port. Other SFRs allow the user to set the serial baud rate, control and access
timers, and configure the 8052.s interrupt system. When programming, SFRs have the
illusion of being Internal Memory. For example, if you want to write the value "1" to
Internal RAM location 50h you would execute the instruction:

MOV 50H,#01H

Similarly, if you want to write the value "1" to the 8052.s serial port you would write this
value to the SBUF SFR, which has an SFR address of 99 Hex. Thus, to write the value
"1" to the serial port you would execute the instruction:

MOV 99H,#01H

As you can see, it appears as if the SFR is part of Internal Memory. This is not the case.
When using this method of memory access (it’s called. direct address. more on that
soon), any instruction that has an address of 00h through 7Fh refers to an Internal RAM
memory address; any instruction with an address of 80h through FFh refers to an SFR
control register.

Programming Tip #1: SFRs are used to control the way the 8052 functions. Each SFR has
a specific purpose and format that will be discussed later. Not all addresses above 80h are
assigned to SFRs. However, this area may NOT be used as additional RAM memory
even if a given address has not been assigned to an SFR.

Programming Tip #2: Since direct access to addresses 80h through FFh refers to SFRs,
direct access cannot be used to access Internal RAM addresses 80h through FFh. The
upper 128 bytes of Internal RAM must be accessed using. Indirect Addressing. Which
will be explained in a subsequent chapter.

Special Function Registers (SFRs)


The 8052 is a flexible microcontroller with a relatively large number of modes of
operation. Your program may inspect and/or change the operating mode of the 8052 by
manipulating the values of the Special Function Registers (SFRs).

SFRs are accessed as if they were normal Internal RAM. The only difference is that
Internal RAM is addressed in direct mode. with addresses 00h through 7Fh whereas SFR
registers are accessed in the range of 80h through FFh. Each SFR has an address (80h
through FFh) and a name. The following chart provides a graphical presentation of the
8052's SFRs, their names, and their address.

As you can see, although the address range of 80h through FFh offers 128 possible
addresses, there are only 26 SFRs in a standard 8052 (21 with an 8051). All other
addresses in the SFR range (80h through FFh) are considered invalid. Writing to or
reading from these registers may produce undefined values or behavior.
Programming Tip: It is recommended that you not read or write to SFR addresses that
have not been assigned to an SFR. Doing so may provoke undefined behavior and may
cause your program to be incompatible with other 8052-derivatives that use the given
SFR for some other purpose.

8051 Addressing Modes

Immediate Addressing:
In this addressing mode, a constant value is specified in the instruction itself. The
“#” symbol precedes the constant values in the assembly instructions. The constants can
be decimal numbers, hexadecimal numbers, binary numbers or characters.
1. Hexadecimal numbers are written with “H” suffix (e.g. 3AH). Moreover, a
hexadecimal number must start with a digit. If not, put a leading 0. For example,
if the hexadecimal number that you want to specify is D3H, then you have to
write it in a program as 0D3H.

Example: MOV A, #D3H ; Invalid


MOV A, #0D3H ; valid

2. Binary numbers are written with a “B” suffix (e.g. 01000101B).

Example: MOV A, #01000101B

3. Decimal numbers do not require any suffix.

Example: MOV A, #100 ; loads the Accumulator


With the decimal number 100

4. Characters must be written between double quotation marks (e.g. "Z"). Actually,
the ASCII code of the character is processed here.

Example: MOV a, #”Z”

Register Addressing:
The register banks, containing registers R0 through R7, can be accessed by certain
instructions that carry a 3-bit register specification within the opcode of the instruction.
Instructions that access the registers this way are code efficient, since this mode
eliminates an address byte. When the instruction is executed, one of the eight registers in
the selected bank is accessed.

Example: ADD A, R5 ; add the content of R5 to accumulator


Direct Addressing:
In direct addressing the operand is specified by an 8-bit address field in the
instruction. Only internal data memory (including SFRs) can be directly addressed.
Examples:MOV A, 30H ; move the content of internal data memory
Address 66H to acc
ADD A, B ;add the content of the B register to acc

In the latter example the address of the B register (F0) register is actually used in the
encoded form.

Indirect Addressing:
In indirect addressing the instruction specifies a register which contains the
address of the operand. Both internal and external data memory can be indirectly
addressed (SFRs are not indirectly addressed). The address register for 8-bit addresses
can only be R0 or R1 of the selected bank. The “@” symbol is used before the register is
to specify the indirect addressing mode in instructions. The address register for 16-bit
addresses can only be the 16-bit “data pointer” register, DPTR (this is not the case in
labs).

Example:
MOV A,@R0 ;move the content of internal data memory
location whose address is in register R0.

Q) Write an ALP to fill 10 successive locations Starting at 40h with decimal numbers 0
to 9.

Start: CLR A ; Initialize ACC to zero


MOV R0,#40H ; assign a pointer to mem location 40h
MOV R2,#10 ; load counter
loop: MOV @R0,A ; move ACC into mem location
INC A ; Increment ACC
INC R0 ; Increment RO to point to next address
DJNZ R2, loop

Programming Tip: Technically, accessing external memory with the MOVX @DPTR
instruction is indirect addressing since the address to be accessed is referred to indirectly
by the DPTR register. However, to directly access a specific external RAM memory
location the most direct way is to load DPTR with the address in question and access it
with the MOVX instruction. Thus while this approach is technically "indirect," I called it
"External Direct" since it is the most direct method of accessing a specific external RAM
memory location and to differentiate it from the following addressing mode (External
Indirect) which is very similar to the "indirect addressing"

Indexed addressing mode:


Indexed addressing mode is widely used in accessing data elements of
lookup tables entries located in the program ROM space of the 8051.The instruction used
for this is MOVC A,@A+DPTR. The 16-bit register DPTR and register A are used to
form the address of the data element stored in on-chip ROM. Because the data elements
are stored in the program space Rom of the 8051, it uses the instruction MOVC instead of
MOV. The “C” means code. In this instruction the contents of A are added to the 16 bit
register DPTR to form 16-bit address of the needed data.

Write a program to access the string THUNDER which is stored at ROM


locations starting from 200hand also store the result at RAM locations starting from 40h.

org 0000h
start: mov dptr,#MSG
mov r0,#40h
mov r2,#7
loop: clr a
movc a,@A+dptr
mov @r0,a
inc DPTR
inc r0
djnz r2,loop
nop

org 0200h
MSG: DB 'THUNDER'

We start with DPTR = 200H, and A = 0. The instruction “MOVC A,@A+DPTR” moves
the contents of ROM location 200H (200H + 0 = 200H ) to register A. Register A
contains the ASCII value for “T”. This is moved to 40H location. Next, the DPTR is
incremented to make DPTR = 201. Accumulator is set to 0 again to get contents of the
next ROM location 201H, which holds the ASCII value of “H” and it is moved into the
location 41H. After the program execution is completed we have the characters of the
string starting from 40H.

NOTE: Register-Specific Instructions. Some instructions are specific to a certain


register. For example, some instructions always operate on the Accumulator, so no
address byte is needed to point to it. The opcode itself does that. Instructions that refer to
the Accumulator as A resembles an accumulator specific opcodes.

Example: CPL A ; Complement accumulator


8052 Instruction Set

Definitions:
Instruction: Indicates the correct syntax for the given opcode.
OpCode: The operation code, in the range of 0x00 through 0xFF, that represents the
given instruction in machine code.
Bytes: The total number of bytes (including the opcode byte) that make up the
instruction.
Cycles: The number of machine cycles required to execute the instruction.

Some notations:
bitAddr: Bit address value (00-FF)
data8: Immediate 8-bit data value
data16: Immedate 16-bit data value
address16: 16-bit code address
direct: Direct address (IRAM 00-7F, SFR 80-FF)
relAddr: Relative address (-127 to +128 bytes)

ACALL . Absolute Call within 2k Block


Syntax: ACALL codeAddress
ACALL unconditionally calls a subroutine at the indicated code address. ACALL pushes
the address of the instruction that follows ACALL onto the stack, least-significant-byte
first, most-significant-byte second. The Program Counter is then updated so that program
execution continues at the indicated address.

The new value for the Program Counter is calculated by replacing the least-significant-
byte of the Program Counter with the second byte of the ACALL instruction, and
replacing bits 0-2 of the most-significantbyte of the Program Counter with bits 5-7 of the
opcode value. Bits 3-7 of the most-significant-byte of the Program Counter remain
unchaged. Since only 11 bits of the Program Counter are affected by ACALL, calls may
only be made to routines located within the same 2k block as the first byte that follows
ACALL.

ADD, ADDC . Add Value, Add Value with Carry


Syntax: ADD A,operand
Syntax: ADDC A,operand
ADD and ADDC both add the value operand to the value of the Accumulator, leaving the
resulting value in the Accumulator. The value operand is not affected. ADD and ADDC
function identically except that ADDC adds the value of operand as well as the value of
the Carry flag whereas ADD does not add the Carry flag to the result. The Carry bit (C) is
set if there is a carry-out of bit 7. In other words, if the unsigned summed value of the
Accumulator, operand and (in the case of ADDC) the Carry flag exceeds 255 Carry is set.
Otherwise, the Carry bit is cleared.
The Auxillary Carry (AC) bit is set if there is a carry-out of bit 3. In other words, if the
unsigned summed value of the low nibble of the Accumulator, operand and (in the case
of ADDC) the Carry flag exceeds 15 the Auxillary Carry flag is set. Otherwise, the
Auxillary Carry flag is cleared. The Overflow (OV) bit is set if there is a carry-out of bit
6 or out of bit 7, but not both. In other words, if the addition of the Accumulator, operand
and (in the case of ADDC) the Carry flag treated as signed values results in a value that is
out of the range of a signed byte (-128 through +127) the Overflow flag is set. Otherwise,
the Overflow flag is cleared.

AJMP . Absolute Jump within 2k Block


Syntax: AJMP codeAddress
AJMP unconditionally jumps to the indicated codeAddress. The new value for the
Program Counter is calculated by replacing the least-significant-byte of the Program
Counter with the second byte of the AJMP instruction, and replacing bits 0-2 of the most-
significant-byte of the Program Counter with bits 5-7of the opcode value. Bits 3-7 of the
most-significant-byte of the Program Counter remain unchaged. Since only 11 bits of the
Program Counter are affected by AJMP, jumps may only be made to code located within
the same 2k block as the first byte that follows AJMP.

ANL . Bitwise AND


Syntax: ANL operand1,operand2
ANL does a bitwise "AND" operation between operand1 and operand2, leaving the
resulting value in operand1. The value of operand2 is not affected. A logical "AND"
compares the bits of each operand and sets the corresponding bit in the resulting byte
only if the bit was set in both of the original operands, otherwise the resulting bit is
cleared.

CJNE . Compare and Jump if Not Equal


Syntax: CJNE operand1,operand2,reladdr
CJNE compares the value of operand1 and operand2 and branches to the indicated
relative address if the two operands are not equal. If the two operands are equal program
flow continues with the instruction following the CJNE instruction.
The Carry bit (C) is set if operand1 is less than operand2, otherwise it is cleared.

CLR . Clear Register


Syntax: CLR register
CLR clears (sets to 0) all the bit(s) of the indicated register. If the register is a bit
(including the carry bit), only the specified bit is affected. Clearing the accumulator sets
the Accumulator.s value to 0.

CPL . Complement Register


Syntax: CPL operand
CPL complements operand, leaving the result in operand. If operand is a single bit then
the state of the bit will be reversed. If operand is the Accumulator then all the bits in the
Accumulator will be reversed. This can be thought of as "Accumulator Logical Exclusive
OR 255" or as "255-Accumulator." If operand refers to a bit of an output port, the value
that will be complemented is based on the last value written to that bit, not the last value
read from it.
DA . Decimal Adjust Accumulator
Syntax: DA A
DA adjusts the contents of the Accumulator to correspond to a BCD (Binary Coded
Decimal) number after two BCD numbers have been added by the ADD or ADDC
instruction. If the carry bit is set or if the value of bits 0-3 exceed 9, 0x06 is added to the
accumulator. If the carry bit was set when the instruction began, or if 0x06 was added to
the accumulator in the first step, 0x60 is added to the accumulator. The Carry bit (C) is
set if the resulting value is greater than 0x99, otherwise it is cleared.

DEC . Decrement Register


Syntax: DEC register
DEC decrements the value of register by 1. If the initial value of register is 0,
decrementing the value will cause it to reset to 255 (0xFF Hex). Note: The Carry Flag is
not set when the value "rolls over" from 0 to 255.

DIV . Divide Accumulator by B


Syntax: DIV AB
Divides the unsigned value of the Accumulator by the unsigned value of the "B" register.
The resulting quotient is placed in the Accumulator and the remainder is placed in the
"B" register. The Carry flag (C) is always cleared. The Overflow flag (OV) is set if
division by 0 was attempted, otherwise it is cleared.

DJNZ . Decrement and Jump if Not Zero


Syntax: DJNZ register,relAddr
DJNZ decrements the value of register by 1. If the initial value of register is 0,
decrementing the value will cause it to reset to 255 (0xFF Hex). If the new value of
register is not 0 the program will branch to the address indicated by relAddr. If the new
value of register is 0, program flow continues with the instruction following the DJNZ
instruction.

INC . Increment Reister


Syntax: INC register
INC increments the value of register by 1. If the initial value of register is 255 (0xFF
Hex), incrementing the value will cause it to reset to 0. Note: The Carry Flag is not set
when the value "rolls over" from 255 to 0.
In the case of "INC DPTR", the two-byte value of DPTR is incremented as an unsigned
integer. If the initial value of DPTR is 65535 (0xFFFF Hex), incrementing the value will
cause it to reset to 0. Again, the Carry Flag is not set when the value of DPTR "rolls
over" from 65535 to 0.

JB . Jump if Bit Se t
Syntax: JB bitAddr,relAddr
JB branches to the address indicated by relAddr if the bit indicated by bitAddr is set. If
the bit is not set program execution continues with the instruction following the JB
instruction.
JBC . Jump if Bit Set and Clear Bit
Syntax: JBC bitAddr,relAddr
JBC will branch to the address indicated by relAddr if the bit indicated by bitAddr is set.
Before branching to relAddr the instruction will clear the indicated bit. If the bit is not set
program execution continues with the instruction following the JBC instruction and the
value of the bit is not changed.

JC . Jump if Carry Se t
Syntax: JC relAddr
JC will branch to the address indicated by relAddr if the Carry Bit is set. If the Carry Bit
is not set program execution continues with the instruction following the JC instruction.

JMP . Jump to Data Pointer + Accumulator


Syntax: JMP @A+DPTR
JMP jumps unconditionally to the address represented by the sum of the value of DPTR
and the value ofthe Accumulator.

JNB . Jump if Bit Not Set


Syntax: JNB bitAddr,reladdr
JNB will branch to the address indicated by relAddr if the indicated bit is not set. If the
bit is set program execution continues with the instruction following the JNB instruction.

JNC . Jump if Carry Not Set


Syntax: JNC reladdr
JNC branches to the address indicated by relAddr if the carry bit is not set. If the carry bit
is set program execution continues with the instruction following the JNB instruction.

JNZ . Jump if Accumulator Not Zero


Syntax: JNZ reladdr
JNZ will branch to the address indicated by relAddr if the Accumulator contains any
value except 0. If the value of the Accumulator is zero program execution continues with
the instruction following the JNZ instruction.

JZ . Jump if Accumulator Zero


Syntax: JZ reladdr
JZ branches to the address indicated by relAddr if the Accumulator contains the value 0.
If the value of the Accumulator is non-zero program execution continues with the
instruction following the JNZ instruction.

LCALL . Long Cal l


Syntax: LCALL address16
LCALL calls a program subroutine. LCALL increments the program counter by 3 (to
point to the instruction following LCALL) and pushes that value onto the stack , low-byte
first, high-byte second. The Program Counter is then set to the 16-bit value address16,
causing program execution to continue at that address.
LJMP . Long Jump
Syntax: LJMP address16
LJMP jumps unconditionally to the specified address16.

MOV . Move Memory into/out of Accumulator


Syntax: MOV operand1, operand2
MOV copies the value of operand2 into operand1. The value of operand2 is not affected.

MOV . Move into/out of Carry Bit


Syntax: MOV bit1,bit2
MOV copies the value of bit2 into bit1. The value of bit2 is not affected. Either bit1 or
bit2 must refer to the Carry bit.

MOV . Move into/out of Internal RAM


Syntax: MOV operand1,operand2
operand1. The value of operand2 is not affected.

NOTE: In the case of "MOV direct1,direct2 ", the operand bytes of the instruction are
stored in reverse order. That is, the instruction consisting of the bytes 85h, 20h, 50h
means "Move the contents of Internal RAM location 0x20 to Internal RAM location
0x50" whereas the opposite would be generally presumed.

MOV DPTR . Move value into DPTR


Syntax: MOV DPTR,#data16
Instructions OpCode Bytes Cycles Flags
MOV DPTR,#data16 0x90 3 2 None
Sets the value of the Data Pointer (DPTR) to the value data16.

MOVC . Move Code Byte to Accumulator


Syntax: MOVC A,@A+register
MOVC moves a byte from code memory into the Accumulator. The code memory
address from which the byte will be moved is calculated by summing the value of the
Accumulator with either DPTR or the Program Counter (PC). In the case of the Program
Counter, PC is first incremented by 1 before being summed with the Accumulator.

MOVX . Move Data to/from External RAM


Syntax: MOVX operand1,operand2
MOVX moves a byte to or from external memory into or from the Accumulator.
If operand1 is @DPTR, the Accumulator is moved to the 16-bit External Memory
address indicated by DPTR. This instruction uses both P0 (port 0) and P2 (port 2) to
output the 16-bit address and data. If operand2 is DPTR then the byte is moved from
external memory into the Accumulator. If operand1 is @R0 or @R1, the Accumulator is
moved to the 8-bit external memory address indicated by the specified register. This
instruction uses only P0 (port 0) to output the 8-bit address and data. P2 (port 2) is not
affected. If operand2 is @R0 or @R1 then the byte is moved from external memory into
the Accumulator.
MUL . Multiply Accumulator by B
Syntax: MUL AB
Multiplies the unsigned value in the Accumulator by the unsigned value in the "B"
register. The leastsignificant byte of the result is placed in the Accumulator and the most-
significant-byte is placed in the "B" register. The Carry Flag (C) is always cleared. The
Overflow Flag (OV) is set if the result is greater than 255 (if the most-significant byte is
not zero), otherwise it is cleared.

NOP . No Operation
Syntax: NOP
NOP, as it.s name suggests, causes no operation to take place for one machine cycle.
NOP is generally used only for timing purposes. Absolutely no flags or registers are
affected.

ORL . Bitwise OR
Syntax: ORL operand1,operand2
ORL does a bitwise "OR" operation between operand1 and operand2, leaving the
resulting value in operand1. The value of operand2 is not affected. A logical "OR"
compares the bits of each operand and sets the corresponding bit in the resulting byte if
the bit was set in either of the original operands, otherwise the resulting bit is cleared.

POP . Pop Value from Stack


Syntax: POP register

POP "pops" the last value placed on the stack into the direct address specified. In other
words, POP will load direct with the value of the Internal RAM address pointed to by the
current Stack Pointer. The stack pointer is then decremented by 1.

NOTE #1: The address of direct must be an Internal RAM or SFR address. You cannot
POP directly into .R. registers, such as R0, R1, etc. To pop a value off the stack into R0,
for example, you must pop the value into the accumulator and then move the value of the
accumulator into R0. NOTE #2: When popping a value off the stack into the
Accumulator, you must code the instruction as POP ACC, not POP A. The latter is
invalid and will result in an error at assembletime.

PUSH . Push Value onto Stack


Syntax: PUSH register
PUSH "pushes" the value of the specified direct address onto the stack. PUSH first
increments the value of the Stack Pointer by 1, then takes the value stored in direct and
stores it in internal RAM at the location pointed to by the incremented Stack Pointer.

NOTE #1: The address of direct must be an Internal RAM or SFR address. You cannot
PUSH directly from .R. registers, such as R0, R1, etc. To push a value onto the stack
from R0, for example, you must move R0 into the accumulator, then PUSH the value of
the accumulator onto the stack.
NOTE #2: When pushing a value from the accumulator onto the stack into the, you must
code the instruction as PUSH ACC, not PUSH A. The latter is invalid and will result in
an error at assemble-time.

RET . Return from Subroutine


Syntax: RET
RET is used to return from a subroutine previously called by LCALL or ACALL.
Program execution continues at the address that is calculated by popping the top-most 2
bytes off the stack. The mostsignificant- byte is popped off the stack first, followed by
the least-significant-byte.

RETI . Return from Interrupt


Syntax: RETI
RETI is used to return from an interrupt service routine. RETI first enables interrupts of
equal and lower priorities to the interrupt that is terminating. Program execution
continues at the address that is calculated by popping the top-most 2 bytes off the stack.
The most-significant-byte is popped off the stack first,
followed by the least-significant-byte. RETI functions identically to RET if it is executed
outside of an interrupt service routine.

RL . Rotate Accumulator Left


Syntax: RL A
Shifts the bits of the accumulator to the left. The left-most bit (bit 7) of the Accumulator
is loaded into bit0.

RLC . Rotate Accumulator Left Through Carry


Syntax: RLC A
Shifts the bits of the accumulator to the left. The left-most bit (bit 7) of the accumulator is
loaded into the Carry Flag, and the original Carry Flag is loaded into bit 0 of the
Accumulator.

RR . Rotate Accumulator Righ t


Syntax: RR A
Shifts the bits of the accumulator to the right. The right-most bit (bit 0) of the
accumulator is loaded into bit 7.

RRC . Rotate Accumulator Right Through Carry


Syntax: RRC A
Shifts the bits of the accumulator to the right. The right-most bit (bit 0) of the
accumulator is loaded into the Carry Flag, and the original Carry Flag is loaded into bit 7.
SETB . Set Bi t
Syntax: SETB bitAddr
Sets the specified bit.
If the instruction requires the Carry bit to be set, the assembler will automatically use the
0xD3 opcode. If any other bit is set, the assembler will automatically use the 0xD2
opcode.

SJMP . Short Jump


Syntax: SJMP relAddr
SJMP jumps unconditionally to the address specified relAddr. RelAddr must be within -
128 or +127 bytes of the instruction that follows the SJMP instruction.

SUBB . Subtract from Accumulator with Borrow


Syntax: SUBB A,operand
SUBB subtracts the value of operand from the value of the accumulator, leaving the
resulting value in the accumulator. The value operand is not affected.
The Carry Bit (C) is set if a borrow was required for bit 7, otherwise it is cleared. In other
words, if the unsigned value being subtracted is greater than the accumulator the carry
flag is set. The Auxillary Carry (AC) bit is set if a borrow was required for bit 3,
otherwise it is cleared. In other words, the bit is set if the low nibble of the value being
subtracted was greater than the low nibble of the
accumulator. The Overflow (OV) bit is set if a borrow was required for bit 6 or for bit 7,
but not both. In other words, the subtraction of two signed bytes resulted in a value
outside the range of a signed byte (-128 to 127). Otherwise it is cleared.

SWAP . Subtract Accumulator Nibbles


Syntax: SWAP A
SWAP swaps bits 0-3 of the Accumulator with bits 4-7 of the Accumulator. This
instruction is identical to executing "RR A" or "RL A" four times.

XCH . Exchange Bytes


Syntax: XCH A,register
Exchanges the value of the accumulator with the value contained in register.

XCHD . Exchange Digi t


Syntax: XCHD A,register
Exchanges bits 0-3 of the accumulator with bits 0-3 of the Internal RAM address pointed
to indirectly by R0 or R1. Bits 4-7 of each register are unaffected.

XRL . Bitwise Exclusive OR


Syntax: XRL operand1,operand2
XRL does a bitwise "EXCLUSIVE OR" operation between operand1 and operand2,
leaving the resulting value in operand1. The value of operand2 is not affected. A logical
"EXCLUSIVE OR" compares the bits of each operand and sets the corresponding bit in
the resulting byte if the bit was set in either (but not
both) of the original operands, otherwise the bit is cleared.

Program Flow
When an 8052 is first initialized the PC SFR is reset to 0000h. The 8052 then begins to
execute instructions sequentially in memory unless a program instruction causes the PC
to be otherwise altered. There are various instructions that can modify the value of the
PC; specifically, conditional branching instructions, direct jumps and calls, and "returns"
from subroutines. Additionally, interrupts, when enabled, can cause the program flow to
deviate from its otherwise sequential scheme.

Conditional Branching
The 8052 contains a suite of instructions which, as a group, are referred to as "conditional
branching" instructions. These instructions cause program execution to follow a non-
sequential path if a certain condition is true. Take, for example, the JB instruction. This
instruction means "Jump if Bit Set." An example of the JB instruction might be:

In this case, the 8052 will analyze the contents of bit 45h. If the bit is set program
execution will jump immediately to the label HELLO, skipping the NOP instruction. If
the bit is not set the conditional branch fails and program execution continues, as usual,
with the NOP instruction that follows.
Conditional branching is the fundamental building block of program logic since all
"decisions" are accomplished by using conditional branching. Conditional branching can
be thought of as the "IF... THEN" structure in 8052 assembly language. An important
note worth mentioning about conditional branching is that the program may only branch
to instructions located within 128 bytes prior to or 127 bytes after the address that follows
the conditional branch instruction. This means that in the above example the label
HELLO must be within +/- 128 bytes of the memory address that contains the conditional
branching instruction.
Direct Jumps
While conditional branching is extremely important, it is often necessary to make a direct
branch to a given memory location without basing it on a given logical decision. This is
equivalent to saying "GOTO" in BASIC. In this case you want the program flow to
continue at a given memory address without considering any conditions. This is
accomplished in the 8052 using "Direct Jump and Call" instructions. s illustrated in the
last paragraph, this suite of instructions causes program flow to change unconditionally.
Consider the example:

The LJMP instruction in this example means "Long Jump." When the 8052 executes this
instruction the PC is loaded with the address of NEW_ADDRESS and program execution
continues sequentially from
there. The obvious difference between the Direct Jump and Call instructions and the
conditional branching is that with Direct Jumps and Calls program flow always changes.
With conditional branching program flow only
changes if a certain condition is true.

It is worth mentioning that, aside from LJMP, there are two other instructions that cause a
direct jump to occur: the SJMP and AJMP commands. Functionally, these two
commands perform the exact same
function as the LJMP command--that is to say, they always cause program flow to
continue at the address indicated by the command. However, these instructions differ
from LJMP in that they are not capable of jumping to any address. They both have
limitations as to the .range. of the jumps.

1. The SJMP command, like the conditional branching instructions, can only jump to an
address within +/- 128 bytes of the SJMP command.

2. The AJMP command can only jump to an address that is in the same 2k block of
memory as the AJMP command. That is to say, if the AJMP command is at code memory
location 650h, it can only do a jump to addresses 0000h through 07FFh (0 through 2047,
decimal).
You may ask yourself, "Why would I want to use the SJMP or AJMP command which
have restrictions as to how far they can jump if they do the same thing as the LJMP
command which can jump anywhere in memory?" The answer is simple: The LJMP
command requires three bytes of code memory whereas both the SJMP and AJMP
commands require only two. If you are developing an application that has memory
restrictions you can often save quite a bit of memory using the 2-byte AJMP/SJMP
instructions instead of the 3-byte instruction.

Direct Calls
Another operation that will be familiar to seasoned programmers is the LCALL
instruction. When the 8052 executes an LCALL instruction it immediately pushes the
current Program Counter onto the stack and then continues executing code at the address
indicated by the LCALL instruction.
Similar in format to the AJMP instruction that was described in the previous section, the
ACALL instruction provides a way to perform the equivalent of an "LCALL" with a 2-
byte instruction (instead of 3) as long as the target routine is within the same 2k block of
memory.

Returns from Routines


Another structure that can cause program flow to change is the "Return from Subroutine"
instruction, known as RET in 8051 Assembly Language. The RET instruction, when
executed, returns to the address following the instruction that called the given subroutine.
More accurately, it returns to the address that is stored on the stack. The RET command
is direct in the sense that it always changes program flow without basing it on a
condition, but is variable in the sense that where program flow continues can be different
each time the RET instruction is executed depending on from where the subroutine was
called originally.
Interrupts
An interrupt is a special feature that allows the 8052 to break from its normal program
flow to execute an immediate task, providing the illusion of "multi-tasking." The word
"interrupt" can often be substituted with the word "event." An interrupt is triggered
whenever a corresponding event occurs. When the event occurs, the 8052 temporarily
puts "on hold" the normal execution of the main program and executes a special section
of code referred to as the "Interrupt Service Routine" (ISR). The ISR performs whatever
special functions are required to handle the event and then returns control to the 8052 at
which point program execution continues as if it had never been interrupted. The topic of
interrupts is somewhat tricky and very important. For that reason, an entire chapter will
be dedicated to the topic.

Instruction Set, Timing, and Low-Level Information


In order to understand--and better make use of--the 8052, it is necessary to understand
some underlying information concerning timing. The 8052 operates with timing derived
from an external crystal or a clock signal generated by some other system. A crystal is a
component that allows an electronic oscillator to run at a very precisely known
frequency. One can find crystals of virtually any frequency depending on the application
requirements. When using an 8052, one of the most common crystal frequencies is
11.0592 megahertz. Why would anyone pick such an oddball frequency? There.s a reason
which has to do with generating baud rates and we.ll talk more about it in the Serial
Communication chapter. For the remainder of this discussion we.ll assume that we.re
using an 11.0592Mhz crystal. Microcontrollers (and many other electrical systems) use
their oscillators to synchronize operations. The 8052 uses its crystal or clock for precisely
that: to synchronize its internal operation. The 8052 operates
using what are called "instruction cycles." A single instruction cycle is the minimum
amount of time in which a single 8052 instruction can be executed, although many
instructions take multiple cycles. A cycle is, in reality, 12 clock cycles from the crystal.
That is to say, if an instruction takes one instruction cycle to execute, it will take 12
clocks of the crystal to execute. Since we know the crystal oscillates 11,059,200 times
per second and that one instruction cycle is 12 clock cycles, we can calculate how many
instruction cycles the 8052 can execute per second:

11,059,200 / 12 = 921,600

This means that the 8052 can execute 921,600 single-cycle instructions per second. Since
a large number of 8052 instructions are single-cycle instructions it is often considered
that the 8051 can execute roughly 1
million instructions per second (MIPS), although in reality it is less--and, depending on
the instructions being used, an estimate of about 600,000 instructions per second is more
realistic. For example, if you are using exclusively 2-cycle instructions you would find
that the 8052 executes
460,800 instructions per second. The traditional 8052 also has two really slow
instructions (MUL AB and DIV AB) that require a full 4 cycles to execute--if you were
to execute nothing but those instructions you.d find performance to be about 230,400
instructions per second. It is again important to emphasize that not all instructions
execute in the same amount of time. The fastest instructions require one instruction cycle
(12 clock cycles), many others require two instruction cycles (24 clock cycles), and the
two very slow math operations require four instruction cycles (48 clock cycles).

Since all the instructions require different amounts of time to execute, a very obvious
question comes to mind: How can one keep track of time in a time-critical application if
we have no reference to time in the outside world?

NOTE: Many derivative chips change instruction timing. For example, many optimized
versions of the 8052 execute instructions in 4 oscillator cycles instead of 12; such a chip
would be effectively 3 times faster than the 8052 when used with the same 11.0592 MHz
crystal.

Counters and Timers

It was mentioned in previous chapters that MCU clock employs quartz crystal. As this
frequency is highly stable and accurate, it is ideal for time measuring (similar oscillators
can be found in watches). To determine the amount of time past between two
occurrences, all you need to do is count the generated impulses. This is where the timer
takes part; properly programmed, value of timer register will increase or decrease with
every MCU clock impulse. Since one instruction takes 12 oscillator cycles to complete,
the math is easy. For example, if quartz oscillator works at 12 MHz, timer register will
increase/decrease every microsecond (million times per second).

AT89S52 has three timers/counters marked as T0, T1, and T2. Two of them are from the
"first lineup" shared by all models from 8051 family, while the third (T2) was added in
the process of developing the basic model. Their purpose is to measure time and count
external occurrences, but can also be used as clock in serial connection, Baud Rate.

Timer T0

As shown in the image below, T0 consists of two registers - TH0 and TL0, for storing
higher and lower byte of a 16-bit binary numeral.
For example, if T0 = 0, both registers will have value of zero. If T0 has value of 1000
(decimal), TH0 (higher byte) will hold decimal value of 3, and TL0 (lower byte) will
hold decimal value of 232. See the image below.

Formula for calculating the value of 16-bit register is simple:

TH0 * 256 + TL0 = T

On our previous example:

3 * 256 + 232 = 1000

Timers are technically 16-bit registers, thus the maximal value they can hold is 65.535. If
this number is exceeded, timer will automatically reset and start from zero. This situation
is known as overflow.

Two registers tightly connected to Timer T0 are TMOD and TCON.


TMOD - Timer Mode

This register sets mode for timers T0 and T1. As shown in the image below, lower 4 bits
(bit 0 - bit 3) are associated with T0, while the higher 4 bits (bit4 - bit7) are associated
with T1.

The following table gives details on bits 0 - 7 :

Bit Bit Name Purpose Timer


7 GATE1 1 Timer works only if INT1 (P3.3) is set T1
0 Timer works regardless of INT1 (P3.3)
6 C/T1 1 Timer counts impulses on T1 (P3.5) T1
0 Timer counts impulses of internal oscillator
5 T1M1 Timer mode T1
4 T1M0 Timer mode T1
3 GATE0 1 Timer works only if INT0 (P3.2) is set T0
0 Timer works regardless of INT0 (P3.2)
2 C/T0 1 Timer counts impulses on T0 (P3.4) T0
0 Timer counts impulses of internal oscillator
1 T0M1 Timer mode T0
0 T0M0 Timer mode T0

Four bits from the previous table determine the operating mode of timers T0 and T1.
There are 4 of these modes, and each will be covered in details.

T0M1 T0M0 Mode Description


0 0 0 13-bit Timer
0 1 1 16-bit Timer
1 0 2 8-bit auto-reload
1 1 3 Split mode

Mode 0 (13-bit Timer)

This mode is an antiquity kept just for the sake of compatibility with older MCUs. When
activated, whole higher byte TH0 and only the first 5 bits of lower byte TL0 are
accessible. Thus, with Mode 0, Timer T0 uses only 13 of its 16 bits. How does it work?
On each impulse, lower register is changed (the "trimmed" one). When TL0 is filled after
32 impulses, it is automatically reset, and TH0 is increased by one. This process repeats
itself until 8192 impulses are registered, upon which both registers are reset to zero.

Mode 1 (16-bit Timer)

Mode 1 uses all bits of registers TH0 and TL0, and is commonly used. Counting process
is same as with Mode 0, except the timer reaches value of 65.536 (max for 16 bits) before
reset.
Mode 2 (8-bit "auto reload" Timer)

What is "auto reload" ? Simply, only one of two registers is used for counting; however,
it does not start from zero, but from a specified value stored in the other register (0-255).

Advantages of this mode will be illustrated on the following example: suppose that there
is a need to report every 55th impulse of the clock. If Mode 0 or Mode 1 was used, you
would need to store 200 (decimal) into T0, and then continually check for the overflow
(exceeding 255 decimal). Upon hit, value of 200 would need to be written to T0 again. In
Mode 2, MCU performs this task automatically. Namely, TL0 works as an 8-bit timer,
while TH0 stores the starting value, specifically 200 in our example. When TL0 is filled,
instead of reset, it will load value from TH0. Thus, to register every 55th impulse, all you
need to do is write 200 to TH0, and set the Timer Mode 2.

Mode 3 ("Split" Timer)

When Timer T0 is configured to Mode 3, you actually get an additional timer. In this
mode, registers TH0 and TL0 act as separate 8-bit timers: TH0 substitutes Timer 0, while
TL0 substitutes Timer 1. Consequently, all control bits associated with the original Timer
1 (16-bit register consisting of TH1 and TL1) are now in control of newly created "Timer
1". This means that, although it can be set to any mode (Mode 1, 2, or 3), the original
Timer 1 cannot be stopped anymore, because there is simply no control bit to do it. In this
mode, it will be constantly active in the background.

TCON - Timer Control

TCON is another register in direct control of the timers.

Of the 8 bits, TCON uses only 4 bits for controlling the timers, while the other 4 are
associated with interrupts.

Bit Bit Name Purpose Timer


7 TF1 This bit is automatically set in T1
case of overflow in Timer T1
6 TR1 1 - Timer T1 is on T1
0 - Timer T1 is off
5 TF0 This bit is automatically set in T0
case of overflow in Timer T0
4 TR0 1 - Timer T0 is on T0
0 - Timer T0 is off

Starting Timer T0

Select this timer and set the desired mode.


This sets the Timer T0 to operate in Mode 1, and count the impulses of internal source
with frequency equal to 1/12 of the quartz oscillator's frequency.

Right after the command for setting the bit TR0, Timer is operational. Assuming that
12MHz quartz crystal is installed, value in T0 will increase every microsecond. After
passing of 65.536 microseconds, both registers of the Timer will be full. MCU
automatically resets them and the Timer continues the loop, as long as the bit TR0 is set.
Reading Timer

Depending on the application, you need either the value written in Timer registers, or the
exact point of time at which the Timer is reset.

 If you need to read the value of the Timer which uses only one register for
counting (Mode 3, for example) just read the value of that register.
 If the Timer works in Mode 2, reading is a bit more complicated. For example,
you might have obtained values of the lower and the higher byte, respectively:

TH0=15, TL0=255.

Seemingly, the results are valid, but the true state of registers at the moment of
reading was:

TH0=14, TL0=255.

This widely inaccurate reading (255 impulses) may happen due to not so obvious,
yet perfectly logical reason. Lower byte was read ok (255), but while the Program
Counter was "loading" your new instruction for reading TH0, overflow occurred,
changing both registers (TH0: 14 -> 15, TL0: 255 -> 0). Solution to the problem
is simple: you need to read the higher byte first, then the lower byte, and then the
higher byte again. If two readings of higher byte do not match, the sequence has
to be repeated (this is a mini-loop in the program, not more than 3 instructions).

There is also another solution: just turn off the Timer for the time of reading
(clear the bit TR0 in TCON), and turn it on afterwards.

Detection of Overflow

Usually, there is no need to continually read the Timer registers; it is sufficient to detect
the moment at which they are reset, the so-called Overflow. When it happens, bit TF0 in
TCON will be automatically set. This moment can be "awaited", by writing a small loop
for testing the bit continually, or by enabling an interrupt. Suppose that there is a need to
suspend a program for duration of 0.05 seconds (5000 cycles):

First, you need to calculate a number to be written to Timer registers:


This value should be stored to Timer registers TH0 and TL0:

After that, when started (bit TR0 = 1), Timer will continue the counting up from our
written value. Now a program instruction can be used to test if the bit TF0 was set, which
should take place after exactly 50.000 cycles, i.e. 0.05 seconds.

Measuring Impulse Duration

Measuring time past between two events is a common task in electronics; for example,
measuring for how long has device been active. Note the bit named GATE0 (in TMOD
Register) in the Timer schematics. If this bit is cleared, pin P3.2 has no effect on the
Timer. But, if GATE0 = 1, Timer will work only for as long as the pin P3.2 is set. This
means that, by bringing 5V externally to this bit, simultaneously with turning the power
on, Timer can measure the active period of the device, which was the original idea.

Counting Impulses

The answer is in bit C/T0 in TCON Register. Similar to the previous example, C/T0
"brings in" an external signal: if bit is cleared, Timer measures the time, i.e. impulses
generated by MCU clock. If bit is set, impulses from P3.4 (T0) are conducted to Timer's
input. Having no predetermined order or sequence, these impulses cannot be used for
measuring time, effectively turning the Timer into Counter. The highest frequency this
Counter can record equals 1/24 of frequency of used quartz-crystal.

Timer T1

This is the "twin brother" of Timer T0. It can fulfill same roles, it is also controlled by
TMOD and TCON, and has 4 different modes of work.
Serial communication

UART (Universal Asynchronous Communication)

One of the things that makes this MCU so powerful is the hardware integrated UART,
better known as serial port. It is a duplex port capable of sending and receiving data
simultaneously. Without it, serial data transfer would be an endlessly complicated task,
with numerous checks performed at strictly defined pace. UART represents an elegant
solution: programmer just needs to set the mode and the rate of transfer. Register SBUF
holds data to be sent to line, and the same register accepts data from the line. Controller
takes care of all the details of transfer with no room for error.

Before using the serial port, it should be appropriately configured. SFR register SCON
(Serial Control) is in control of the transfer parameters: size of one serial "word" in bits,
baud rate, and the source of impulses for synchronization.

SCON (Serial Port Control Register)

Bit Name Bit Address Purpose


SM0 9Fh Mode of work
SM1 9Eh Mode of work
SM2 9Dh Enables connecting multiple MCU's
REM 9Ch When set, enables receiving data
TB8 9Bh 9th bit for sending data in modes 2 and 3
RB8 9Ah 9th bit for sending data in modes 2 and 3
TI 99h Bit is automatically set when the whole byte
is sent
RI 98h Bit is automatically set when the whole byte
is received

As shown in the table, combination of bits SM0 and SM1 determines the mode of work
for serial port:

SM0 SM1 Mode Description Baud Rate


0 0 0 8-bit Shift register Quartz frequency / 12
0 1 1 8-bit UART Determined by timer T1 or T2
1 0 2 9-bit UART Quartz frequency / 32
1 1 3 9-bit UART Determined by timer T1 or T2

Obviously, baud rate in modes 0 and 2 is fixed, and can be adjusted in modes 1 and 3
(details can be found in the chapter on timers). In addition, baud rate in modes 1, 2, and 3
is doubled if bit SMOD in register PCON is set (see below).

Mode 0

Mode 0 is not used for standard serial communication, but serves to provide additional
I/O pins. External shift registers convert the data into binary sequence, which is then
serially transferred to the controller. Although there is no limit on the number of I/O ports
that can be gained in this manner, the existing 32 I/O lines are sufficient for most of the
tasks, making this mode rarely used.
Mode 1

This is the standard RS-232 mode for serial transfer of 8-bit data. Sequence of ten bits is
sent via pin TXD or received via pin RXD in the following order: one start bit (always 0),
followed by 8 data bits (LSB bit is first), and one stop bit (always 1). Start bit is not
registered anywhere as its sole purpose is to start the mechanism for receiving data.
When data is received, stop bit is automatically copied to bit RB8 in register SCON. In
order to connect the controller to RS-232 line, this "raw" serial data needs to be inverted -
this is carried out automatically by the designated drivers.

Modes 2 and 3

These modes are frequently used for speedy transfers at short range (Mode 2) and for
standard RS-232 transfers with parity bit (Mode 3). Both modes transfer 9-bit data in the
following order: one start bit (always 0), followed by 8 data bits (LSB bit is first), 9th bit
which is copied from the bit TB8 before transfer, and to the bit RB8 after transfer, and
finally one stop bit (always 1).

Other bits of register SCON have following roles:

Bit Purpose
SM2 This bit is used if multiple microcontrollers exchange data using the
same line. Otherwise, it needs to be cleared to provide normal
functioning of the communication
REN Needs to be set to enable receiving data via serial communication
TB8 Auxiliary 9th bit in 9-bit transfer (modes 2 and 3)
RB8 Similar to TB8, but on receiving. When accepting 9-bit data, it stores
value of the ninth bit.
TI This bit is automatically set when the last bit of one byte has been
proceeded to the line. In this way, processor "knows" that the line is
free for sending another byte.
RI Similar to TI, but on receiving. It is a "doorbell" of a kind, which
indicates that one byte has been received, and that it should be read
before another one arrives.
Setting the Baud Rate

Once you have selected the mode of UART, you need to set the Baud Rate.

Baud Rate in modes 0 and 2 depends solely on the frequency of quartz crystal. Crystals
designed specifically for this purpose can be found in the market. Although their
frequencies might seem a bit exotic at first (e.g. 11.059 MHz), they produce standard
rates for serial communication after the clock has been divided by the controller.

Baud Rate in modes 1 and 3 is determined by timers T1 and/or T2. Timer T1 is most
commonly used in "Auto-Reload" mode (TMOD = 0010xxxx). In this case, rate is
determined by the frequency of overflow occurrence, and can be calculated according to
the formula:

Quartz oscillator frequency


Baud Rate =
384 * (256 - TH1)

If bit SMOD in register PCON is set, rate will be doubled:

Quartz oscillator frequency


Baud Rate =
192 * (256 - TH1)

Here, bits which are automatically set upon overflow are of no use, and should be cleared
to avoid causing an interrupt.

If timer T2 is used for setting the Baud Rate, its bits will always have priority, allowing
the microcontroller to send and receive data at different rates:

RCLK TCLK Mode of work


0 0 Rates of sending and receiving are equal and set by timer T1
only
0 1 Receiving rate is set by T1, sending rate is set by T2
1 0 Receiving rate is set by T2, sending rate is set by T1
1 1 Rates of sending and receiving are equal and set by timer T2
only

Sending and Receiving Data via UART

Once UART is prepared for transfer, sending and receiving data is very simple. It all
comes down to simple writing and reading of register SBUF.

As soon as data is written to this port, MCU starts sending it, one bit at a time. At the end
of the sequence, bit TI in register SCON is set to indicate that one byte has been sent.
Similar procedure takes place when receiving data - after the bit RI (also in SCON) has
been set, you just need to read the register SBUF.
Interrupts

AT89S51 supports total of 6 interrupt sources, meaning that it can recognize up to 6


different events that can interrupt regular program execution. Each of these interrupts can
be individually enabled or disabled by configuring the register IE. Also, as shown in the
figure below, whole system of interrupts can be disabled by clearing the bit EA in the
same register.

There is one not so obvious detail which requires an additional explanation, and it
concerns the external interrupts - INT0 and INT1. Namely, if bits IT0 and IT1 (in register
TCON) are set, program will be interrupted on change of pins from 1 to 0, i.e. on falling
edge of the impulse. If these two bits are cleared, same signal will trigger an interrupt, but
in this case it will be continually executed as long as the state on pins is low.

IE (Interrupt Enable)
Following table describes the bits of register IE
(same rule applies to all bits - logical state of 1 enables the appropriate interrupt):

Bit Purpose
EA Enables/disables all interrupt sources
ET2 Timer T2 interrupt
ES UART and SPI interrupts
ET1 Timer T1 interrupt
EX1 External interrupt: pin INT1
ET0 Timer T0 interrupt
EX0 External interrupt: pin INT0

Interrupt Priorities

It cannot be predicted with absolute certainty when will interrupt request take place. If
multiple interrupts are enabled, it's quite possible to have interrupt requests during
execution of another interrupt routine. In such cases, controller needs to resolve whether
to proceed with the current interrupt routine, or to enter a new one, based on a priority
check. Our microcontroller can differentiate between three priority levels:

1. Reset. If there is a request for reset, all processes are halted and the controller
behaves as if the power had just been turned on.
2. Priority 1 interrupts. Can be interrupted only by reset.
3. Priority 2 interrupts. Can be interrupted by any of above.

IP (Interrupt Priority)
SFR register IP determines the priority of existing interrupt sources
(Same rule applies to all bits : logical state of 1 assigns higher priority to the appropriate
interrupt):

Bit Purpose
PT2 Timer T2 interrupt priority
PS Serial port interrupt priority
PT1 Timer T1 interrupt priority
PX1 External interrupt INT1 priority
PT0 Timer T0 interrupt priority
PX0 External interrupt INT0 priority

If two interrupt requests collide, the one with higher priority has precedence in execution.
If both interrupts are of same priority, the one with the later request has to hold one and
let the controller handle the first one.

How does interrupt execute?

Upon receiving an interrupt request, following scenario takes place:

1. Current instruction is executed first.


2. Address of the instruction that would be executed next if there was no interrupt
request is put away to stack.
3. Depending on the interrupt in question, program counter will take value of one of
possible 6 vectors (addresses) according to the table below.

Interrupt source Vector (address in hex)


IE0 0003h
TF0 000Bh
IE1 0013h
TF1 001Bh
RI, TI, SPIF 0023h
TF2, EXF2 002Bh

4. These addresses should hold the appropriate subroutines for handling the
interrupts. In practice, instead of actual routines, they only point to the location of
appropriate routines in the code.
5. Upon accomplishing the interrupt routine, address of the next instruction to be
executed is retrieved from the stack, and the program proceeds from the location
where it was interrupted.

LCD Interfacing:

Frequently, an 8051 program must interact with the outside world using input and
output devices that communicate directly with a human being. One of the most common
devices attached to an 8051 is an LCD display. Some of the most common LCDs
connected to the 8051 are 16x2 and 20x2 displays. This means 16 characters per line by 2
lines and 20 characters per line by 2 lines, respectively.

16x2 character LCD

Fortunately, a very popular standard exists which allows us to communicate with


the vast majority of LCDs regardless of their manufacturer. The standard is referred to as
HD44780U, which refers to the controller chip which receives data from an external
source (in this case, the 8051) and communicates directly with the LCD.

Why LCD’s are widely used:

The widespread of using LCD’s is because of


(i) The ability to display numbers, characters and graphics. This is in contrast to
LEDs and 7-segment displays, which are limited to numbers and few
characters.
(ii) Ease of programming for characters and graphics.
44780 standards:

The 44780 standard requires 3 control lines as well as either 4 or 8 I/O lines for the data
bus. The user may select whether the LCD is to operate with a 4-bit data bus or an 8-bit
data bus. If a 4-bit data bus is used, the LCD will require a total of 7 data lines (3 control
lines plus the 4 lines for the data bus). If an 8-bit data bus is used, the LCD will require a
total of 3 control lines plus the 8 lines for the data bus.

Pin description of LCD.

Pin
Symbol I/O Description
NO.
1 Vss -- Ground
2 Vcc -- +5V power supply
3 VEE -- Power supply to control contrast
RS=0 to select command register
4 RS I
RS=1to select data register
R/W=0 for write
5 R/W I
R/W=1 for read
6 E I/O Enable; H- L pulse
7 DBO I/O The 8-bit data bus
8 DB1 I/O The 8-bit data bus
9 DB2 I/O The 8-bit data bus
10 DB3 I/O The 8-bit data bus
11 DB4 I/O The 8-bit data bus
12 DB5 I/O The 8-bit data bus
13 DB6 I/O The 8-bit data bus
14 DB7 I/O The 8-bit data bus

Vcc, Vss and VEE:


Vcc and Vss provide +5v and ground, respectively, Vee is used for controlling
LCD contrast.

The three control lines are referred to as RS, RW and EN.

RS, Register select:


There are very two important registers inside the LCD. The RS pin is used for
their selection as follows.

The RS line is the "Register Select" line. When RS is low (0), the data is to be
treated as a command or special instruction (such as clear screen, position cursor, etc.).
When RS is high (1), the data being sent is text data which should be displayed on the
screen. For example, to display the letter "T" on the screen you have to set RS high.

The RW line is the "Read/Write" control line. When RW is low (0), the
information on the data bus is being written to the LCD. When RW is high (1), the
program is effectively querying (or reading) the LCD. Only one instruction ("Get LCD
status") is a read command. All others are write commands--so RW will almost always be
low.

The EN line is called "Enable." This control line is used to tell the LCD that you are
sending it data. To send data to the LCD, your program should first set this line high (1)
and then set the other two control lines and/or put data on the data bus. When the other
lines are completely ready, bring EN low (0) again. A high to low transition tells the
LCD to take the data currently found on the other control lines and on the data bus and to
treat it as a command. The high to pulse must be minimum of 450ns wide.

Finally, the data bus consists of 4 or 8 lines (depending on the mode of operation
selected by the user). In the case of an 8-bit data bus, the lines are referred to as DB0,
DB1, DB2, DB3, DB4, DB5, DB6, and DB7.

AN EXAMPLE HARDWARE CONFIGURATION

A sample schematic of how the LCD will be connected to the 8051 is as follows:

As you can see, we've established a 1-to-1 relation between a pin on the 8051 and a line
on the LCD. Thus as we write our assembly program to access the LCD, we are going to
equate constants to the 8051 ports so that we can refer to the lines by their names as
opposed to P0.1, P0.2, etc. Let's go ahead and write our initial equates:

Having established the above equates, we may now refer to our I/O lines by their name.
For example, to set the RW line high (1), we can execute the following instruction:

SETB RW
SETB RS
SETB EN

HANDLING THE EN CONTROL LINE

As we mentioned above, the EN line is used to tell the LCD that you are ready for it to
execute an instruction that you've prepared on the data bus and on the other control lines.
Note that the EN line must be raised/lowered before/after each instruction sent to the
LCD regardless of whether that instruction is read or write text or instruction. In short,
you must always manipulate EN when communicating with the LCD. EN is the LCD's
way of knowing that you are talking to it. If you don't raise/lower EN, the LCD doesn't
know you're talking to it on the other lines.

Thus, before we interact in any way with the LCD we will always bring the EN line high
with the following instruction:

SETB EN
And once we've finished setting up our instruction with the other control lines and data
bus lines, we'll always bring this line back low:
CLR EN

Programming Tip: The LCD interprets and executes our command at the instant the EN
line is brought low. If you never bring EN low, your instruction will never be executed.
Additionally, when you bring EN low and the LCD executes your instruction, it requires
a certain amount of time to execute the command. The time it requires to execute an
instruction depends on the instruction and the speed of the crystal which is attached.

CHECKING THE BUSY STATUS OF THE LCD

As previously mentioned, it takes a certain amount of time for each instruction to be


executed by the LCD. The delay varies depending on the frequency of the crystal
attached to the oscillator input of the LCD as well as the instruction which is being
executed.

While it is possible to write code that waits for a specific amount of time to allow the
LCD to execute instructions, this method of "waiting" is not very flexible. If the crystal
frequency is changed, the software will need to be modified. Additionally, if the LCD
itself is changed for another LCD which, although 44780 compatible, requires more time
to perform its operations, the program will not work until it is properly modified.

A more robust method of programming is to use the "Get LCD Status" command to
determine whether the LCD is still busy executing the last instruction received.

The "Get LCD Status" command will return to us two tidbits of information; the
information that is useful to us right now is found in DB7. In summary, when we issue
the "Get LCD Status" command the LCD will immediately raise DB7 if it's still busy
executing a command or lower DB7 to indicate that the LCD is no longer occupied. Thus
our program can query the LCD until DB7 goes low, indicating the LCD is no longer
busy. At that point we are free to continue and send the next command.

Since we will use this code every time we send an instruction to the LCD, it is useful to
make it a subroutine. Let's write the code:

Thus, our standard practice will be to send an instruction to the LCD and then call our
WAIT_LCD routine to wait until the instruction is completely executed by the LCD.
This will assure that our program gives the LCD the time it needs to execute instructions
and also makes our program compatible with any LCD, regardless of how fast or slow it
is.

Programming Tip: The above routine does the job of waiting for the LCD, but was it to
be used in a real application a very definite improvement would need to be made: as
written, if the LCD never becomes "not busy" the program will effectively "hang,"
waiting for DB7 to go low. If this never happens, the program will freeze. Of course, this
should never happen and won't happen when the hardware is working properly. But in a
real application it would be wise to put some kind of time limit on the delay--for
example, a maximum of 256 attempts to wait for the busy signal to go low. This would
guarantee that even if the LCD hardware fails, the program would not lock up.

INITIALIZING THE LCD

Before you may really use the LCD, you must initialize and configure it. This is
accomplished by sending a number of initialization instructions to the LCD.

The first instruction we send must tell the LCD whether we'll be communicating with it
with an 8-bit or 4-bit data bus. We also select a 5x8 dot character font. These two options
are selected by sending the command 38h to the LCD as a command. As you will recall
from the last section, we mentioned that the RS line must be low if we are sending a
command to the LCD. Thus, to send this 38h command to the LCD we must execute the
following 8051 instructions:

So, in all, our initialization code is as follows:

Having executed this code the LCD will be fully initialized and ready for us to send
display data to it.

CLEARING THE DISPLAY

When the LCD is first initialized, the screen should automatically be cleared by the
44780 controller. However, it's always a good idea to do things yourself so that you can
be completely sure that the display is the way you want it. Thus, it's not a bad idea to
clear the screen as the very first operation after the LCD has been initialized.

An LCD command exists to accomplish this function. Not surprisingly, it is the command
01h. Since clearing the screen is a function we very likely will wish to call more than
once, it's a good idea to make it a subroutine:

How that we've written a "Clear Screen" routine, we may clear the LCD at any time by
simply executing an LCALL CLEAR_LCD.
Programming Tip: Executing the "Clear Screen" instruction on the LCD also positions
the cursor in the upper left-hand corner as we would expect.

WRITING TEXT ON TO THE LCD

Now we get to the real meat of what we're trying to do: All this effort is really so we can
display text on the LCD. Really, we're pretty much done.

Once again, writing text to the LCD is something we'll almost certainly want to do over
and over--so let's make it a subroutine.

The WRTDAT routine that we just wrote will send the character in the accumulator to
the LCD which will, in turn, display it. Thus to display text on the LCD all we need to do
is load the accumulator with the byte to display and make a call to this routine.

A "HELLO WORLD" PROGRAM

Now that we have all the component subroutines written, writing the classic "Hello
World" program--which displays the text "Hello World" on the LCD, is a relatively
trivial matter. Consider:

LCALL INIT_LCD
LCALL CLEAR_LCD
MOV A,#'H'
LCALL WRTDAT
MOV A,#'E'
LCALL WRTDAT
MOV A,#'L'
LCALL WRTDAT
MOV A,#'L'
LCALL WRTDAT
MOV A,#'O'
LCALL WRTDAT

MOV A,#'W'
LCALL WRTDAT
MOV A,#'O'
LCALL WRTDAT
MOV A,#'R'
LCALL WRTDAT
MOV A,#'L'
LCALL WRTDAT
MOV A,#'D'
LCALL WRTDAT
The above "Hello World" program should, when executed, initialize the LCD, clear the
LCD screen, and display "Hello World" in the upper left-hand corner of the display.

KEYPAD INTERFACING:

The above diagram shows a 4 X 4 keypad - 16 switches arranged in 4 columns and 4


rows.
In the default state (all switches open) there is no connection between the rows and
columns. When a switch is pressed a connection between the switch's row and the
switch's column is made. i.e; whenever a key is pressed the corresponding rows and
columns are shorted.
The lower nibble of Port1 i.e. P1.0 to P1.3 are Connected to the 4 columns
The upper nibble is connected to the 4 Rows note that Row 1 is connected to P1.7.

Important steps in reading a keypad:


Step1: See if any key is pressed , so keep scanning the key pad till a key is presses
Step2: Once we have detected a key press we have to decode the key i.e we have to identify
which key is pressed.
Step3: We have to wait till the pressed key is released before We go on to process the next key
During programming we have to remember the following things.
1. Ground all the Columns and read the rows.
2. If no key is pressed you will read all rows as high. Remember the port structure P1 has
internal pull up resistors
3. If some key is pressed then one of the rows will indicate a zero

Note: But some times key press detected in the previous step could be due to noise or
transients so in order to be sure that it is key press we need to do key debounce
Key debounce involves giving a small delay of 20 ms and then checking again for a key
press,if we find a key press the second time also,we can be assured that we have a valid
key press,else we have to again go back to key scan mode.

This subroutine checks whether any key is pressed or not .


KEYCHK: MOV PORT,#0F0H ; make all the columns LOW
MOV A,PORT ; read from the ports
ANL A,#0F0H ; mask the lower nibble
CJNE A,#0F0H,HERE ; check if there is key press
SJMP KEYCHK
The next subroutine checks whether the key press is due to noise or actual keypress.
HERE: ACALL DELAY ; debounce
MOV A,PORT ; read port again to make sure it was not noise
ANL A,#0F0H
CJNE A,#0F0H,KEYFIND ; If valid key, jump to decode the key
SJMP KEYCHK ; If invalid go back to key scan mode
The following coding shows the lookup table approach for storing the corresponding key
data.
KEYCODE: DB 0FEH,70H,'1'
DB 0FEH,0B0H,'5'
DB 0FEH,0D0H,'9'
DB 0FDH,70H,'2'
DB 0FDH,0B0H,'6'
DB 0FDH,0D0H,'0'
DB 0FBH,70H,'3'
DB 0FBH,0B0H,'7'
DB 0F7H,70H,'4'
DB 0F7H,0B0H,'8'
The following steps are required to find which key is pressed.
Step1: Initialize pointer to Look Up Table
Step2: Output code ,in pointer and read input
Step3: Input == Expected Input Key found exit loop
Step4: Inc pointer to point to next code location and goto Step 2
The code for the above is as follows

KEYFND: MOV DPTR, #KEYCODE


keyfnd1: MOV A,#00H ; initialize acc to 0
MOVC A,@A+DPTR ; get the first code into acc
INC DPTR ; inc DPTR to point to expected output
MOV PORT,A ; PUT KEYCODE INTO PORT1
NOP
NOP
MOV A,PORT ; READ FROM THE PORT
ANL A,#0F0H ; MASK THE LOWER NIBBLE
MOV R1,A ; STORE ACC. IN REG. R1
MOV A,#00H
MOVC A,@A+DPTR ; LOAD THE EXPECTED NO. IN A
CJNE A,01,NEXT
INC DPTR ;IF KEY FOUND POINT TO THE CODE
CLR A
MOVC A,@A+DPTR
MOV R3,A ;STORE RESULT IN REG R3
SJMP KEYREL
NEXT: INC DPTR
INC DPTR
SJMP KEYFND 1
KEYREL: MOV PORT,#0F0H ; make all the colums LOW
MOV A,PORT ; read from the ports
ANL A,#0F0H ; mask the lower nible
CJNE A,#0F0H,KEYREL ; check if there is keypress
mov a,r3
lcall wrtdat
sjmp keychk

MOTORS

When trying to move things with microcontrollers, there are basically three kinds of .
motors that are most useful: DC motors, servomotors, and stepper motors. Following is
a brief introduction to these three. More notes can be found all over the web, and in
many good electronics and robotics books.

Most all motors work on the electrical principle of induction. When you put electric
current through a wire, it generates a magnetic field around the wire. By placing a
charged coil of wire in an existing magnetic field (say, between two magnets), the coil
will be either attracted to one magnet and repelled by the other, or vice versa,
depending on the current flow. The higher the current, the greater the magnetic field,
and therefore the greater the attraction or repulsion. The coil is mounted on a spinning
shaft in the middle of the motor. As the coil is alternately attracted to one magnet and
repulsed by the other, it spins from one to the other, and we get circular motion.

All inductive loads (like motors, electromagnets, and solenoids) work on this same
principle: induce a magnetic field by putting current through a wire, use it to attract or
repulse a magnetic body. However, the principle works in reverse as well. When you
spin a wire in an existing magnetic field, the field induces a current in the wire. So if
you've got a motor spinning, and you turn it off, the fact that the motor's coil is
spinning in a magnetic field will generate a current in the wire for a brief amount of
time. This current comes back in the reverse direction of the current flow you
generated to run the motor. It's called blowback, or back voltage, and it can cause
damage to your electronics. Usually it's stopped by putting a diode in line with your
motor, to stop the back voltage.

Motor Characteristics

There are a few characteristics common to all motors that you should keep in mind
when looking for motors:

Voltage

The rated voltage of a motor is the voltage at which it operates at peak efficiency. Most
DC motors can be operated somewhat above or below their range, but it's best to plan
to operate them at their rated voltage. Dropping below rated voltage reduces the
motor's power, and operating above the rated voltage may burn the motor out. Plan on
the motor's top speed being at rated voltage, and slowest speed at no more than 50%
less than the rated voltage.

Current

Motors draw current depending on the load they're pulling. Usually more load means
more current. Every motor has a stall current, which is the current it draws when it's
stopped by an opposing force. This stall current is much greater than the running
current, or current that it draws under no load. Your power supply for a motor should
be able to handle the stall current with extra amperage to spare. Motors may draw near
the stall current for a brief period of time when starting up, to overcome their inertia.

Speed

Motor speed is given in revolutions per minute (RPM's).


Torque

Torque is the measure of a motor's pulling force. It's measured by the force a motor
can pull when the opposing force is attached to a shaft attached to its center rod. If the
shaft sticks out a foot from the motor's center, and the motor can pull one pound on
that shaft, the motor's torque is one foot-pound. Motor manufacturers haven't
standardized this measurement, so sometimes you will see it as ft.-lb., lb-ft., oz.-in, in.-
oz., g-cm (gram-centimeter), and any other weight to length variation you can think of.

Resistance

Often you'll see a motor rated in ohms. This just gives you the resistance that the
motor's coil offers. Using Ohm's Law (voltage = current x resistance), you can
calculate the motor's current draw if you know the rated voltage and the coil resistance.

The DC Motor .

The DC Motor is the simplest of the motors discussed here. It works on exactly the
principle discussed above. There are two terminals, and when you apply direct current
to one terminal and ground the other, the motor spins in one direction. When you apply
current to the other terminal and ground the first terminal, the motor spins in the
opposite direction. By switching the polarity of the terminals, you reverse the direction
of the motor. By varying the current supplied to the motor, you vary the speed of the
motor. Specific techniques for doing these tasks are discussed below.

DC motors are usually very fast, spinning at several thousand revolutions per minute
(RPM).

The Gearhead Motor

Gearhead motors are a subset of DC motors. They have a box on the top of the motors
containing a series of gears that slow the rotational speed of the motor down and
increase the torque. They are useful when you don't need a lot of speed, but you do
need power.

The Servo Motor

Servo motors are a variation on the gearhead motor coupled with a potentiometer to
give feedback on the motor's position. The gears of the gearbox on a servo are attached
to a potentiometer inside the case, and the pot is turned by the turning of the motor.
The pot is connected to a capacitor in a resistor-capacitor circuit (R-C), and by pulsing
this R-C circuit, you give the motor power to turn. When the motor turns, it changes
the resistance of the R-C circuit, which in turn feeds the motor again. By pulsing the
R-C circuit, you set the motor's position in a range from 0 to 180 degrees.

Servos have three wires to them, unlike most DC and gearhead motors, which have
two. The first two in a servo are power and ground, and the third is a digital control
line. This third line is used to set the position of a servo. Unlike other DC motors, you
do not have to reverse the polarity of a servo's power connections to reverse its
direction.

Hobby servos, the kind most often used in small physical computing projects, usually
take a pulse of between 1-2 ms every 18-20 ms. They rotate 0 to 180 degrees
depending on the pulsewidth. A pulse of 1 ms will turn the motor to 0 degrees; 2 ms
will turn it to 180 degrees. A servo needs to see a pulse every 18-20 ms even when it is
not turning, to keep it in its current position, so once you've moved the motor to a new
position, it's essential to keep pulsing it with the same pulsewidth to keep it there.

The Stepper Motor .

Stepper motors are different than regular DC motors in that they don't turn
continuously, but move in a series of steps. A stepper motor is a motor controlled by a
series of electromagnetic coils. The center shaft has a series of magnets mounted on it,
and the coils surrounding the shaft are alternately given current or not, creating
magnetic fields which repulse or attract the magnets on the shaft, causing the motor to
rotate.

This design allows for very precise control of the motor: by proper pulsing, it can be
turned in very accurate steps of set degree increments (for example, two-degree
increments, half-degree increments, etc.). They are used in printers, disk drives, and
other devices where precise positioning of the motor is necessary. Steppers usually
move much slower than DC motors, since there is an upper limit to how fast you can
step them (5-600 pulses per second, typically. However, unlike DC motors, steppers
often provide more torque at lower speeds. They can be very useful for moving a
precise distance. Furthermore, stepper motors have very high torque when stopped,
since the motor windings are holding the motor in place like a brake.

To control a stepper, it's necessary to create a stepper driver that will energize the coils
in the right order to make the motor move forward.

The first thing to do is to understand the wiring for a stepper motor. The most common
type is a unipolar stepper motor, with six wires and four coils (actually two coils
divided by center wires on each coil). To do this, take an ohmmeter to the wires and
measure the resistance from one wire to another. The outer wires for each coil will
have a definite resistance that is double the resistance between the inner wire and
either of the two outer wires, as follows in the diagram below:

e.g.: if the resistance between wires 1 and 2 is x Ohms, then that between 1 and 3 is 2x
Ohms. Remember, two wires that are not connected (e.g. 1 and 4, 5, or 6) have infinite
resistance, which should read as an error on your meter. When you put voltage across
two wires of a coil (e.g. 1 to 3, or 2 to 4), you should find that the motor is very
difficult to turn (don't force it, that's bad for the motor).

Like other motors, the stepper requires more power than a microcontroller can give it,
so you'll need a separate power supply for it. Ideally you'll know the voltage from the
manufacturer, but if not, get a variable DC power supply, apply the minimum voltage
(hopefully 1V or so), apply voltage across two wires of a coil (e.g. 1 to 3 or 4 to 6) and
slowly raise the voltage until the motor is difficult to turn. It is possible to damage a
motor this way, so don't go too far. Typical voltages for a stepper might be 5V, 9V,
12V, 24V.

Typically, you would drive the stepper by connecting the 4 phase wires to a good
power transistor or MOSFET,and the 2 common wires to the supply voltage, as
follows:
In this diagram, the transistors are TIP120 Darlington transistors. A convenient way to
do this is with a ULN2003 or ULN2004 Darlington transistor array from Allegro
Micro.

Once you have the motor stepping in one direction, stepping in the other direction is
simply a matter of doing the steps in reverse order. Knowing the position is a matter of
knowing how many degrees per step, and counting the steps and multiplying by that
many degrees. So for examples, if you have a 2-degree stepper, and it's turned 180
steps, then it's turned 2 x 180 degrees, or 360 degrees, or one full revolution.

For more on stepper control, see this example.

How Stepper Motor Works?


Stepper motors are very different from a regular DC motors. Instead of spinning like DC motors do, s
specific resolution for each pulse. The motor that we are using needs 48 steps / pulses just to comp
That should be enough to tell about

Another advantage of stepper motors is the fact that their speed of rotation can be achieved almo
change the spinning

Stepper motor consists of a rotor - the permanent magnet that rotates inside, and stator - four c
west) that are part of the case, and which don't move. Rotor can be moved by sequentially applying
one or two coils at a time.

Stepper Motor Connections

Unipolar motor should have five or six connections depending on the model. If the motor has six c
pictured above, you have to join pins 1 and 2 (red) together and connect them to a (+) 12-24V voltag
pins; a1 (yellow), b1 (black), a2 (orange), b2 (brown) should be connected to a driver (ULN2003) as s
Stepping Modes

There are several stepping modes that you can use to drive the stepper motor.

1. Single Stepping - the simplest mode turns one coil ON at a time. 48 pulses are needed to comp
Each pulse moves rotor by 7.5 degrees. The following sequence has to be repeated 12 times for mot
revolution.

Pulse Coil a1 Coil b1 Coil a2 Coil b2


1 ON
2 ON
3 ON
4 ON

2. High Torque Stepping - high power / precision mode turns ON two coils on at a time. 48 pulses
complete one revolution. Each pulse moves rotor by 7.5 degrees. The following sequence has to be r
for motor to complete one revolution.

Pulse Coil a1 Coil b1 Coil a2 Coil b2


1 ON ON
2 ON ON
3 ON ON
4 ON ON

3. Half Stepping - stepping is doubled and motor needs 96 pulses to complete one revolution. Each p
approximately 3.75 degrees. Notice the mix of single stepping mode (lighter green) and high torque
green).

Pulse Coil a1 Coil b1 Coil a2 Coil b2


1 ON
2 ON ON
3 ON
4 ON ON
5 ON
6 ON ON
7 ON
8 ON ON

Stepper Motor Driver

In able to move the rotor you will need a driver. Driver is a circuit that applies a
voltage to any of the four stator coils. Driver can be built with IC such as ULN2003
(pictured on the circuit diagram), or four darlington transistors or four power
transistors such as 2N3055.
Controlling Stepper Motor with a Port pins:

Controlling DC Motors

There are two easily controllable parameters of a DC motor, direction and speed. To control the direction, the polarity of the motor
is reversed. To control the speed, the input voltage is varied using pulsewidth modulation.

Direction Control

To control a DC motor from a microcontroller, you use switching arrangement known as an H bridge. It looks like this:
When switches 1 and 4 are closed and 2 and 3 are open, voltage flows from the supply to 1 to the motor to 4 to ground. When 2
and 3 are closed and 1 and 4 are open, polarity is reversed, and voltage flows from the supply to 3 to the motor to 2 to ground.

An H-bridge can be built from transistors, so that a microcontroller can switch the motor, like this:

You can see that there are six transistors here; the outer two are used to switch the inner four, in pairs, so that the proper two
transistors always switch together. If you were using this circuit, you'd want to make sure that control pins 1 and 2 were always
reversed; when one is high, the other is low.

Although you can make your own H-bridges, it's usually easier to use a controller manufactured specifically for the job. A pre-
manufactured H-bridge chip will include diodes to protect the transistors from back voltage, sometimes a current sensing pin to
sense the current the motor is drawing, and much more. There are many motor drivers available from various electronics suppliers.
Look around to find one that suits your needs and price range.

Speed

A DC motor's speed is proportional to the supplied voltage. If the voltage drops too far, the motor won't get enough power to turn,
but within a certain range, usually 50% of the rated voltage, the motor will run at varying speeds. The most effective way to adjust
the speed is by using pulsewidth modulation. This means that you pulse the motor on and off at varying rates, to simulate a
voltage. Here are some examples of puleswidths and the voltages they would simulate:
When the time that the voltage is high (the duty cycle) is half the total time in question, the effective voltage is about half the total
voltage.

When the duty cycle is reduced to one quarter of the total time, the effective voltage is about one quarter of the total voltage.

As with direction, there are many controllers that will vary the speed of your motor, so if you don't want to delve into the timing
issues yourself, you can rely on products made for the job.

SEVEN SEGMENT DISPLAYS

Introduction

One common requirement for many different digital devices is a visual


numeric display. Individual LEDs can of course display the binary states of a
set of latches or flip-flops. However, we're far more used to thinking and
dealing with decimal numbers. To this end, we want a display of some kind that
can clearly represent decimal numbers without any requirement of translating
binary to decimal or any other format.

One possibility is a matrix of 28 LEDs in a 7×4 array. We can then light up


selected LEDs in the pattern required for whatever character we want. Indeed,
an expanded version of this is used in many ways, for fancy displays. However,
if all we want to display is numbers, this becomes a bit expensive. A much
better way is to arrange the minimum possible number of LEDs in such a way
as to represent only numbers in a simple fashion.

This requires just seven LEDs (plus an eighth one for the decimal point, if
that is needed). A common technique is to use a shaped piece of translucent
plastic to operate as a specialized optical fiber, to distribute the light from the
LED evenly over a fixed bar shape. The seven bars are laid out as a squared-off
figure "8". The result is known as a seven-segment LED.

We've all seen seven-segment displays in a wide range of applications.


Clocks, watches, digital instruments, and many household appliances already
have such displays. In this experiment, we'll look at what they are and how they
can display any of the ten decimal digits 0-9 on demand.

Seven-Segment Display Layout

The illustration to the right shows the basic layout of the segments in a
seven-segment display. The segments themselves are identified with lower-case
letters "a" through "g," with segment "a" at the top and then counting
clockwise. Segment "g" is the center bar.

Most seven-segment digits also include a decimal point ("dp"), and some
also include an extra triangle to turn the decimal point into a comma. This
improves readability of large numbers on a calculator, for example. The
decimal point is shown here on the right, but some display units put it on the
left, or have a decimal point on each side.

In addition, most displays are actually slanted a bit, making them look as if
they were in italics. This arrangement allows us to turn one digit upside down
and place it next to another, so that the two decimal points look like a colon
between the two digits. The technique is commonly used in LED clock
displays.
Seven-segment displays can be packaged in a number of ways. Three typical
packages are shown above. On the left we see three small digits in a single 12-
pin DIP package. The individual digits are very small, so a clear plastic bubble
is molded over each digit to act as a magnifying lens. The sides of the end
bubbles are flattened so that additional packages of this type can be placed end-
to-end to create a display of as many digits as may be needed.

The second package is essentially a 14-pin DIP designed to be installed


vertically. Note that for this particular device, the decimal point is on the left.
This is not true of all seven-segment displays in this type of package.

One limitation of the DIP package is that it cannot support larger digits. To
get larger displays for easy reading at a distance, it is necessary to change the
package size and shape. The package on the right above is larger than the other
two, and thus can display a digit that is significantly larger than will fit on a
standard DIP footprint. Even larger displays are also available; some digital
clocks sport digits that are two to five inches tall.

Seven-segment displays can be constructed using any of a number of


different technologies. The three most common methods are fluorescent
displays (used in many line-powered devices such as microwave ovens and
some clocks and clock radios), liquid crystal displays (used in many battery-
powered devices such as watches and many digital instruments), and LEDs
(used in either line-powered or battery-powered devices). However, fluorescent
displays require a fairly high driving voltage to operate, and liquid crystal
displays require special treatment that we are not yet ready to discuss.
Therefore, we will work with a seven-segment LED display in this experiment.

Schematic Diagram
As shown in the two schematic diagrams above, the LEDs in a seven-
segment display are not isolated from each other. Rather, either all of the
cathodes, or all of the anodes, are connected together into a common lead,
while the other end of each LED is individually available. This means fewer
electrical connections to the package, and also allows us to easily enable or
disable a particular digit by controlling the common lead. (In some cases, the
common connections are made to groups of LEDs, and the external wiring
must make the final connections between them. In other cases, the common
connection is made available at more than one location for convenience in
laying out printed circuit boards. When laying out circuits using such devices,
you simply need to take the specific connection details into account.)

There is no automatic advantage of the common-cathode seven-segment unit


over the common-anode version, or vice-versa. Each type lends itself to certain
applications, configurations, and logic families. we will use a common-cathode
display for our experimental example.

INTERFACING A/D CONVERTERS TO 8051


ADC devices
Analog to digital converters are among the most widely used devices for data
acquisition. Digital computers use binary values, but in the physical world everything is
analog. Temperature, pressure, humidity, and velocity are a few examples of physical
quantities that we deal everyday. A physical quantity is converted to electrical signals
using a device called transducers. Transducers are also referred to as sensors. Although
there are sensors for temperatures, velocity, pressure, light, and many other natural
quantities, they produce an output that is voltage. Therefore, we need an analog to digital
converter to translate the analog signals to digital numbers so that the microcontrollers
can read them.
The ADC804 IC is an analog to digital converter in the family of the ADC80
series from National Semiconductors. It is also available from many other manufactures.
It works with +5v and has a resolution of 8bits. In addition to resolution, conversion is
the another factor in judging an ADC. Conversion time is defined as the time it takes the
ADC to convert the analog input to a digital number. In the ADC804, the conversion time
varies depending on the clocking sign als applied to the CLK R and CLK IN pins, but it
can’t be faster than 110usec.

CHIP SELECT (CS): Chip select is an active low input used to activate the ADC804
chip. To access the ADC804, this pin must be low.
READ (RD): This is an input signal and is active low. The ADC converts the analog
input to its binary equivalent and holds it an internal register. RD is used to get the
converted data out of the ADC804 chip. When CS=0, if a high to low pulse is applied to
the RD pin, the 8 bit digital output shows up at the D0-D7 data pins. The RD is referred
to as output enable.
WRITE (WR): This is an active low input used to inform the ADC804 to start
conversion process. If CS = 0 when WR makes a low to high transition, the ADC804
starts converting the analog input value of Vin to an 8 bit digital number. The amount of
time it takes to convert varies depending on the CLK IN and CLK R values. When the
conversion is completed , the INTR pin is forced low by the ADC804.

INTERRUPT (INTR):
This is an active low
output pin which indicates
the end of conversion. It
is a normally high pin
when the conversion is
finished; it goes low to
signal the MCU that the
converted data is ready to
be picked up. After INTR
goes low, we make CS =
0 and send a high to low
pulse to the RD pin to get
the data out of the
ADC804 chip.
CLK IN and CLK R: CLK IN is an input pin connected to an external clock source
when an external clock is used for timing. However, the 804 has an internal clock
generator. To use the internal clock generator of the ADC804, the CLK IN and CLK R
pins are connected to a capacitor and a resistor as shown in the figure. The clock
frequency is determined by the equation
f = 1/ 1.1RC
Vin(+) and Vin(-): These are the differential analog inputs where. Vin = Vin(+) – Vin(-).
Often the Vin(-) pin is connected to ground and the Vin(+) pin is used as the analog input
to be inverted to digital.
VCC and Vref: This is the +5v power supply. It is also used as a reference voltage when
the Vrer/2 input is open. Vref/2 is an input voltage used for the reference voltage. If this
pin pin is open( not connected ), the analog input voltage for the AD804 is in the range of
0 to 5v. However , there are many applications where the analog input applied to Vin
needs to be other than the 0 to 5V. For example, if the analog input range needs to be 0 to
4 volts. Vref/2 is connected to 2 volts.
D0 – D7: D0 – D7 are the digital data output pins. These are tri state buffered and the
converted data is accessed only when CS = 0 and RD is forced to low. To calculate the
output voltage, use the formula

Dout = Vin / step size


Where Dout is digital data output, Vin is the analog input voltage and step size is the
smallest change, which is for an 8 bit ADC.
Sequence of steps:
1. Make CS = 0 and send a low to high pulse to pin WR to
start conversion.
2. Keep monitoring the INTR is high, Keep polling until it
goes low.
If it goes low the conversion is completed and we an go to the next step.
3. After the INTR is low, we make CS = 0 and send a high
to low pulse to the RD pin to the data out of the ADC804 IC chip.

Numerical Systems

Introduction

It was always difficult for people to accept the fact that some things differ from them or
their way of thinking. That is probably one of the reasons why numerical systems which
differ from a decimal are still hard to understand. Still, whether we want it or not, reality
is different. Decimal numerical system that people use in everyday life is so far behind
the binary system used by millions of computers around the world.

Each numerical system are based on some basis. With a decimal numerical system, that
basis is 10, with binary 2, and with a hexadecimal system 16. The value of each decimal
is determined by its position in relation to the whole number represented in the given
numerical system. The sum of values of each decimal gives the value of the whole
number. Binary and hexadecimal numerical systems are especially interesting for the
subject of this book. Beside these, we will also discuss a decimal system, in order to
compare it with the other two. Even though a decimal numerical system is a subject we
are well acquainted with, we will discuss it here because of its relatedness to other
numerical systems.

B.1 Decimal numerical system

Decimal numerical system is defined by its basis 10 and decimal space that is counted
from right to left, and consists of numbers 0,1, 2, 3, 4, 5, 6, 7, 8, 9. That means that the
end right digit of the total sum is multiplied by 1, next one by 10, next by 100, etc.

Example:

Operations of addition, subtraction, division, and multiplication in a decimal numerical


system are used in a way that is already known to us, so we won't discuss it further.

B.2 Binary numerical system

Binary numerical system differs in many aspects from the decimal system we are used to
in our everyday lives. Its numerical basis is 2, and each number can have only two
values, '1' or '0'. Binary numerical system is used in computers and microcontrollers
because it is far more suitable for processing than a decimal system. Usually, binary
number consists of binary digits 8, 16 or 32, and it is not important in view of the
contents of our book to discuss why. It will be enough for now to adopt this information.

Example:

10011011 binary number with 8 digits

In order to understand the logic of binary numbers, we will consider an example. Let's
say that we have a small chest with four drawers, and that we need to tell someone to
bring something from one of the drawers to us. Nothing is more simple, we will say left
side, bottom (drawer), and the desired drawer is clearly defined. However, if we had to
do this without the use of instructions like left, right, beneath, above, etc., then we would
have a problem. There are many solution to this problem, but we should look for one that
is most beneficent and practical! Lets designate rows with A, and types with B. If A=1, it
refers to the upper row of drawers, and for A=0, bottom row. Similarly with columns,
B=1 represents the left column, and B=0, the right (next picture). Now it is already easier
to explain from which drawer we need something. We simply need to state one of the
four combinations: 00, 01, 10 or 11. This characteristic naming of each drawer
individually is nothing but binary numerical representation, or conversion of common
numbers from a decimal into binary form. In other words, references like "first, second,
third and fourth" are exchanged with "00,01, 10 and 11".

What remains is for us to get acquainted with logic that is used with binary numerical
system, or how to get a numerical value from a series of zeros and ones in a way we can
understand, of course. This procedure is called conversion from a binary to a decimal
number.

Example:

As you can see, converting a binary number into a decimal number is done by calculating
the expression on the left side. Depending on the position in a binary number, digits carry
different values which are multiplied by themselves, and by adding them we get a
decimal number we can understand. Let's further suppose that there are few marbles in
each of the drawers: 2 in the first one, 4 in the second drawer, 7 in the third and 3 in the
fourth drawer. Let's also say to the one who's opening the drawers to use binary
representation in answer. Under these conditions, question would be as follows: "How
many marbles are there in 01?", and the answer would be: "There are 100 marbles in 01."
It should be noted that both question and the answer are very clear even though we did
not use the standard terms. It should further be noted that for decimal numbers from 0 to
3 it is enough to have two binary digits, and that for all values above that we must add
new binary digits. So, for numbers from 0 to 7 it is enough to have three digits, for
numbers from 0 to 15, four, etc. Simply said, the biggest number that can be represented
by a binary digit is the one obtained when basis 2 is graded onto a number of binary
digits in a binary number and thus obtained number is decremented by one.

Example:

This means that it is possible to represent decimal numbers from 0 to 15 with 4 binary
digits, including numbers '0' and '15', or 16 different values.
Operations which exist in decimal numerical system also exist in a binary system. For
reasons of clarity and legibility, we will review addition and subtraction only in this
chapter.

Basic rules that apply to binary addition are:

Addition is done so that digits in the same numerical positions are added, similar to the
decimal numerical system. If both digits being added are zero, their sum remains zero,
and if they are '0' and '1', result is '1'. The sum of two ones gives two, in binary
representation it will be a zero, but with transferring '1' to a higher position that is added
to digits from that position.

Example:

We can check whether result is correct by transferring these number to decimal numerical
system and by performing addition in it. With a transfer we get a value 10 as the first
number, value 9 as the second, and value 19 as the sum. Thus we have proven that
operation was done correctly. Trouble comes when sum is greater than what can be
represented by a binary number with a given number of binary digits. Different solutions
can be applied then, one of which is expanding the number of binary digits in the sum as
in the previous example.

Subtraction, like addition is done on the same principle. The result of subtraction between
two zeros, or two ones remains a zero. When subtracting one from zero, we have to
borrow one from binary digit which has a higher value in the binary number.

Example:

By checking the result as we did with addition, when we translate these binary numbers
we get decimal numbers 10 and 9. Their difference corresponds to number 1 which is
what we get in subtraction.

B.3 Hexadecimal numerical system

Hexadecimal numerical system has a number 16 as its basis. Since the basis of a
numerical system is 16, there are 16 different digits that can be found in a hexadecimal
number. Those digits are "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F". Letters A, B, C, D,
E and F are nothing but values 10, 11, 12, 13, 14 and 15. They are introduced as a
replacement to make writing easier. As with a binary system, here too, we can determine
with same formula what is the biggest decimal number we can represent with a specific
number of hexadecimal digits.

Example: With two hexadecimal digits

Usually, hexadecimal number is written with a prefix "$" or "0x" ,or suffix"h" , to
emphasize the numerical system. Thus, number A37E would be written more correctly as
$A37E, 0xA37E, or A37Eh. In order to translate a hexadecimal number into a binary
numerical system it is not necessary to perform any calculation but simple exchange of
hexadecimal digits with binary digits. Since the maximum value of a hexadecimal
number is 15, that means that it is enough to use 4 binary digits for one hexadecimal
digit.

Example:
By checking, that is transferring both numbers into decimal numerical system, we get a
number 228 which proves the accuracy of our action.

In order to get a decimal equivalent of a hexadecimal number, we need to multiply each


digit of a number with number 16 which is gradated by the position of that digit in
hexadecimal number.

Example:

Addition is, like in two preceding examples, performed in a similar manner.

Example:

We need to add corresponding number digits. If their sum is equal 16, write 0 and
transfer one to the next higher place. If their sum is greater than 16, write value above
and transfer 1 to the next higher digit.Eg. if sum is 19 (19=16+3) write 3 and transfer 1 to
the next higher place. By checking, we get 14891 as the first number, and second is
43457. Their sum is 58348, which is a number $E3EC when it is transferred into a
decimal numerical system. Subtraction is an identical process to those in previous two
numerical systems. If the number we are subtracting is smaller, we borrow from the next
place of higher value.

Example:

By checking this result, we get values 11590 for the first number and 5970 for the
second, where their difference is 5620, which corresponds to a number $15F4 after a
transfer into a decimal numerical system.

Conclusion
Binary numerical system is still the one that is most in use, decimal the one that's easiest
to understand, and a hexadecimal is somewhere between those two systems. It's easy
conversion to a binary numerical system and easy memorization make it, along with
binary and decimal systems, one of the most important numerical systems.

Glossary
Microcontroller
A processing unit with peripherals in one chip.

I/Opin
External microcontroller's connector pin which can be configured as input or
output. In most cases I/O pin enables a microcontroller to communicate,
control or read information.

Software
Information that microcontroller needs in order to be able to function.
Software can not have any errors if we want the program and a device to
function properly. Software can be written in different languages such as:
Basic, C, pascal or assembler. Physically, that is a file on computer disc.

Hardware
Microcontroller, memory, supply, signal circuits and all components
connected with microcontroller.The other way of viewing this (especially if
it's not working) is, that, hardware is something you can kick.

Simulator
Software package for PC which simulates the internal function of
microcontroller. It is ideal for checking software routines and all the parts of
the code which do not have over demanding connections with an outside
world. Options are installed to watch the code, movement around the
program back and forth step by step, and debugging.

ICE
ICE (In Circuit Emulator), internal emulator, very useful part of the
equipment which connects a PC instead of microcontroller on a device that
is being developed. It enables software to function on the PC computer, but
to appear as if a real microcontroller exists in the device. ICE enables you to
move through program in real time, to see what is going on in the
microcontroller and how it communicates with an outside world.

EPROM-emulator
EPROM Emulator is a device which does not emulate the entire
microcontroller like ICE emulator, but it only emulates its memory. It is
mostly used in microcontrollers that have external memory. By using it we
avoid constant erasing and writing of EPROM memory.

Assembler
Software package which translates source code into a code which
microcontroller can understand. It contains a section for discovering errors.
This part is used when we debug a program from errors made when program
was written.

HEX-file
This is a file made by assembler translator when translating a source file,
and has a form "understood" by microcontrollers. A continuation of the file
is usually Filename .HEX where the name HEX file comes from.

List-file
This is a file made by assembler translator and it contains all instructions
from source file with addresses and comments programmer has written. This
is a very useful file for keeping track of errors in the program. File extension
is LST which is where its name comes from.

Source-File
File written in the language understood by man and assembler translator. By
translating the source file, we get HEX and LIST files.

Debugging
Error made in writing a program, which error we are not aware of. Errors
can be quite simple such as typing errors, and quite complex such as
incorrect use of program language. Assembler will find most of these errors
and report them to '.LST' file. Other errors will need to be searched for by
trying it out and watching how device functions.

ROM,EPROM,EEPROM,FLASH,RAM
Types of memories we meet with microcontroller use. First one can not be
erased, what you write in it once, stays forever, and can not be erased. The
second is erasable with UV lamp. Third one can be erased electrically, using
voltage which microcontroller operates on. Fourth one is electrically
erasable, but unlike EEPROM memory it does not have such a great number
of cycles of writing and erasing at memory locations. Fifth one is fast, but it
does not hold back the contents as the previous when there is supply
shortage. Thus, program is not stored in it, but it serves for different
variables and inter-results.

Addressing
Determines and designates certain memory locations.

ASCII
Short for "American Standard Code for Information Interchange". It is
widely accepted type of coding where each number and letter have their
eight-bit code.

Carry
Transfer bit connected with arithmetic operations

Code
File, or section of a file which contains program instructions.

Byte, Kilobyte, Megabyte


Terms designating amounts of information. The basic unit is a byte, and it
has 8 bits. Kilobyte has 1024 bytes, and mega byte has 1024 kilobytes.

Flag
Bits from a status register. By their activation, programmer is informed
about certain actions. Program activates its response if necessary.

Interrupt vector or interrupts


Location in microcontroller memory. Microcontroller takes from this
location information about a section of the program that is to be executed as
an answer to some event of interest to programmer and device.

Programmer
Device which makes it possible to write software in microcontroller
memory, thus enabling the microcontroller to work independently. It
consists of the hardware section usually connected with one of the ports and
software section used on the computer as a program.

Von-Neumann Architecture

Microcontrollers based on the Von-Neumann architecture have a single "data"


bus that is used to fetch both instructions and data. Program instructions and data are
stored in a common main memory. When such a controller addresses main memory, it
first fetches an instruction, and then it fetches the data to support the instruction. The two
separate fetches slows up the controller's operation.

Harvard Architecture

Microcontrollers based on the Harvard Architecture have separate data bus and
an instruction bus. This allows execution to occur in parallel. As an instruction is being
"pre-fetched", the current instruction is executing on the data bus. Once the current
instruction is complete, the next instruction is ready to go. This pre-fetch theoretically
allows for much faster execution than Von-Neumann architecture, but there is some
added silicon complexity.

CISC

Almost all of today's microcontrollers are based on the CISC Complex Instruction
Set Computer) concept. The typical CISC microcontroller has well over 80 instructions,
many of them very powerful and very specialized for specific control tasks. It is quite
common for the instructions to all behave quite differently. Some might only operate on
certain address spaces or registers, and others might only recognize certain addressing
modes.

The advantage of the CISC architecture is that many of the instructions are macro-
like, allowing the programmer to use one instruction in place of many simpler
instructions.

RISC

The industry trend for microprocessor design is for Reduced Instruction Set
Computers (RISC) designs. This is beginning to spill over into the microcontroller
market. By implementing fewer instructions, the chip designed is able to dedicate some
of the precious silicon real-estate for performance enhancing features. The benefits of
RISC design simplicity are a smaller chip, smaller pin count, and very low power
consumption.

Among some of the typical features of a RISC processor:


- Harvard architecture (separate buses for instructions and data) allows
simultaneous access of program and data, and overlapping of some operations for
increased processing performance
- Instruction pipelining increases execution speed
- Orthogonal (symmetrical) instruction set for programming simplicity; allows each
instruction to operate on any register or use any addressing mode; instructions have no
special combinations, exceptions, restrictions, or side effects

Simulators
A simulator runs your microcontroller program on a host machine (such as your PC).
You can step through the code to see exactly what is happening as the program runs.
Contents of registers or variables can be altered to change the way the program runs.
Eliminates the erase/burn/program EPROM cycle common in microcontroller program
development. You can work out ideas or learn about microcontrollers by experimenting
with small code fragments and watching on the screen what happens. A simulator can't
support real interrupts or devices, and usually runs much slower than the real device the
program is intended for.

Some manufacturers have a cross between a software simulator and the hardware
emulator - a hardware simulator. This is a piece of equipment that plugs into your
target, and the pins will toggle and react like they should - just MUCH slower.

Emulators
If you've got the money, this is the equipment you want to develop your system with
(yeah, that's right, a preposition at the end of a sentence!). A [usually] expensive piece
of hardware that even for the cheaper versions will run you at least $700. An emulator is
a sophisticated device that pretends that it is the microprocessor itself, while at the same
time capturing information. It provides full and total control over your target, while at
the same time not requiring any resources from the target. The emulator can either be a
stand alone device with its own display, or it can be interface to a PC.

Machine and Assembly languages


Machine language is the program representation as the microcontroller understands it
i.e. it is in form of 0s and 1s. It is not easy for humans to read and is a common cause of
migraine headaches. Assembly language is a human-readable form of machine language
which makes it much easier for us. Each assembly language statement corresponds to one
machine language statement (assembly language contains mnemonics).

An assembly/machine language program is fast and small. This is because you are in
complete charge of what goes into the program. Of course, if you write a slow, large,
stupid program, then it will run slowly, be too big, and be stupid.

Interpreters
An interpreter is a high level language translator that is closer to natural language.
The interpreter itself is a program that sits resident in the microcontroller. It executes a
program by reading each language statement one at a time and then doing what the
statement says to do. The two most popular interpreters for microcontrollers are BASIC
and FORTH.

Compilers
A compiler is a high level language translator that combines the programming ease
of an interpreter with greater speed. This is accomplished by translating the program (on
a host machine such as a desktop PC) directly into machine language. The machine
language program is then burned onto an EPROM or downloaded directly to the
microcontroller. The microcontroller then executes the translated program directly,
without having to interpret first.

The most popular microcontroller compilers are C and BASIC. PL/M, from Intel,
also has some popular support due to that company's extensive use of that language.

Fuzzy Logic and Neural Networks


Fuzzy Logic and neural networks are two design methods that are coming into favor
in embedded systems. The two methods are very different from each other, from
conception to implementation. However, the advantages and disadvantages of the two
can complement each other.

The advantage of neural networks is that it is possible to design them without


completely understanding the underlying logical rules by which they operate. The neural
network designer applies a set of inputs to the network and "trains" it to produce the
required output. The inputs must represent the behavior of the system that is being
programmed, and the outputs should match the desired result within some margin of
error. If the network's output does not agree with the desired result, the structure of the
neural network is altered until it does. After training it is assumed that the network will
also produce the desired output, or something close to it, when it is presented with new
and unknown data.

In contrast, a fuzzy-logic system can be precisely described. Before a fuzzy control


system is designed, its desired logical operation must be analyzed and translated into
fuzzy-logic rules. This is the step where neural networks technology can be helpful to
the fuzzy-logic designer. The designer can first train a software neural network to
produce the desired output from a given set of inputs and outputs and then use a software
tool to extract the underlying rules from the neural network. The extracted rules are
translated into fuzzy-logic rules.

Fuzzy logic is not a complete design solution. It supplements rather than replaces
traditional event control and PID (proportional, integral, and derivate) control techniques.
Fuzzy logic relies on grade of membership and artificial intelligence techniques. It works
best when it is applied to non-linear systems with many inputs that cannot be easily
expressed in either mathematical equations used for PID control or IF-THEN
statements used for event control.
In an effort to change fuzzy logic from a "buzzword" (as it is in most parts of the
world) to a well established design method (as it is in Japan), most manufacturers of
microcontrollers have introduced fuzzy logic software. Most software generates code for
specific microcontrollers, while other generates C code which can be compiled for any
microcontroller.

You might also like