You are on page 1of 520

See discussions, stats, and author profiles for this publication at: https://www.researchgate.

net/publication/349812349

Introduction to Microcontrollers & Embedded Systems

Book · January 2017

CITATIONS READS

0 323

1 author:

Muhammad El-Saba
Ain Shams University
71 PUBLICATIONS   58 CITATIONS   

SEE PROFILE

Some of the authors of this publication are also working on these related projects:

Modeling & Numerical Simulation of all Semiconductor Devices View project

Advanced Electronic Engineering Encyclopedia (AEEE) View project

All content following this page was uploaded by Muhammad El-Saba on 14 June 2021.

The user has requested enhancement of the downloaded file.


Introduction to Microprocessors INDEX

Introduction to Microcontrollers
&
Embedded Systems
________________________________________________

Dr. Eng. Muhammad H. El-SABA


Faculty of Engineering, Ain-Shams University in Cairo
Department of Electronics and Communications

5th Edition 2015

i
Dr. Eng. Muhammad El-SABA
Introduction to Microprocessors INDEX

Copyright © 2003-2014, by the author. All rights reserved.

1st Edition 2003


2nd Edition 2004
3rd Edition 2005
4th Edition 2011

Reproduction or translation of any part of this work, without permission


of the copyright owner, is unlawful. Requests for permission or further
information should be addressed to the author, at the Dept. of Electronic
Engineering, Faculty of Engineering, 1 Sarayat street, 11517Abbasia,
Cairo, Egypt. E-mail Address mhs@saudia.com

Deposit No. 2003/10177 (Dar El-Kottob)

ii
Dr. Eng. Muhammad El-SABA
Introduction to Microprocessors INDEX

PREFACE
Introduction to Microcontrollers & embedded systems deals with the
basic principles of microcontrollers, with emphasis on the Intel x51, PIC
and ARM microcontrollers and their associated peripheral chips. The
8051 microcontroller assembly language is depicted in order to
emphasize the sequence of operations and their implications on the
hardware design.

The book handles the microcontroller architecture, memory organization,


and assembly programming. It also looks at techniques such as handling
external interrupt, handshaking and serial communication with a PC.

The book covers the Intel 8051 (8-bits) and compatible microcontrollers,
and jet a look at other advanced 16-bit and 32-bit microcontrollers, from
Intel and other manufacturers.

The course aims to give the students and graduate engineers a general
understanding in microcontroller-based applications and embedded
systems. Embedded systems are defined as the small computers
incorporated in consumer devices in order to perform application specific
functions. Such embedded systems usually contain a CPU core, or an
application specific integrated processor (ASIP) or even a digital signal
processor (DSP). Assembly and C-programming of such cores is briefly
explained in the course. So, another goal of this book is to provide a
foundation that supports the multithreading style of programming of
embedded software. This should enable the student to enter the workplace
with microcontroller design skills, an understanding of microcontroller
applications and essential assembly language programming for the 8051
family of microcontrollers. The students will need to be familiar with
basic logic circuits and software design using flow charts or functional
decomposition.

Applications in various instrumentation, data acquisition, control, and


communication fields are discussed. Programming examples on stepper
motors, door access control, temperature and light control, speed control,
process control, sensor transceivers, remote controls, and
communications between microcontrollers and the PC are also provided.
We presented 12 complete projects, including a microcontroller
programmer kit, an 8051 emulator and an EPROM / Flash programmer.
iii
Dr. Eng. Muhammad El-SABA
Introduction to Microprocessors INDEX

INDEX
Subject Page
Preface
CH1 Introduction to Microcontrollers 1
1-1. Microprocessors versus Microcontrollers 1
1-2. Microcontrollers Modules 4
1-2.1. Central Processing Unit (CPU) 5
1-2.2. Memory (RAM, ROM, EPROM, E2PROM, FLASH) 6
1-2.3. Microcontroller Busses 7
1-2.4. I/O Parallel Ports 7
1-2.5. Serial Communication Interface (SCI) Ports 8
1-2.6. Serial Peripheral Interface (SPI) 10
1-2.7. Timers 10
1-2.8. Watchdog Timer (WDT) 10
1-2.9. Analog-to-Digital (A/D), Digital-to-Analog (D/A) Converters 11
1-2.10. Pulse-Width Modulation (PWM) port 12
1-2.11. Control-Area Network (CAN) Interface Bus 13
1-2.12. Inter-integrated Circuit (I2C) Interface Bus 13
1-2.13. JTAG Port 14
1-3. Microcontrollers versus DSP's 15
1-4. RISC & CISC Microcontrollers 16
1-5. Microcontrollers History (INTEL, ZILOG, MOTOROLA) 16
1-6. Microcontrollers Development Tools 18
1-6.1. Editors 20
1-6.2. Compilers / Interpreters and Assemblers 20
1-6.3. Microcontroller Simulators 21
1-6.4. Microcontroller Emulator (Hardware Simulator) 23
1-6.5. Monitor ROM 24
1-6.6. Terminal Emulator (PC terminal) 24
1-6.7. Microcontroller Soft Core 24
1-7. Microcontroller IDE 25
1-8. Microcontroller Development Boards 27
1-9. Summary 29
1-10. Problems 31
CH2 Architecture of Microcontrollers 33
2-1. Introduction 33
2-2. Architecture of the 8051 Microcontrollers 33
2-2.1. Pin Description of the 8051 Microcontrollers 35
2-2.2.. Internal Architecture of the 8051 Microcontrollers 39
2-2.3. Program Status Word (PSW) Register 40
2-2.4. Timers / Counters, TMODE & TCON Registers 41
2-2.5. Serial Port 48
2-2.6. Serial Port Control (SCON) Register 49
2-2.7. Interrupt Map & Interrupt Enable (EI) Registers 52
2-2.8. Structure of I/O Ports 53
iv
Dr. Eng. Muhammad El-SABA
Introduction to Microprocessors INDEX

Subject Page
2-3. Architecture of x51 variants, from Atmel. 56
2-4. Architecture of the PIC Microcontrollers 59
2-4.1. Architecture of PIC 8-bit Microcontrollers 59
2-4.2. Internal Architecture of PIC16 60
i. CPU 62
ii. Program memory (FLASH) 62
iii. Data memory (RAM) 63
iv. I/O Ports 63
v. Timer Modules 65
vi. Watchdog Timer 66
vii.PIC Interrupt Map 67
viii. INTCON Register 67
ix. A/D Converters 68
x. Reset Circuit 69
xi. Configuration Register 69
2-4.3. Architecture of PIC 16-bit Microcontrollers 70
2-5. Architecture of the ARM Microcontrollers 71
2-6. Architecture of the AVR Microcontrollers 77
2-7. Comparison between 8051, PIC, AVR and ARM 93
2-8. Summary 95
2-9. Problems 99
CH3 Memory Organization of Microcontrollers 101
3-1. Introduction 101
3-2. Memory Organization of the 8051 Microcontrollers 102
3-2.1. Data Memory of the 8051 Microcontrollers 103
i. Special Function Registers (SFR) 103
ii. Direct & Indirect Address Memory 104
iii. External Data Memory (External RAM) 112
3-2.2. Program Memory the 8051 Microcontrollers 113
3-2.3. Connecting Program memory (ROM) to the 8051 114
3-2.4. Connecting External Serial EEPROM to the 8051 114
3-3. Memory Organization of the PIC Microcontrollers 116
3-4. Memory Organization of the ARM Microcontrollers 125
3-5. Memory Organization of the AVR Microcontrollers 129
3-6. Summary 135
3-7. Problems 140
CH4 Intel 8051 Instructions & Assembly Language 141
4-1. Intel’ 8051 Instruction Format 141
4-2. The 8051 Basic Instruction Set (Alphabetical) 142
4-3. The 8051 Addressing Modes. 144
4-4. The 8051 Instruction Set (by category). 146
4-4.1. Arithmetic Instructions 146
4-4.2. Data Transfer Instructions 147
4-4.3. Logic Instructions 149
4-4.4. Boolean Instructions 150

v
Dr. Eng. Muhammad El-SABA
Introduction to Microprocessors INDEX

Subject Page
4-4.5. Branching Instructions 121
4-4.6. Conditional Jump Instructions 122
4-5. Stack Operations in 8051 Microcontrollers 153
4-6. The 8051 Assembly Programming 155
4-6.1. Instruction Format for A51 Assembler. 156
4-6.2 Handling Interrupts in 8051 Assembly 161
4-6.3. The 8051 Development Tools (AS31, A51) 165
i. AS31 Assembler Program 165
ii. AS51 Assembler Program 166
iii. AS51 Directives 167
iv. AS51 .Asembler Startup Code 169
v. Variable Initialization Code 170
4-7. Summary 172
4-8. Problems 175
CH5 PIC Instructions &Assembly Language Programming 177
5-1. PIC Instruction Format 177
5-2. PIC Instructions By Category 180
5-3. PIC Microcontroller Instruction Set (Alphabetical) 182
5-4. PIC Addressing Modes 184
5-5. Stack Operations PIC Microcontrollers 187
5-6. PIC Development Tools 188
5-6. 1. PIC Assembler 189
5-6. 2. PIC Assembly Program Template 195
5-6. 3. PIC In-circuit Debugging & Emulation 196
5-7. Summary 197
5-8. Problems 198
CH6 ARM Instructions &Assembly Language Programming 199
6-1. ARM Instruction Format 199
6-2. ARM Instruction Set 202
6-2.1. ARM Instruction Set (Alphabetic) 202
6-2.2. ARM Instruction Set (By category) 208
i. Memory access instructions 208
ii. Arithmetic instructions 209
iii. Multiply and divide instructions 210
iv. Shift Operations 211
v. Bitfield instructions 213
vi. General data processing instructions 214
vii. Branch and control instructions 215
viii. Conditional execution 216
ix. Condition flags 216
x. Miscellaneous instructions 217
xi. DSP enhancement instructions 217
vi
Dr. Eng. Muhammad El-SABA
Introduction to Microprocessors INDEX

Subject Page
6-3. ARM Addressing Modes 219
6-3.1. Immediate (Literal) Addressing 219
6-3.2 Register Indirect Addressing 220
6-3.3. Indirect Addressing with an Offset Addressing 220
6-3.4. Auto-indexing Pre-indexed Addressing 220
6-3.5. Auto-indexing Post-indexed Addressing 221
6-3.6. PC Relative) Addressing 221
6-3.7. Stack Operations 222
6-4. ARM Development Tools 223
6-4.1. ARM IDE’s 223
6-4.2. ARM Assembly Language 225
6-4.3. ARM In-circuit Debugging & Emulation 234
6-5. Summary 235
6-6. Problems 237
CH7 Microcontroller Programming with C Language 239
7-1. Introduction 239
7-2. Programming with C51 Language 240
7-2.1. Data Types in C51 240
7-2.2. Memory Models 241
7-2.3. Sequencing Instructions 242
7-2.4. Pointers in C51 243
7-2.5. Functions in C51 244
7-2.6. Cx51Library Routines 252
7-2.7. Basic I/O 259
7-2.8. C51 Compiler Directives 260
7-2.9. Interfacing C51 to AS51 262
7-2.10. Interfacing C51 to Real-time Systems (RTOS) 267
7-3. Programming with SDCC 269
7-4. PIC Programming with C 271
7-5. ARM Programming with C/C++ 280
7-5.1. ARM C-Compilers 281
7-5.2. C-Coding Hints for ARM Cortex-M3 282
7-6. C-Code Comparisons (x51, PIC, AVR, ARM) 285
7-7. Summary 290
7-8. Problems 292

CH8 Building a Microcontroller Embedded System 293


8-1. Developing a Microcontroller System 293
8-2. Writing the System Software 293
8-3. Building a Prototype 296
8-4. Serial Interface Driver Chips 299
8-5. Connecting Keypads & Keyboards 303

vii
Dr. Eng. Muhammad El-SABA
Introduction to Microprocessors INDEX

Subject Page
8-6. Connecting Displays 316
8-6.1. Connecting 7-Segment Display 316
8-6.2. Connecting LCD & Host Interface 322
8-6.3. Parallel or Serial LCD Drivers 324
8-6.4. Programming the HD44780 LCD Driver 326
8-7. Tri-state Buffers and Tri-State Buses 341
8-8. A/D Converter Chips 342
8-8.1. Programming The ADC8080 Chip 343
8-8.2. DAC Chip 352
8-9. X-10 Control Interface & X-10 Protocol 353
8-10. Building a Demo Board 358
8-11. Microcontroller Development Boards. 366
8-12. Building Your own 8051 Development Board 368
8-13. Summary 372
8-14. Problems 373
CH9 Miscellaneous Microcontroller Projects 375
9-1. Introduction 375
9-2. LED Blinker (AT89C2051 Microcontroller) 374
9-3. Flashing a LED ( PIC PIC16F876 microcontroller) 375
9-4. Playing Sound 381
9-5. Light sensor 355
9-6. Temperature sensor 361
9-7. Data Collection (Analog Data Acquisition) 367
9-8. Stepper Motor Controller 372
9-9. Clock Controller 376
9-10. Digital Thermometer with LCD 382
9-11. Microcontroller Programmer 393
9-12. EPROM / FLASH Memory Programmer 406
9-13. Summary 411
9-14. Problems 444
CH10 Microcontroller Selection Guide 445
10-1. Introduction 445
10-2. Intel Microcontrollers 414
10-3. Atmel CISC Microcontrollers 415
10-4. Atmel CISC Microcontrollers 415
10-5. Motorola Microcontrollers 420
10-6. Zilog Microcontrollers 424
10-7. Microchip Microcontrollers 426
10-8. ARM Microcontrollers 429
10-9. Microcontroller Evaluation Boards 432
10-10. Summary 435
viii
Dr. Eng. Muhammad El-SABA
Introduction to Microprocessors INDEX

References 437
Appendices 439
A: Summary of 8051 Instruction Set, 441
A2: Test of all 8051 Opcodes 461
B: Summary of PIC Instruction Set, 477
C: Summary of ARM Instruction Set, 481
D: Hex File Format, 489
Glossaries 491

ix
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

CHAPTER 1: Introduction to Microcontrollers

1-1, Microprocessors Versus Microcontrollers


The microprocessor (P) is a programmable very large scale integrated
(VLSI) circuit, which usually contains millions of transistors, and is able
to execute so many sets of user-defined programs. Programs are written,
using a set of predefined instructions, which the microprocessor can
handle. This set is called the microprocessor instruction set. A
microprocessor system consists of a central processing unit (CPU), a
memory and input/output (I/O) devices.

The microcontroller (MC) is an integrated microprocessor-based control


system on a single chip. For instance, the INTEL MC 8051
microcontroller is based on the 8080 microprocessor. There is a basic
difference between a micro-controller and a CPU. Peripheral components
like a RAM, ROM, a serial port or an ADC or DAC are on the same chip.

Fig. (1-1.a). Schematic diagram showing the structure of a microcontroller.

The CPU is the part of the microcontroller where information is


processed (added, subtracted… etc.). Memory is the controller part which
stores information in the form of binary numbers (0’s and 1’s code). Input
devices, like keypads, permit us to input information to the controller
system. Also, output devices, like liquid-crystal display (LCD), permit us
to get back the information from within the MC after they have been
processed.

1
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

That means it is possible to realize complex control functions with only


one MC chip. In fact, you can use a microcontroller in a variety of control
systems. Whatever you like to do with a MC, it only depends on the
software. You can feed the microcontroller chip with a set of instructions
to follow and it will run through those instructions and do exactly what
you want to do. Microcontrollers are actually used in so many products in
our daily life, like cars and home appliances such as TV’s, microwave
ovens, washer machines and air-conditioning control.

By using a microcontroller in a hardware design the workflow is


completely different. Most of the time you spend in writing software but
on the other hand you can reduce the hardware design to a minimum.

Microcontrollers are usually "embedded" inside some other device (often


a consumer product) so that they can control the features or actions of the
product. Another name for a microcontroller, therefore, is "embedded
controller". So, an embedded controller is a computer that is embedded
into some device for some purpose other than to provide general purpose
computing.

A microcontroller-based application has an input device (e.g., a sensor or


a keypad) and often a small output device (e.g., an LCD). The
microcontroller takes input from the input and controls the application by
sending signals to its different components. For example, the
microcontroller inside a TV takes input from the remote control and
displays output on the TV screen (OSD). The controller controls the
channel selector (TV tuner), the speaker system and certain adjustments
on the picture tube electronics such as tint and brightness. The engine
controller in a car takes input from sensors such as the oxygen and knock
sensors and controls things like fuel mix and spark plug timing. A
microwave oven controller takes input from a keypad, displays output on
an LCD display and turns the microwave generator on and off.

As shown in figure (1-1), the microprocessor system is interfaced to


external memory and input/output ports via a group of wires, called
buses. There exist three main buses in the microprocessor system,
namely: data bus, address bus, and control bus. The address bus (that
may be 8, 16 or 32 bits wide) sends an address to memory. The data bus
(that may be 8, 16 or 32 bits wide) can send data to memory or receive
data from memory. The control bus has RD (read) and WR (write) lines
to tell the memory whether it wants to set or get the addressed location.

2
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

Fig. (1-1.b). Schematic diagram showing how a microcontroller can be interfaced to


monitor and control various devices.

Tuner IF Filter

Power Supply

Memory Audio Amp

Fig. (1-1.c). Schematic diagram showing how the Philips TV controller TDA935 lies
in the heart of a recent color TV system.

The actual CPU used in a microcontroller can vary from simple 4-bit
processor to 32-bit microprocessor. Standard microprocessors, such as the
Motorola 68000 or National 32032, are also used as powerful embedded
3
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

controllers. For example, the cell phone often contains a 8-bit Z-80
microprocessor, while the Garmin global positioning system (GPS)
contains a low-power version of the Intel 80386 32-bit microprocessor.
One of the important features of microcontrollers is their tiny size and
low cost. In addition, microcontrollers are often "ruggedized" in some
way. For instance, the microcontroller controlling a car's engine has to
work in extreme temperatures. A car's microcontroller in north Europe
has to work fine in 0C weather, while the same microcontroller in upper
Egypt might be operating at 50C° or more.

1-2. Microcontroller Modules:


Figure (1-2) depicts the general architecture of a microcontroller on a
single chip. As shown, a microcontroller is usually composed of several
modules, namely:

• Microprocessor core (8-bit, or 16-bit, or 32-bit microprocessor core)


• Memory (ROM, RAM)
• Input/Output (I/O) ports
• Timers
• Analog-to-digital converter (ADC) with multiplexed input channels
• Serial communication interface (SCI)

MCU

Figure (1-2). General architecture of a microcontroller unit (MCU).

4
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-2.1 CPU
The CPU (central processing unit) is the part which is responsible of data
processing in the microcontroller. The CPU has the ability to perform the
following functions:
• Executes a stored set of instructions (programs),
• Accesses memory for read and write operations,
• Accesses input and output ports.

Fig. (1-3). Simplified model of the central processing unit (CPU) .

5
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

The CPU has internal memory locations called registers. Registers are
therefore memory locations whose role is to help with performing various
mathematical operations or any other operations with data wherever data
can be found.

1-2.2. Memory
Memory is part of the microcontroller whose function is to store data.
The easiest way to explain the memory function is to describe it as one
big closet with lots of drawers. If we suppose that we marked the drawers
in such a way that they can not be confused, any of their contents will
then be easily accessible. It is enough to know the designation of the
drawer and so its contents will be known to us for sure. Memory
components are exactly like that.

For a certain input we get the contents of a certain addressed memory


location and that's all. So, we have two new concepts: memory addressing
and memory location. Memory consists of all memory locations, and
addressing is nothing but selecting one of them. This means that we need
to select the desired memory location on one hand, and on the other hand
we need to wait for the contents of that location to be put on the data bus.
Beside reading from a memory location, memory must also be provided
by a means for writing onto it. This is done by supplying an additional
line called control line. We will designate this line as R/W (read/write).
Control line is used in the following way: if R/W=1, reading is done, and
if opposite is true then writing is done on the memory location.

The microcontroller internal memory is composed of:

• ROM to store the program in the final product

• RAM to store the data in the final product

The one-time programmable (OTP) memory is a sort of ROM that is most


commonly used in embedded systems.

However, during development phases, one can use erasable program-able


ROM (EPROM), which is erasable by ultraviolet light, or electrically-
erasable programmable ROM (EEPROM). The FLASH EPROM is a sort
of EEPROM, which is faster in reprogramming (up to 100 times) than
conventional EPROM with a security features to protect FLASH code.

6
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

Fig. (1-4). A simplified model of the memory unit.

1-2.3. Microcontroller Buses


As we stated above, the bus represents a group of 8, 16, or more wires.
There are two main buses in the microcontroller: address bus and data
bus. The first one consists of as many lines as the amount of memory we
wish to address and the other one is as wide as data, or the connection
line. First one serves to transmit address from CPU memory, and the
second to connect all blocks inside the microcontroller.

1-2.4. I/O Parallel Ports


Digital input/output (I/O) ports are the means by which the MC can be
interfaced to the external world. There are several types of ports: input,
output or bi-directional ports. Digital I/O ports are usually 8-bits ports.
When working with ports, first of all it is necessary to choose which port
we need to work with, and then to send data to, or take it from the port.

7
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

Fig. (1-5). Simplified model of I/O units.

1-2.5. Serial Communication Ports


The serial communication unit gives us the possibility of communication
with the outside world. It enables us to reduce the number of data lines in
such a way that we don't lessen its functionality. We are working with
three lines only, one line is used for sending data, other for receiving, and
the third one is used as a reference line (ground). In order for this to
work, we need to set the rules of exchange of data. These rules are called
protocol. Protocol is therefore defined in advance so there wouldn't be
any misunderstanding between the sides that are communicating with
each other.

The serial communication interface (SCI) in the microcontrollers


implements this protocol. SCI is a sort Universal Asynchronous Receiver
Transmitter (UART) device. However, like the standard PC UART, the
SCI has additional signals that allow it to be connected to a MODEM.
Some of SCI units can support also synchronous working.

As we have separate lines for receiving and sending, it is possible to


receive and send data at the same time (full-duplex). The serial
communication unit enables full duplex communication is called a.
Unlike the parallel transmission, data moves here bit by bit, or in a series
of bits what defines the term serial communication comes from. After the
reception of data we need to read it from the receiving location and store
it in memory as opposed to sending where the process is reversed. Data
goes from memory through the bus to the sending location, and then to
the receiving unit according to the protocol.
8
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

Figure (1-6). The serial port of a microcontroller

It should be noted that logic levels from a SCI port are TTL (+5V).
Therefore, a TTL to RS232 interface chip (like MAX232) is required to
translate voltage levels. RS232 to TTL interface chip is included in the
PC (16050 UART).

Fig. (1-7a). Simplified model of full-duplex serial communication over 3 lines

9
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-2.6. Serial Peripheral Interface (SPI):


The SPI is a 4-wire serial interface to connect the MC to a particular
peripheral device such as a liquid crystal display (LCD) or a serial
analogue-to-digital converter (ADC) or even a programmable transceiver.

Fig. (1-7b). Simplified model of full-duplex serial communication over 3 lines

It can be used to communicate between two MCs. This allows a number


of MCs in a system to share data. The SPI also allows one master MC to
control a number of other MCs (slaves). Motorola 6811 has a built-in
Serial Peripheral Interface (SPI). Also, some of PIC MCs have a special
SPI device called the Synchronous Serial Port (SSP). According to
Motorola, the SPI signals are: serial clock (SCLK or SCK), which is
always driven by the master, master-in slave-out data (MISO or SDO),
master-out slave-in data (MOSI or SDI) and chip select (CS or SS).

1-2.7. Timers
The timer is one of the important blocks that gives us information about
time, duration, protocol etc. The basic unit of the timer is a free-run
counter which is in fact a register whose numeric value increments by one
in even intervals, so that by taking its value during periods T1 and T2 and
on the basis of their difference we can determine how much time has
elapsed. This is a very important part of the microcontroller whose
understanding necessary.

10
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

Fig. (1-8). Simplified model of timer unit.

1-2.8. Watchdog Timer


One more thing is requiring our attention is a flawless functioning of the
microcontroller during its run-time. Suppose that as a result of some
interference (which often occurs in industry) our microcontroller stops
executing the program, or worse, it starts working incorrectly.

Of course, when this happens with a computer, we simply reset it and it


will keep working. However, there is no reset button we can push on the
microcontroller. To overcome this obstacle, a block called watchdog is
incorporated. This block is in fact another free-run counter where our
program needs to write a zero in every time it executes correctly. In case
that program gets stuck, zero will not be written in, and counter alone will
reset the microcontroller upon achieving its maximum value. This will
result in starting executing the program again, and correctly this time.
That is an important element of every program to be reliable without
man's supervision.

Fig. (1-9). Simplified model of watchdog timer (WDT) unit.

1-2.9. Analog-to-Digital (A/D) & Digital-to-Analog (D/A) Converters


Analog-to-digital converters (ADCs) are used to sample analog inputs
into the microcontroller. The ADC performance needs careful choice of
the following:

11
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

- On chip sample and hold to accommodate AC signal sampling


- Control over the sample clock and synchronization between channels
- CPU loading at higher sampling frequencies

Fig. (1-10). Simplified model ADC and DAC units.

The 8-bit MCs have limited performance due to the limited ADC
resolution. They may only be used for simple data logging and
measurement applications.

1-2.10. Pulse-Width Modulation (PWM) Port:


Pulse Width Modulation (PWM) is a technique widely used in modern
switching circuit to control the amount of power given to the electrical
device. The PWM port outputs a pulse with programmable width (or duty
cycle) according to a certain digital signal (a byte or a 16-bit word). For
instances, if the input signal byte is equal to 00H (0D), the duty cycle of
the output PWM signal is 0 and if the input signal is FFH (255D) the
output pulse duty cycle is 100%. Any other input signal between 0 and
255 is divided by 256. For example, if the input signal byte is equal to
80H (128D), the duty cycle of the output PWM signal is 50%. The output
signal from the PWM port is usually averaged (rectified and filtered) such
that its average is proportional to the input digital signal value. PWM
blocks are used in DC motor control, and switch-mode power supplies.

Duty Cycle = 100 * T1/(T1+T2) %

Fig. (1-11). Simplified model of PWM port.

12
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-2.11. Control Area Network (CAN) Interface:


The control area network (CAN) was originally developed for the
automobile industry in order to reduce the amount of cabling in a vehicle.
Serial data is transmitted around a number of sub-system units (CAN
interface units). Each device to be controlled and each device sending
data to another part of the automobile contains a CAN interface device.

Each CAN interface is called a node. The data messages transmitted from
any node on a CAN bus do not contain addresses of either the
transmitting node or of any intended receiving node. Instead, an identifier
that is unique throughout the network labels the content of the message
(e.g. RPM, headlights on). All other nodes on the network receive the
message and each performs on acceptance test on the identifier to
determine if the message is relevant to that particular node.

Fig. (1-11). Simplified model of a CAN network

1-2.12. Inter-Integrated Circuit (I2C) Interface Bus


The I2C bus is a simple 2 wire serial interface which has been developed
by Philips. It was developed for 8-bit applications and is widely used in
consumer electronics, automotive and industrial applications. In addition
13
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

to microcontrollers, several peripherals also exist that support the I 2C bus.


The I2C bus physically consists of 2 active wires and a ground wire. The
active wires, SDA (Serial Data) and SCL (Serial Clock), are both
bidirectional. IC devices can act as a receiver and/or a transmitter. As
shown in Fig. 1-12, the I2C bus is a multi-master, multi-slave network
interface. The master is usually the microcontroller and the clock is
always generated by the master. Up to 128 devices can exist on the
network and they can be spread out over 10 meters. Each node
(microcontroller or peripheral device) may initiate a message, and then
transmit or receive data. Each node on the network has a unique address
which accompanies any message passed between nodes. The I2C bus
interface typically has data transfer speeds up to 3.4 Mb/s.

Fig. (1-12). Simplified model of I2C bus.

1-2.13 . The JTAG Port.


The JTAG is a standard for providing external test access to integrated
circuits serially, via a 5-pin interface. JTAG is an acronym for a the Joint
Test Action Group, which developed the standard. The JTAG standard
has been adopted as an IEEE standard (IEEE 1149 Standard Test Access
Port and Boundary-Scan).

JTAG ports have been very widely embraced by processor and


microcontroller manufacturers. The JTAG serial port is sometimes used
for in-circuit programming (ISP) of microcontrollers.

14
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

Fig. (1-13). Simplified model of the JTAG bus. The connector pins are:
TDI (Test Data In), TDO (Test Data Out), TCK (Test Clock), TMS (Test Mode
Select) and TRST (Test Reset) optional.

1-3. Microcontrollers versus Digital Signal Processors (DSP)


Microcontrollers react to and control events - DSPs execute repetitive
math-intensive algorithms. The most basic thing a DSP does is to
Multiply and Accumulate (MAC). The number of data bits a DSP can
Multiply and Accumulate will determine the dynamic range (and
therefore the application). Today many embedded applications require
both types of processors, and semiconductor manufacturers have
responded by introducing microcontrollers with on-chip DSP capability
and DSPs with on-chip microcontrollers.

15
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-4. RISC & CISC Microcontrollers


According to the nature of the instruction set of their CPU core,
microcontrollers can be divided into two basic architectures:

• Reduced instruction set controllers (RISC),


• Complex instruction set controllers (CISC).

RISC systems are characterized by small set of short primitive


instructions, from which a computer programmer can build more complex
routines and programs. On the other hand, CISC systems are using more
advanced, but complex, large set of instructions. In fact, most of today's
microcontrollers are based on the CISC concept. The typical CISC
microcontrollers have over 80 instructions, many of them are very
powerful and very specialized for specific control tasks. The Intel
MCS8051 and the Motorola MC6805 are CISC systems, while the
Microchip PIC has RISC architectures. The normalized instruction set of
RISC microcontrollers are all equal in length (3 bytes for the PIC) and
few in number (33 instructions for the PIC). Also, all RISC instructions
are single clock cycle except for branching instructions which usually
take 2 clock cycles. Generally speaking, RISC microcontrollers are
usually faster than CISC microcontrollers.

1-5. Microcontrollers History


We mention here some of the well known microcontrollers, which have
been available for sale commercially. The small 8-bit chips (like 8051
and 6805) are the best-selling type of microcontrollers. This kind of small
processors are found embedded in a wide variety of electronics devices,
ranging from small gadgets and home equipment control to car
electronics. Those small controllers are flying off the shelves at the rate
of more than 3 billion new chips per year (more than half of the
microprocessor sale per units). But they're not very expensive, so they're
less than 15% of the fiscal tonnage.
At the opposite end of the scale are-big surprise-32-bit microprocessors.
This category includes PC processors like Pentium 4 and Athlon, of
course, but also dozens of embedded processors such as PowerPC, 68k,
MIPS, and ARM chips. Most (98% or so) 32-bit processors are used in
embedded systems, not PCs. ARM-based chips alone do about triple the
volume that Intel and AMD peddle to PC makers. PC processors are only
2% of all processors in volume, but PC processors are 50% of all
processor sales in money. This means that PC processor makes 15% of all
the money made from every type of semiconductor from every company
everywhere in the world. The reason for this is that PC processors are
16
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

expensive (modern Intel CPU can cost $300) and they are sold in large
volumes. Taken as a whole, the average price for a microprocessor,
microcontroller, or DSP is just over $6. Most microprocessors are much
cheaper than that, but then there are always those expensive ones in the
market that pull the average price up. The current list mainly includes
late 1980's and 1990's microcontroller implementations. We have
categorized the microcontrollers by company.

INTEL MicrocontrollersIn 1980 Intel has introduced the 8051 as the


first member of the MCS-51 family of microcontrollers. Today hundreds
of cheap 8051 derivatives are available from dozens of manufacturers.
This makes the MCS-51 architecture so interesting for both professionals
and hobbyists.

Fig. (1-14). The Intel’ 8051 microcontroller.

ZILOG Microcontrollers After the introduction of Intel 8051, ZILOG


introduced Z8. The Z8 is a family of 8-bit microcontrollers. The Z86Exx
microcontrollers are 8-bit OTP versions of Z8 microcontrollers. The
members of this family contain up to 16 kB on-chip ROM, 236 Byte on-
chip RAM and up to 32 I/O lines. In addition, all Z86E members have 6
interrupt inputs, 2 timer/counters, a WDT and run at 12 MHz.

MICROCHIP Microcontrollers:
The Microchip PIC microcontrollers are very popular microcontrollers.
The PIC12/16/18 microcontroller families are based on the Harvard RISC
microprocessor core. The PIC microcontrollers are easily programmable
and very cheap. The PIC16F84 seems to be the "standard" for small
gadgets you see in armatures projects.

17
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

MOTOROLA Microcontrollers:
The Motorola MC6805/8/11 are all members of a family of 8-bit
microcontrollers, which are based on the MC6800 microprocessor. The
Motorola MC6812 is a family of 16-bit microcontrollers, which are also
based on the MC6808 core, but with enhanced functionalities. For
instance, the MC68HCx12 microcontroller devices are composed of
standard on-chip peripherals including a 16-bit central processing unit,
32-KB flash EEPROM, 1-KB RAM, 768-byte EEPROM, serial
communications interface (SCI), serial peripheral inter-face (SPI), 10-bit
analog-to-digital converter (ADC), four-channel pulse-width modulator
(PWM). The chip is the first 16-bit microcontroller to include both byte-
erasable EEPROM and flash EEPROM.

ARM Embedded Processors


ARM (Advanced RISC Machines) is the industry leading provider of
16/32-bit embedded RISC microprocessor solutions. The company
licenses its low-cost, low-power RISC processors to leading international
electronics companies, like Philips (now NXP), Atmel, Zilog, Intersil,
etc.). ARM microprocessor cores are rapidly becoming a RISC standard
in portable communications, handheld computing, multimedia, and digital
consumer markets. ARM partners are also creating new microcontrollers
and embedded solutions containing ARM cores.

1-6. Microcontrollers Programming & Development Tools


Programming microcontrollers is an easy 3 steps process:

A) writing the code


B) compiling/debugging the code
C) uploading the code to the microcontroller

Figure (1-15) depicts the steps and tools, which are used for the
development of a microcontroller-based application. The software
development starts by editing an assembly program for the targeted
microcontroller (or its C-language equivalent), compiling it uploading the
equivalent binary code file (usually in hexadecimal form) to the
microcontroller, using a microcontroller programmer. Each step may
need a specific tool with several options.

Alternatively you can do all the steps with the aid of a microcontroller
programmer with its integrated software package, for editing, compiling,
writing and verifying code.

18
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

Fig. (1-15). The microcontroller development tools. The code is written to the micro-
controller memory (EPROM or Flash) by a microcontroller programmer (below).
The software development tools consist of the following elements:

19
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-6.1. File Editor:


This is where you will compose the code that ultimately will run on your
8051 board and make you project function. All PC operating systems
include a text editor, and there are many free text editors available on the
internet. All Microsoft Windows systems have NOTEPAD, which is a
very simple editor.

1-6.2. Compiler/Interpreter or Assembler:


Your source code will be turned into a .HEX file by either an Assembler
or Compiler, or even an interpreter, depending on your choice of
programming language.

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 or PL/M.


ADA has also many adherents among those designing on the larger
microcontroller chips (16-bit and 32-bit). A few companies supply a
BASIC compiler for several of the more popular microcontrollers.
Execution speed is drastically increased over interpreted BASIC since the
microcontroller is freed from the task of interpreting the statements as the
program runs.

C-language is now the language of choice for the entire universe. C is


used on computers from the tiny microcontroller up to the largest Cray
supercomputer. Although a C program can be a bit tedious at times to
read, it is a powerful and flexible development tool. Although a high level
language, it also gives the developer access to the underlying machine.
There are several very good and cheap C compilers available for the more
popular microcontrollers. It is widely used, available, supported, and
produces fairly efficient code fast and compact.

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
Java. JVM – Java (TM) Virtual Machine - was added lately to the list of
20
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

interpreters, after the invention of the language and concepts by Sun


Microsystems. Java was adopted enthusiastically by programmers all
over the world and has finally found its way into the embedded
environment. Java provides a new and revolutionary concept, geared
towards the use of portable software applications which can be
dynamically downloaded over a network, rather than kept on the local
disk or in the local memory of a specific computer. This way, the client
computer does not need to keep all the applications, since they can be
dynamically downloaded from the server whenever required. Another
Java main feature is its Operating-System (OS) independent capability.
Java is also a language. The Java language is a new object-oriented
programming language, also developed by Sun Microsystems. In its very
own architecture it is particularly suited to the development of Java's
portable application pieces of software, called applets.The nicest thing
about developing a system with an interpreter is that you can build your
program interactively. You first write a small piece of code and then you
can try it out immediately to see how it works. When the results are
satisfactory, you can then add additional components until the final
product is achieved.

There exist so many vendors for microcontroller development tools and


integrated environments, such as Keil Software Inc., Ashling,
RealView™, Hitex, Nohau and Phytec. You can also find so many free
development tools under Windows, such as the AS51 assembler, and the
SDCC C-compiler1.

1-6.3. Microcontroller Simulator:


The microcontroller simulator allows you to test small programs out on
your PC without downloading them to the microcontroller. You can see
all the registers change as the program is stepped through each
instruction. This greatly speeds up the debugging process, and is an
educational tool that shows how each instruction affects the various parts
of the microcontroller. 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.

1
You can downloads both the AS31 assembler and SDCC C-Compiler at the
following site: http:// www.pjrc.com/tech/8051/tools

21
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

Fig. (1-16). Some screens of microcontroller simulator.

22
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-6.4. Microcontroller Emulator:


The microcontroller emulator is a hardware simulator. It is a sophisticated
device that pretends that it is the microcontroller itself, while at the same
time capturing information. The emulator provides full and total control
over your target, while at the same time not requiring any resources from
the target. If you've got the money, this is the ideal equipment you need to
buy to develop your system with.

The emulator is usually expensive piece of hardware such that the


cheapest versions will run you around $1000 or more (depending on the
microcontroller type and the emulator facilities). The microcontroller
emulator can either be a stand alone device with its own display, or it
may be interfaced to a PC. The following figure depicts a microcontroller
emulator with attached target circuit.

Fig. (1-17). The microcontroller emulator setup. The picture below shows an in-
circuit emulator (ICE), without the PC connection.

23
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

The so called In-Circuit Emulators (ICE) have recently replaced the


conventional microcontroller emulators and offer advanced features. Note
that JTAG to USB adapters such as the Keil ULINK®2 are not strictly
emulators. They provide the connection between the debugging module
inside the production chip with the debugger software (or microcontroller
simulator) running on a PC. You can think of the debugging technology
being moved from an external ICE to inside the 8051 chip. Of course, it is
impossible to move all the ICE features onto the chip – this would take up
too much space on the microcontroller chip.

1-6.5. Monitor ROM:


The Monitor ROM is the microcontroller code that runs when your
microcontroller board boots. It looks like an operating system of the
microcontroller. It provides interactive menus that allow you to download
other code, run it, manipulate memory and perform other functions. Some
development boards come with loaded monitor ROM in the non-erasable
internal memory of the microcontroller. For instance, the 8051
development board from PJRC, come with the PAULMON22 monitor,
installed on the internal ROM of the 8752 microcontroller. We’ll present
a brief description of the 8051 development board, and how it can be
implemented, in chapter 9. Using the monitor, you can run your code on
the board. It is also possible to download your code to non-volatile
memory on the board together with a "auto-start header" that makes the
monitor run your code automatically when the board boots.

1-6.6. Terminal Emulator:


To communicate with your 8051 board, via a PC, you must run a terminal
emulator program. Using this terminal, you will be able to transmit your
.HEX file from the terminal to the board and run its code, observe its
results and information via the serial port. Microsoft was providing a
Hyper-Terminal with old versions of Windows. Nowadays, the
HyperTerminal is no longer supported. You can use Telnet or any
equivalent utility.

1-6.7. Microcontroller Soft Cores:


Instead of buying an 8051 chip, just get an FPGA and program into it the
8051 core along with the peripherals you need plus other logic that you
require in your project and you now have your own 8051-on-a-chip.
This may be necessary if the supplier of that 8051 chip with the special
unique peripheral that you absolutely have to use is discontinued.
2
You can download this from http://www.pjrc.com/tech/8051/paulmon2.html

24
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-7. Microcontroller IDE


Below is a comparison of some of the popular microcontroller IDEs
(integrated development environments).

Keil uVision

Cost Free
 ARM
 Cortex
Supported Architectures
 8051
 C116
Supported Compilers WinAVR
Supported Programmers SiLabs USB Debug Adapters
Simulation Yes
Programming/Debugging Methods: JTAG
Latest Version

AVR Studio

Cost Free
Supported Operating Systems Recent Windows
All 8-bit and 32-bit ATMEL MCUs
 ATmega
Supported Architectures
 ARM
 AT91xx
 C
Supported Languages
 C++
Supported Compilers WinAVR
All of the AVR programmers
 AVR ONE!
 JTAGICE MKII
 JTAGICE3
Supported Programmers
 STK600
 QT600
 AVRISP MKII
 AVR Dragon
Programming/Debugging Methods: JTAG
Latest Version 6.0 (as of July 2014)

25
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

Designed to be used with ATMEL micro-controllers (the IDE is built by


ATMEL after-all). Supports most if not all of ATEML’s programmers.
It can use Win-GCC to compile. The lastest version (5.0 beta) has had a
major facelift (over v4) and given it that much needed feature boost to
keep in the IDE game. Now it has auto-complete other Visual Studio
features!

The ASF (Atmel Software Framework), is a collection of firmware


libraries that is set-up graphically through Atmel Studio. The libraries
include things such as UART drivers, common signal processing
algorithms, e.t.c. They can provide a high-level interface to the hardware
which promotes modular, reusable code. Atmel Studio also promotes an
integrated app-store, simulator (which of July 2014 only supports AVR
devices), and shared workspace.

Eclipse

Cost Free (and open-source)


 Windows
Supported Operating Systems  Linux
 MacOS
Supported Architectures Heaps
 Java
 PHP
Supported Languages
 C/C++
 Many more…
Supported Compilers  GCC
Supported Programming/Debugging Methods: JTAG
Latest Version Unknown

Eclipse would be one of the most popular open-source IDE’s out there.
It’s popularity is partly due to the fact it supports so many frameworks
with it’s modular design. The Eclipse project was started initially in
2001 and the not-for-profit corporation The Eclipse Foundation was
founded in 2004. With support for many large frameworks such as Java,
C/C++, PHP and mobile platforms, it is very powerful. It also support
TEX based mark-up languages. There are many different releases of
Eclipse that you can download.

26
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-8. Microcontroller Development Boards


To do the low level tasks, it is helpful to have total control of the CPU
and Arduino may be a better fit.

The Arduino hardware consists of an open-source hardware board


designed around an 8-bit Atmel AVR microcontroller, or a 32-bit Atmel
ARM. At a conceptual level, when using the Arduino software stack, all
boards are programmed over an RS-232 serial connection, or USB,
implemented using USB-to-serial adapter chips such as the FTDI FT232.

The software consists of a standard programming language compiler. An


Arduino's microcontroller is also pre-programmed with a boot loader that
simplifies uploading of programs to the on-chip flash memory. Arduino
boards can be purchased pre-assembled or as do-it-yourself kits.
Hardware design information is available for those who would like to
assemble an Arduino by hand. The Arduino libraries make it very easy to
start with a working demo and modify the code for your particular
application. The optional Ethernet Shield makes it very easy to make a
SD card data logger, or a web enabled sensor port.

Fig. 1-18. The Arduino development board 240


27
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

The Arduino integrated development environment (IDE) is a cross-


platform application written in Java, and is derived from the IDE for the
Processing programming language and the Wiring projects. It is designed
to introduce programming to artists and other newcomers unfamiliar with
software development. It includes a code editor with features such as
syntax highlighting, brace matching, and automatic indentation, and is
also capable of compiling and uploading programs to the board with a
single click. A program or code written for Arduino is called a "sketch".

Arduino programs are written in C or C++. The Arduino IDE comes with
a software library called "Wiring" from the original Wiring project, which
makes many common input/output operations much easier. Users only
need define two functions to make a runnable cyclic executive program:

Fig. 1-19. Arduino_Stepper motor driver

If your goal is to do something on a larger scale perhaps RPI is more


suitable. The Raspberry Pi is a credit-card-sized single-board computer
developed in the UK by the Raspberry Pi Foundation with the intention of
promoting the teaching of basic computer science in schools (Price about
25USD). The Raspberry Pi has a Broadcom BCM2835 system on a chip
(SoC), which includes an ARM1176JZF 700 MHz CPU,512MB RAM,
USB port and can use external SD Cards, for booting or storage. The
Foundation provides Debian and Arch Linux ARM distributions for
download. Also planned are tools for supporting Python as the main
programming language. However, writing a device driver from scratch
for Linux is not trivial.
Below

28
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-9. Summary
Microcontrollers play a key role in both our daily lives and in industry by
performing as the core system controllers in a range of different products.
If the family car is included, for example, a single household may use
between 100 to 200 or more microcontrollers

There exist so many companies that fabricate x51 derivatives, such as:

 Atmel,
 Analog Devices,
 Cypress Semiconductor,
 Dallas Semiconductor,
 Goal,
 Hynix,
 Infineon,
 Intel,
 NXP (founded by Philips),
 OKI, Silicon Labs, SMSC,
 STMicroelectronics,
 Synopsis,
 TDK,
 Temic,
 Texas Instruments, and
 Winbond.

29
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

The 8051 is a component of many modern products being manufactured


today. For instance, the on-off button on your vacuum cleaner might be
merely an input to an 8051 which in turn is turning on a triac. This allows
a cheap on-off switch plus motor control. Other examples include the
display on your microwave oven or even the display board of your car or
of a Cisco router, all might be controlled by the 8051. Your PC keyboard
is probably powered by an 8051. This list of applications is actually very
long.

30
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

1-10. PROBLEMS

1) Draw a block diagram showing the architecture of a simple


microprocessor system and explain briefly its main components. Explain
why it is necessary to have an address bus, a data bus and a control bus
in microprocessor systems.

2) Draw a block diagram showing the architecture of a simple


microcontroller and explain briefly its main components.

3) Explain, how can you isolate low voltage microcontrollers from high
voltage loads that they are controlling.

4) What’s the difference between RISC and CICS Microcontrollers? Give


examples of real commercial microcontrollers.

5) The main importance of ARM microprocessors is providing operation


with,
a) Low cost and low power consumption
b) Higher degree of multi-tasking
c) Lower error or glitches
d) Efficient memory management?

6) What is function of the following programs: microcontroller operating


systems, microcontroller programmer, assemblers and linkers.

31
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1

32
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

CHAPTER 2: Architecture of Microcontrollers

2-1. Introduction
In this chapter we start looking at the internal architecture of some
famous microcontrollers, with emphasis on the Intel 8051 micro-
controllers (MCS51).
Actually, the Intel 8051 is the most successful microcontroller device in
the world nowadays. In the last decade, a lot of companies like Atmel,
Dallas Semiconductors, Philips, OKI, Cypress, and Samsung, have
developed new variants, with special features, all based on the 8051 core.
It’s well known that the 8051 is based on the Intel 8080 CISC
microprocessor, which is based on the Harvard architecture.
Microcontrollers based on the Harvard Architecture have separate data
bus and an instruction bus. This means that data and instructions are
stored into separate memories that are accessed separately. On the other
hand, 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 (if such data is needed).

Fig. 2-1. Harvard versus Von Neumann architecture.

2-2. Architecture of 8051 Microcontrollers


The Intel 8051 is a general purpose 8-bit microcontroller. The basic
version of 8051 comes in a 40 pin dual-inline package (DIP) including 32
I/O lines, two 16-bit Timers/Counters, 2 Interrupts, 128 Bytes on-chip
RAM, 4k ROM and a serial UART channel. The 8031 is a ROM-less
version of the 8051. Also the 8751 is identical to 8051 but it has an
internal 4kB EPROM. The 8051 can address up to 64kB of external RAM
31
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

and 64kB of external ROM. The pin-out diagram of the 8051 is shown in
figure 2-2. Also Table 2-1 explains the functions of each pin.

Fig. 2-2. Pin-out diagram of the Intel 8051 microcontroller

32
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2-2.1. Pin Description of the 8051 Microcontroller


Out of the 40 pins of the 8051 microcontroller, there exist 32 I/O pins,
which are dedicated for connecting the 8051 to the outside world.
Table 2-1. Pin assignment of the 8051 microcontroller.

Pin # Pin name Function Pther Function


1 P1.0 Port 1 bit 0
2 P1.1 Port 1 bit 1
3 P1.2 Port 3 bit 2
4 P1.3 Port 3 bit 3
5 P1.4 Port 3 bit 4
6 P1.5 Port 3 bit 5
7 P1.6 Port 3 bit 6
8 P1.7 Port 3 bit 7
9 RST Reset input
10 P3.0 / RXD Port 3 bit 0 Receive (serial input)
11 P3.1 / TXD Port 3 bit 1 Transmit (serial output)
12 P3.2 / INT0 Port 3 bit 2 External Interrupt 0
13 P3.3 / INT1 Port 3 bit 3 External Interrupt 1
14 P3.4 / T0 Port 3 bit 4 Timer 0 input
15 P3.5 / T1 Port 3 bit 5 Timer 1 input
16 P3.6 / WR Port 3 bit 6 Write memory strobe
17 P3.7 / RD Port 3 bit 7 Read memory strobe
18 XTL2 Crystal oscillator output
19 XTL1 Crystal oscillator input
20 VSS (GND) Ground
21 P2.0 / A8 Port 2 bit 0 Address 8
22 P2.1 / A9 Port 2 bit 1 Address 9
23 P2.2 / A10 Port 2 bit 2 Address 10
24 P2.3 / A11 Port 2 bit 3 Address 11
25 P2.4 / A12 Port 2 bit 4 Address 12
26 P2.5 / A13 Port 2 bit 5 Address 13
27 P2.6 / A14 Port 2 bit 6 Address 14
28 P2.7 / A15 Port 2 bit 7 Address 15
29 PSEN Program Store Enable
30 ALE / PROG Address Latch Enable Program pulse input
31 EA / VPP External memory Access Programming Supply
32 P0.7 /AD7 Port 0 bit 7 Address/Data 7
33 P0.7 /AD6 Port 0 bit 6 Address/Data 6
34 P0.7 /AD5 Port 0 bit 5 Address/Data 5
35 P0.7 /AD4 Port 0 bit 4 Address/Data 4
36 P0.7 /AD3 Port 0 bit 3 Address/Data 3
37 P0.7 /AD2 Port 0 bit 2 Address/Data 2
38 P0.1 /AD1 Port 0 bit 1 Address/Data 1
39 P0.0 /AD0 Port 0 bit 0 Address/Data 0
40 VCC Supply Volt

33
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Through these pins, information can be brought into or out of the 8051
microcontroller. The 32 pins show up inside the package as 4 parallel
ports (P0 through P3). Each port is 8 bits wide (e.g. P0 has 8 lines,
namely: P0.0 through P0.7). Each port can be inputs or outputs to or from
the outside. Besides being parallel I/O, P0, P2, and P3 have special
functions assigned to them. P0 and P2 are used for external memory
interface, which may not be used since there is plenty of memory inside
the 8051. These 16 pins can be used for input/output. But if we were
talking about an 8051, this is where external memory would connect. The
8051 has 16-bit address bus (A0-A15) and 8-bit data bus (D0-D7). The
first 8-bit of the 8051 address bus are multiplexed with the 8-bit data bus
(AD0-AD8). The External Access pin, EA, is used to access external
memory by connecting pin 31 to ground (VSS). When EA is strapped to
ground, the MC51 can fetch code from external program memory starting
at 0000H up to FFFFH (64k). When EA is strapped to VCC, the MCU
fetches code from the internal program memory (on-chip EEPROM).

Figure 2-3. Photograph of an 8051 microcontroller.

Half of the pins of port3 of the 8051 microcontroller are used for some
special functionality. The other four pins of P3 will be used as regular
inputs and outputs, not using their special functions.

Also, two pins of port3 (P3.0, P3.1) can be used for serial
communications (RXD, TXD). Through these pins, serial data can be
transmitted (via TXD) or received (via RXD) with another computer.
This is how we will load a program into the 8051 from a PC. More details
about the serial port come in the following sections.

Two more pins of port 3 (P3.3, P3.3) are dedicated for a different kind of
input called interrupts (INT0, INT1). As the name implies, an interrupt
34
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

is some event which interrupts normal program execution. An interrupt


doesn't alter the program the microcontroller is doing, it just temporarily
stops it. Each time an interrupt occurs, the current program is temporarily
stopped and an interrupt service routine (ISR) is executed and when
complete, the CPU returns to the current program. Further details about
interrupts and interrupt handling will come in the subsequent sections.
The Address Latch Enable (ALE / PROG) outputs a signal for latching
the low byte of the address during accesses to external memory. This pin
is also the program pulse input (PROG) during EPROM programming
for the 87C51.

Figure 2-4. Connecting a crystal oscillator to the 8051 microcontroller.


35
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

The ALE operation can be disabled (if desired) by setting bit 0 of the
special function register (SFR) at memory location 8EH. With this bit set,
the pin is weakly pulled high. The ALE disable feature will be terminated
by reset. The Program Store Enable (PSEN) pin is the Read strobe to
External Program Memory. When the 80C51/BH is executing from
Internal Program Memory, PSEN is inactive (high). When the device is
executing code from External Program Memory, PSEN is activated twice
each machine cycle, except that two PSEN activations are skipped during
each access to External Data Memory. The XTL1 and XTL2 are input
and output of the built-in on-chip crystal oscillator. To drive the device
from an external clock source, XTL1 should be driven, while XTL2 is left
unconnected, as shown in figure 2-5.

Figure 2-5. Connecting a crystal oscillator to the 8051 microcontroller.


36
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

There are no requirements on the duty cycle of the external clock signal,
since the input to the internal clocking circuitry is through a divide-by-
two flip-flop, but minimum and maximum high and low times specified
on the data sheet must be observed. An external oscillator may encounter
as much as a 100 pF load at XTAL1 when it starts up. This is due to
interaction between the amplifier and its feedback capacitance. The 8051
takes 12 clock cycles to make an instruction cycle. This makes 921.6
instructions per second (0.9216 MIPS) at 11.0592 MHz clock.

2-2.2. Internal Architecture of 8051 Microcontrollers


As shown in figure 2-6, the internal architecture of the 8051 contains 34
general purpose 8-bit registers. The register A is the accumulator called
A. It is used to accumulate the results of various instructions like ADD or
SUB. The register B is also used in arithmetic/logical operations. The
other 32 registers are arranged as part of the 8051 internal RAM.

Fig. 2-6. Architecture of Intel 8051 microcontroller


37
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Besides, there exist special function registers (SFR). This is where P0,
P1, P2, and P3 are located. The accumulator (A), the 16-bit program
counter (PC), the 16-bit interrupt priority (IP), interrupt enable (IE), the
8-bit program status word (PSW), stack pointer (SP), the two 16-bit
timers (TL, TH) make part of these special registers.

SFRs
Port 0 Stack Data Port Timer Timer Timers
Pointer Pointer Control Control Mode
P0 SP DP PCON TCON TMOD TL TH
DPL DPH TL0 TL1 TH0 TH1

Port 1 Port 2 Interrupt Port 3 Inst Prog status Accumula


Enable pointer word tors
P1 SCON SBUF P2 IE P3 IP PSW A B
Figure 2-7(a). Special function registers in the 8051 microcontroller..

Figure 2-(b). Addresses of special function registers in the 8051 microcontroller.

2-2.3. Program Status Word (PSW) Register


The Program Status Word (PSW) resides in the SFR space. The PSW
contains several status bits that reflect the current state of the CPU. As
shown in the table below, the PSW contains the Carry bit CY, the
Auxiliary Carry AC (for BCD operations), the two register bank select
bits RS0 and RS1, the Overflow flag OV, a Parity bit P, and two user-
38
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

definable status flags (F0). The Carry bit CY, other than serving the
functions of a Carry bit in arithmetic operations, also serves as the
“Accumulator” for a number of Boolean operations. The Parity bit P
reflects the number of 1s in the Accumulator P=1 if the Accumulator (A)
contains an odd number of 1s, and P=0 if the Accumulator contains an
even number of 1s. Thus the number of 1s in the Accumulator plus P is
always even. Two bits in the PSW are uncommitted and maybe used as
general purpose status flags.

PSW
CY AC F0 RS1 RS0 OV - P
Carry Aux carry Overflow Parity
Fig. 2-8(a). The program status word.

The bits RS0 and RSl are set to select one of the four data memory banks
(Bank0, Bank1, Bank2 and Bank3). These 4 memory banks are part of
the internal RAM of the microcontroller. Each bank contains 8 bytes. The
selection of which banks is being referred to, is made on the basis of the
bits RS0 and RS1 bits of the PSW, according to the following table.

Table 2-2. Register selection bits (of the PSW) and their functions.

RS0 RS1 Function


0 0 Select Memory Bank 0
0 1 Select Memory Bank 1
1 0 Select Memory Bank 2
1 1 Select Memory Bank 3

2-2.4. Timers and Counters of the 8051


The 8051 has two 16-bit Timer/Counters (T0 and T1) assigned at P3.4
and P3.5 (pins 14 and 15). Each timer can be divided to two 8-bit
registers (TL0, TH0, TL1, TH1). Timers are used to generate
programmable timing intervals, from the internal clock, while counters
are usually used to count an external pulse source. However, counters can
also serve for internal loop counting, during execution of programs. The
functions of the 8051 Counter/Timers are controlled by the Timer Control
(TCON) and the Timer Mode control (TMOD) registers, as follows:

TMODE
Gate C/T M1 M0 Gate C/T M0 M1
Timer 1 Timer 0
Fig. 2-8(b). The Timer mode register.
39
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

The TMODE signals are duplicated for both T0 and T1. The gate signals
(Gate) control the START/STOP of the timer counter for T0 and T1.
The C/T signals select the operation mode of the counter timers (counter
or timer). If C/T = 1, then the counter operation is selected, otherwise
(C/T=0) the timer operation is selected. The M0 and M1 are used to
select the timer modes according to the following table:
Table 2-3. Timer mode selection.
M1 M0 Mode Function Frequency
TL TH
0 0 0 13-bit Timer/Counter fosc / 32 fosc /384
0 1 1 16-bit Timer /Counter
1 0 2 Auto-reload (TL from TH)
1 1 3 Two 8-bit Timers

As shown in the following figure, half of the Timer Control (TCON)


signals are flags and half of them are interrupt signals.

TCON
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
Timer Flags Interrupt Signals
Fig. 2-9.The Timer control register.

The TCON register signals are assigned as follows:

TF0: Timer 0 Overflow flag,


TF1: Timer 1 Overflow flag,
TR0: Timer 0 Run control. Setting TR0 to '1' enables Timer0 to count.
TR1: Timer 1 Run control. Setting TR1 to '1' enables Timer1 to count.
IE0: External Interrupt0 Edge flag. Set to '1' when INT0 signal goes from
high to low.
IE1: External Interrupt1 Edge flag. Set to '1' when INT1 signal goes from
high to low.
IT0: External Interrupt signal type. Set to '1' to enable falling edge INT0.
IT1: External Interrupt signal type. Set to '1' to enable falling edge INT1.

Note that the Timer/Counter modes depend on both TMODE and TCON
bits. The only difference between Timer and counter functions are the
source of pulses. The timer takes its input from the clock oscillator
(divided by 12), while counters take their input from external pulse
40
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

source. The maximum external pulse source (for 8051 counters) is given
by the crystal frequency divide by 24. The following figure depicts the
Timer/Counter modes

Figure 2-10. Timer/Counter modes in the 8051 microcontroller.


41
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Note 2-1. Timers & Counters


Every microcontroller comes with one or more built-in timer/counters. The term
timer/counter itself reflects the fact that the underlying counter hardware can be
configured to count either clock pulses (like a timer) or irregular event pulses (like a
counter). We use the term “timer” rather than “timer/counter” for the actual hardware
block, in the name of simplicity.

Timer basics
A typical timer will consist of a prescaler, an N-bit timer/counter register (typically N
is 8, 16 or 32 bits), one or more N-bit capture registers, and one or more N-bit
compare registers. There will also be control and status registers to configure and
monitor the timer. Note that this section is called Timers/Counters. The fundamental
hardware involved is an up-counter, which counts incoming pulses. A counter, any
counter, becomes a timer when the incoming pulses are at a fixed, known frequency.
I will often use the terms “counter” and “timer” interchangeably, but just keep in mind
that the hardware is always a counter, and that the counter becomes a timer if we are
feeding it a fixed, known frequency to count. It is also worth noting that the size in
bits of a timer is not directly related to the size in bits of the CPU architecture.
Nothing prevents an 8-bit microcontroller from having 16-bit timers (most do, in
fact), nor does anything prevent a 32-bit uC from having 16-bit timers (and some do).
Something else that you may see are uCs that have multiple timers of different size.
For example, most AVRs have both 8-bit and 16-bit timers, and some LPC2xxx
devices have both 32-bit and 16-bit timers.

Prescaler
The prescaler takes the basic timer clock frequency (which may be the CPU clock or
some higher or lower frequency) and divides it by some value before feeding it to the
timer, according to how the prescaler register(s) are configured. The prescaler values
that may be configured might be limited to a few values (powers of 2), or they may be
any integer value from 1 to 2^P, where P is the number of prescaler bits. The purpose
of the prescaler is to allow the timer to be clocked at the rate you desire. For short
timers (8 and 16-bit), there will be a tradeoff between resolution (high resolution
requires a high clock rate) and range (high clock rates cause the timer to overflow
more quickly). For example, you cannot (without some tricks) get 1us resolution and a
1sec maximum period using a 16-bit timer. If you want 1us resolution you are limited
to about 65ms maximum period. If you want 1sec maximum period, you are limited to
about 16us resolution. The prescaler allows you to juggle resolution and maximum
period to fit your needs. As an example of a fixed prescaler, many devices allow for
fixed prescale values of 1, 8, 64, 256 and 1024. If the system clock frequency is e.g.
8MHz, this results in a timer clock period of 0.125, 1, 8, 32 or 128usec per clock tick.
Likewise, the 9S12 prescaler allows fixed prescale values in powers of 2: 1, 2, 4, 8,
16, 32, 64 and 128. Such configurable prescalers are more flexible than fixed
prescalers, but in practice the fixed selection prescalers are usually adequate. When a
timer/counter is configured as a counter, it is most commonly used with some
timebase (another timer) to count pulses per some interval.
Timer Registers & Timer Flags
The timer register is typically aj N-bit up-counter, with the ability to read and write

42
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

the current count value, and to stop or reset the counter. As discussed, the timer is
driven by the prescaler output. Any regular pulses which drive the timer, whatever
their source, are often called “ticks” and that is the term which will be used here.
Understand that timers do not necessarily time in seconds or milliseconds or
microseconds, they time in ticks. Depending on the hardware design and software
configuration, the rate of these ticks may be configured to some human-friendly value
such as e.g. 1 us or 1 ms, or some value which makes sense for a particular design.

Capture Registers
A capture register is a register which can be automatically loaded with the current
counter value upon the occurrence of some event, typically a transition on an input
pin. The capture register is thus used to take a “snapshot” of the timer at the moment
when the event occurs. A capture event can also be configured to generate an
interrupt, and the ISR can save or otherwise use the just-captured timer snapshot.
Since the capture happens in hardware, there is no latency error introduced into the
snapshot value as there would be if the capture was done in software. Capture
registers can be used to time intervals between pulses, to determine the high and low
times of input signals, and to time the intervals between two different input signals.

Compare / Match Registers


Compare registers (sometimes also called match registers) hold a value against which
the current timer value is automatically and continuously compared. A compare
register is used to trigger an event when the value in the timer register matches the
value in the compare register. If the timer/counter is configured as a timer, using
compare registers will let you generate events (output pin changes and/or interrupts
and/or timer resets) at known and precise times. If the T/C is configured as a counter,
the compare registers can generate events based on preset counts being achieved. One
example of the use of a compare register is to generate a timer “tick”, a fixed timer
interrupt used for system software timing.
Some Ways to Use Timers
Here are some examples of different ways to use timers. The examples are just for
understanding of how timers work and can be used.

Timer Polling
While timers are most commonly used in conjunction with timer-generated interrupts,
it is also useful to understand how timers can be used in a polling situation. Polling
means sitting in a software loop, reading some register or memory location, and
waiting for some value in that location.

43
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

// poll for a value in a memory location


while ( Location_Im_Polling != VALUE_IM_WAITING_FOR )
; // wait for this location to have certain value or poll for specific bit(s) to go high
while ( !(Location_Im_Polling & MY_BITMASK) )
; // wait for bit(s) of MY_BITMASK to go high
Polling a timer is intermediate between simple cycle-counting on one hand, and timer-
generated interrupts on the other. The advantage of polling a timer is that the
accuracy of the timer is for the most part retained. The disadvantage is that the time
the μC spends polling the timer is a wasted time.

Polling for a Timer Value


This is a technique you probably never want to use in a serious project, but it’s useful
to help you start thinking about how timers work. This technique is very similar to
your earlier software delay loops, with the difference being that now, instead of
timing by monitoring a variable that is incremented (or decremented) in software, you
will monitor the hardware timer register. Notice the similarity: Software delay loop
(COUNT is the number of software loops to wait)
1. Set variable to 0
2. Increment variable
3. Check if variable is at COUNT
4. If not, loop to #2
5. If yes, finished
Timer register polling loop (COUNT is the number of timer ticks to wait)
1. Set timer register to 0
2. Increment timer register (this happens in the hardware, not the software!)
3. Check if timer register is equal to or greater than COUNT
4. If not, loop to #3
5. If yes, finished
The difference is simply in which timer variable is monitored, and in how it is
incremented. The advantage of using the hardware timer is that you can do other
work e.g. service interrupts and you will not lose accuracy, unless you happen to be
doing the other work at the exact time the timer register reaches your COUNT.
Polling for a Timer Flag
This is another technique you probably never want to use in a serious project, but it
will introduce you to one of the useful flags (hardware status bits) that are associated
with timers: Timer overflow flag polling loop (COUNT is the number of ticks to wait)
1. Set timer register to 0-COUNT
2. Increment timer register (this happens in the hardware, not the software!)
3. Check if timer overflow flag is set
4. If not, loop to #3
5. If yes, finished
This method utilizes the timer overflow flag, which will be set when the timer register
counts over from -1 to 0. -1 would be 0xFF for an 8-bit timer, 0xFFFF for a 16-bit
timer, and 0xFFFFFFFF for a 32-bit timer. Since the flag signals when the timer goes
to zero, we start the timer at 0-COUNT to get COUNT ticks. The advantage of this
method over timer register polling is that we have an unambiguous indication of the
end of the interval.
44
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

There are some pathological possibilities in the timer register polling, if the COUNT
value is near N-1, where one could miss the COUNT value and have the timer roll
over to 0 and then we’d end up waiting another 2^N ticks. By checking instead for
the overflow flag, even if we missed the exact time it was set, the flag will never unset
by itself, so we will always detect it as soon as our software polling loop comes
around to the next check. Another advantage is that the code to compare a given
COUNT may be larger and slower than the code to check for a single bit flag.

Timer overflow interrupt


Now we begin to get into the natural pairing that exists between timers and interrupts.
This method is similar to the timer overflow polling loop except that now the timer
overflow triggers an interrupt, and the ISR can handle the end of the timing interval
directly, or it can signal the main code to handle the end of the interval. Whereas with
the polling method the software had to clear the overflow flag, the hardware on many
microcontrollers will automatically clear the flag when the timer is configured to
generate an interrupt.

Timer compare interrupt with automatic timer clear


This method is similar to the timer overflow interrupt method, but the interrupt is
generated by match between the timer register and a compare register. The compare
event which triggers the interrupt also automatically clears the timer register, so for
the first time we have a configuration that can generate repetitive timing intervals with
no slippage or loss of accuracy between intervals. This is a major advance in our
timer operation. While it is often useful to be able to achieve single timing intervals,
it is much more useful to be able to achieve repetitive, constant timing intervals. This
method allows us to achieve such intervals. Note that for most devices it is also
possible to configure a timer to reset on compare without generating an interrupt.
This has benefits when the timer is being used to generate waveforms, but it offers no
particular advantage as a means of generating repetitive intervals using software
polling. Note also that it is also possible, as was discussed above, to configure a timer
to interrupt on overflow, while letting the timer continue to run. This will generate an
interval every 2^N timer ticks.
Using timer overflows to extend timer resolution
The simplest way to use a timer is to use it for counts that are less than the natural
timer count 2^N. However, it is possible to use a timer to count numbers greater than
the natural timer period by keeping track of overflows and including the overflow
count in the total count calculation.
System tick
It is very common to configure a hardware timer to generate a system “tick” which
controls the system timing and delays. This tick is often in the range of 1-20ms (50-
1000 ticks per second). From such a tick it is easy to generate in software unlimited
timing intervals, at the resolution of the tick period. For example, if you need to
display a message for 3 seconds and your system has a 10ms tick, your program
would display the message for 300 ticks. During that time your system will be
available for other work, since you’re only checking the tick count at every interrupt.
This strategy of extending hardware timers with software is a very common one and
can greatly increase the utility of the μC hardware timers.

45
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

The system tick function is so common that some μC devices have a dedicated system
tick timer, thus freeing up other onboard timers for other uses. If a μC does not have
a dedicated system tick timer, and a system tick is desired, then one of the regular
hardware timers must be dedicated to this task. If a μC has multiple timers, and if
some of the timers have higher resolution than others (e.g. an 8-bit timer and a 16-bit
timer, or a 16-bit and a 32-bit timer), it is usually a good idea to use a lower-resolution
timer for the system tick if possible, thus leaving the higher resolution timer(s)
available for other uses.

Software Timers
As we have said, hardware timers are an extremely useful resource, but they are also a
limited resource, both in terms of the number of hardware timers a μC may have, and
of the resolution of those timers. If your application needs more timers than your
hardware offers, and if the timing requirements for those extra timers are fairly “slow”
(relative to the processor speed), then the extra timers can easily be created in
software. Likewise, the range of hardware timers can be extended through software.

Event Counters
When timer/counter hardware is used to count external event pulses it is behaving as
an event counter. Some typical examples would be counting the number of widgets
that come down the assembly line in the Acme Widget plant, or the number of pulses
coming off a flywheel engine speed sensor. In the latter case the goal would be to
count the number of pulses in a given time period, in order to calculate an engine
speed. As in that example, it is very common that an event counter is used to count
not just the number of events, but the number of events in a given time interval. One
illustrative use of a timer in counter mode is to count the bounces of a switch.
Connecting a counter to such a switch allows one to see that bouncing in accurate
way.

2-2.5. Serial Port of the 8051


One of the 8051s many powerful features is its integrated UART,
otherwise known as a serial port. The 8051 has two pins (P3.0, P3.1)
which are dedicated for serial communications (RXD, TXD). Through
these pins, serial data can be transmitted (via TXD) or received (via
RXD) with other controllers or devices, as shown in figure 2-11. The
serial port can operate in so many modes, depending on the settings of the
Serial Port Control (SCON) register.
Data Transmission starts once a data byte is written (by the program) to
the SBUF. When data is transmitted and SBUF is empty, the TI bit (of
SCON) is set to 1. So, the program has to wait for TI, before writing a
new byte to SBUF.
Data Reception is enabled if the REN bit of the SCON register is set (1).
The RI flag will be set (automatically), after a data is received. You can
stop reception by resetting REN (0).

46
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Fig. 2-11. Serial communication port of the 8051 microcontrollers.(in serial mode0)

2-2.6. Serial Port Control Register (SCON)


The first thing we must do when using the 8051 serial port is, obviously,
to configure it. This is done by setting some values in the Serial Port
Control (SCON) register. The SCON is one of the SFRs of the 8051. The
following figure depicts the SCON bits and their significance.

SCON
SM0 SM1 SM2 REN TB8 RB8 T1 R1
Figure 2-12. The serial port control (SCON) register

47
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

The different bits of the SCON have the following assignments:


TI: Transmit Interrupt flag.
RI: Receive Interrupt flag.
REN: Receive Enable bit.
SM0: Serial mode bit 0.
SM1: Serial Mode bit 1.
TB8: Transmitted bit 8. Set or reset in modes 2 and 3, by the program
RB8: Received bit 8. In modes 2 and 3, RB8 sets or resets bit 8 of the
received data. In mode 0, RB8 sets or resets the Stop bit.
SM2: Multi-controller communication bit. Setting this bit (to 1) enables
serial communication with another microcontroller in serial modes 1, 2
and 3. In serial mode 1, an interrupt is generated when a valid stop bit is
received. In modes 2, 3, an interrupt is generated if bit 9 of the received
data is 1. Otherwise no interrupt is generated.

Both SM0 and SM1 bits define the mode of serial port communication
according to the following table:

Table 2-4. Serial port modes and their selection bits.

SM0 SM1 Serial Port Mode Mode Description Baud Rate


0 0 0 Shift Register fosc / 12
0 1 1 8-bit UART Programmable
1 0 2 9-bit UART fosc/32
1 1 3 9-bit UART Programmable

In Serial Mode 0, the shift register mode, the SBUF is configured to


receive or transmit data bytes serially via the RXD pin. The baud rate (the
pulse shift rate) is fixed to fosc/12 (supplied internally via TXD pin).

In Serial Mode 1, the standard 8-bit UART mode, the SBUF is


configured as a full-duplex 10-bit buffer that can receive data (via RXD)
and transmit data (via TXD) in the same time. The 10 bit-data are
assigned as 1 START bit, 8 data bits and 1 STOP bit. The TI bit is set
when the ten bits are transmitted. Reception starts with the falling edge of
the start bit and continues as long as the stop bit is not 1. The RI is set
when data reception ends.

IDLE  8-bit DATA 


START 0 1 2 3 4 5 6 7 STOP

Fig. 2-13. Serial data word in standard 8-bit UART mode (serial mode 1).
48
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

The baud rate of serial mode 1 is programmable and given by the


following relation (when Timer1 is working in mode 2):

 2SMODE   f osc   1 
BAUD RATE ( serial mod e 1)   . . 
 32   12   256  (TH 1) 

where SMODE is given in the PCON register (1 or 0). If Timer1 is not


operating in mode 2, then the baud rate is given by:

 2SMODE 
BAUD RATE (serial mod e 1)   .Timer1 Frequency
 32 

where the Timer1 frequency is supplied by either an internal clock


(usually fosc/12) or by any external clock, via the T1 input. In the later
case, Timer1 is working as a counter. If standard baud rates are desirable,
you've to choose an oscillator with fosc = 11.0592 MHz and adjust TH1 to
the following value:

 2SMODE   f osc  1
TH 1  256   . .
 32   12  BaudRate

In Serial Mode 2, the 9-bit UART mode (or multiprocessor mode, with
fixed baud rate), the operation is similar to serial mode 1, except for the
number of transmitted data bits is 9 bits (in addition to the START and
STOP bits). The additional data bit (bit 8) is copied from TB8 bit in the
SCON register during transmission, or copied into RB8 during reception.
The baud rate of serial mode 2 is given by:

 2 SMODE 
BAUD RATE (serial mod e 1)   . f osc 
 64 

Note that the baud rate is much higher than standard UART mode. Note
also that the SM2 bit should be '0' or the ninth data bit (bit 8) should be '1'
to enable communication using this mode.
In Serial Mode 3, the 9-bit UART mode (or multiprocessor mode, with
programmable baud rate), the operation is similar to serial mode 2, except
for the baud rate is programmable in the manner as in serial mode 1.
IDLE  9-bit DATA 
START 0 1 2 3 4 5 6 7 8 STOP

Fig. 2-14. Serial data word in standard 9-bit UART mode (serial mode 2, 3).
49
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Fig. 2-15. Serial Mode 0 (shift-register mode) timing diagram

2-2.7. Interrupt Map & Interrupt Enable (EA) Register


The 8051 has two external interrupt inputs (INT0, INT1). When an
interrupt signal is received and enabled, it doesn't alter the program the
microcontroller is doing, but it just temporarily stops it. Interrupts to the
CPU can also be generated by internal signals. For instance, in serial
communication, the 8051 hardware generates an interrupt (if enabled)
whenever the RI (Receive Interrupt) or TI (Transmit Interrupt) flags are
set in the SCON register. The interrupt has always a program associated
with it to guide the microcontroller what to do, when receiving such
interrupt. This is called an interrupt service routine (ISR). Each interrupt
redirects the program counter (PC) of the microcontroller to an interrupt
service routine (ISR) whose address is given by a vector. The interrupt
vector map of the 8051 interrupts is shown in figure 2-16.

Interrupt Source Meaning Vector address


IE0 Interrupt External 0 0003H
TF0 Timer Flag 0 000BH
IE1 Interrupt External 1 0013H
TF1 Timer Flag 1 001BH
RI , TI Serial port (RX, TX) 00023H
Fig. 2-16. The interrupt map in 8051 microcontrollers.

As soon as the microcontroller finishes handling the interrupt routine, the


PC returns to its original position before interrupt, and the CPU resumes
the execution of the original program. Each interrupt can be enabled or
disabled (masked) if its corresponding bit in the interrupt register (IE) is
set or reset. The following figure depicts the IE register and its flags.
50
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Note that the interrupt register has only one bit for serial port
communication (ES). As we mentioned above, the RI and TI flags are set
or reset in the SCON register.

Interrupt Enable (IE) Register


EA - ET2 ES ET1 EX1 ET0 EX0
Fig. 2-17. Interrupt enable (EI) register in 8051 microcontrollers.
EA = Enable A ll interrupts, ES = Enable Serial port, ET0 = Enable Timer0 overflow,
ET1 =Enable timer1 overflow, ET2 is reserved for future use, EX0= Enable External
interrupt, EX1 = Enable External interrupt.

When several interrupts happen in the same time, the CPU queue them
according to their priorities. The interrupt priority can be set or reset, in a
specific Interrupt Priority (IP) register, as shown in figure 2-6). When an
interrupt bit is set to '1', the interrupt is joins the high priority group of
interrupts. For instance, if the serial port interrupt priority bit (PS) is set
to '1', the serial communication interrupts, will have a high priority. The
low priority subroutines can be interrupted by high priority subroutines.

Interrupt Priority (IP) Register


- - - PS PT1 PX1 PT0 PX0
Fig. 2-18. Interrupt priority (PI) register in 8051 microcontrollers PS = Serial port
priority, PT0 = Timer 0 priority, PT1 = Timer 1 priority, PX0 = External interrupt 0
(INT0) priority, PX1 = External interrupt 1 (INT1) priority .

2-2.8. Structure of I/O Ports of the 8051


Figure 2-19 shows a functional diagram of a typical bit latch and I/O
buffer in each of the four ports. The bit latch (one bit in the port’s SFR) is
represented as a Type D flip-flop, which will clock in a value from the
internal bus in response to a “write to latch” signal from the CPU. The
level of the port pin itself is placed on the internal bus in response to a
“read pin” signal from the CPU. Some instructions that read a port
activate the “read latch” signal, and others activate the “read pin” signal.
As shown in figure 4, the output drivers of Port 0 and 2 are switchable to
an internal ADDR and ADDR/DATA bus by an internal Control signal
for use in external memory accesses.

During external memory accesses, the P2 SFR remains unchanged, but


the P0 SFR gets 1s written to it. As shown in figure, if a P3 bit latch
contains a 1, then the output level is controlled by the signal labeled
“alternate output function.” The actual P3.X pin level is always available
to the pin’s alternate input function, if any. Ports 1, 2, and 3 have internal
51
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

pull-ups, and Port 0 has open drain outputs. Each I/O line can be
independently used as an input or an output. Port 0 and 2 may not be used
as general purpose I/O when being used as the ADDR/DATA BUS for
external memory during normal operation. To be used as an input, the
port bit latch must contain a 1, which turns off the output driver FET.
Then, for Ports 1, 2, and 3, the pin is pulled high by a weak internal pull-
up, and can be pulled low by an external source. Port 0 differs in that its
internal pull-ups are not active during normal port operation.

Fig. 2-19(a). Circuit diagrams of the port0 of the 8051

Fig. 2-19(b). Circuit diagrams of the port1 of the 8051

The pull-up FET in the P0 output driver is used only when the port is
emitting 1s during external memory accesses. Otherwise the pull-up FET
is off. Consequently P0 lines that are being used as output port lines are
open drain. Writing a 1 to the bit latch leaves both output FETs off, so the
pin floats. In that condition it can be used as a high-impedance input.
52
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Because Ports 1, 2, and 3 have fixed internal pull-ups, they are sometimes
called “quasi- bidirectional” ports. When configured as inputs they pull
high and will source current (IIL, in the data sheets) when externally
pulled low. Port 0, on the other hand, is considered “true” bidirectional,
because when configured as an input it floats. All port latches of 80C51
have 1s written to them by the reset function. If a 0 is written to a port
latch, it can be reconfigured as an input by writing a 1 to it.

Fig. 2-19(c). Circuit diagrams of the port2 of the 8051

Fig. 2-19(d). Circuit diagrams of the port3 of the 8051

53
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2-3. Architecture of x51 variants, from Atmel.


There exist so many variants of the 8051, such as Atmel microcontrollers,
with several add-on features. For instance, Atmel 89Cx051 MCU’s are
20-pin versions of the 8051 microcontroller and looks like an 8051 as far
as programming. The 8051 or 8052 can be substituted for the
AT89Cx051 if the connections are moved to the appropriate pins on those
chips (see the compatibility PCB in the figure below).

Fig. 2-20. Atmel AT89C2051 microcontroller pin-out diagram.

As shown in figure 2-20 and table 2-5, the Atmel 2051 has two I/O ports
(named Port 1 and Port 3) distributed over 15 pins. Port 1 (pins 10-19) is
a 8-bit bi-directional I/O port. Port pins P1.2 to P1.7 provide internal pull-
ups. P1.0 and P1.1 require external pull-ups.

Table 2-5(a). Pin assignment of Atmel 2051 microcontroller.

Pin # Pin name Function Secondary Function


1 RST Reset input -
2 P3.0 / RXD Port 3 bit 0 Receive (serial input)
3 P3.1 / TXD Port 3 bit 1 Transmit (serial output)
4 XTAL2 Crystal oscillator output -

54
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Pin # Pin name Function Secondary Function


5 XTAL1 Crystal oscillator input -
6 P3.2 / INT 0 Port 3 bit 2 External Interrupt 0
7 P3.3 / INT 1 Port 3 bit 3 External Interrupt 1
8 P3.4 / T0 Port 3 bit 4 Timer 0 input
9 P3.5 / T1 Port 3 bit 5 Timer 1 input
10 GND -
11 P3.7 Port 3 bit 7 -
12 P1.0 / AN0 Port 1 bit 0 Analog input 0
13 P1.1 / AN1 Port 1 bit 1 Analog input 1
14 P1.2 Port 1 bit 2 -
15 P1.3 Port 1 bit 3 -
16 P1.4 Port 3 bit 4 Write memory strobe
17 P1.5 Port 3 bit 5 Read memory strobe
18 P1.6 Port 3 bit 6 -
19 P1.7 Port 3 bit 7 -
20 VCC Supply Voltage -

Port 3 includes P3.0, P3.1, P3.2, P3.3, P3.4, P3.5 and P3.7 (there is no
P3.6). These pins are usually used as general input/output pins. Port 3
also provides the following functions for the AT89C2051
Table 2-5(b). Pin assignment of Atmel 2051 microcontroller.

Port pin Alternate functions


P3.0 RXD ( serial input port )
P3.1 TXD ( serial output port)
P3.2 INTO ( external interrupt 0)
P3.3 INTI ( external interrupt 1)
P3.4 T0 ( timer 0 external input )
P3.5 T1 ( timer 1 external input)

It should be noted that the 2051 supports two software selectable power
saving modes. The Idle Mode stops the CPU while allowing the RAM,
timer/counters, serial port and interrupt system to continue functioning.
The Power Down Mode saves the RAM contents but freezes the
oscillator disabling all other chip functions until the next hardware reset.

Also, the Atmel AT93C134/5/6 microcontrollers are compatible with


8051 8-bit microcontrollers, with full speed USB port. This module
integrates the USB transceivers and the serial interface engine with digital
phase locked loop and 48-MHz clock recovery. It also includes USB
event detection logic and FIFO buffers supporting the mandatory control
endpoint and five versatile endpoints with minimum software overhead.

55
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

The device retains the features of the Atmel 80C52 and adds 1024 bytes
of on-chip ERAM, a dual data pointer, a 16-bit up/down timer, a
programmable counter array, up to four programmable LED current
sources, a programmable hardware watchdog, and a power-on reset.

Fig. 2-21(a). Architecture of the Atmel AT93C134/5/6 microcontrollers, with USB

Fig. 2-21(b). Connection of the AT89S8252


56
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2-4. Architecture of PIC Microcontrollers


We now start looking at the internal architecture of some famous
microcontrollers which have RISC architecture, such as the Microchip
PIC12/16/18 families of microcontrollers. Actually, the Microchip PIC
microcontroller is one of the most successful RISC microcontroller
devices, nowadays. RISC (Reduced Instruction Set Computer)
microcontroller has smaller number of commands than CISC
microcontroller, and those commands are generally simple (do less work
per command). By implementing fewer instructions, the chip designed is
able to dedicate some of the precious silicon real-estate for performance
enhancing features. Benefits are usually smaller chip and lower power
consumption. The industry trend for microprocessor design is for RISC
designs. The instruction set of RISC-based microcontrollers are
normalized. So, each instruction has its own unique function.

Note 2-1. History of PIC Microcontrollers

In 1985, General Instruments converted their Microelectronics Division


to Microchip Technology. PIC stands for Peripheral Interface Controller.
The General Instruments used the acronyms Programmable Interface
Controller and Programmable Intelligent Computer for the initial PICs
(PIC1640 and PIC1650).
In 1993, Microchip Technology launched the 8-bit PIC16C84 with
EEPROM which could be programmed using serial programming
method. The improved version of PIC16C84 with flash memory
(PIC18F84 and PIC18F84A) hit the market in 1998. Since then,
Microchip continuously developed new microcontrollers with new
complex architecture and enhanced in-built peripherals.

2-4.1. Architecture of PIC 8-bit Microcontrollers


The Microchip PIC microcontroller families are based on the Harvard
RISC microprocessor core. There exist so many 8-bit, PIC
Microcontrollers, from Microchip.
The PIC12 is a family of 8-bit microcontrollers of RISC architecture. It is
available in 18/28 pins DIP (dual inline) and 20/28 pin SSOP (shrink
small outline) packages. Some members of the family incorporate 2
timers, Power save SLEEP mode, watch-dog timer (WDT), a device-reset
timer (DRT) and up to two 8-bit ADC.
PIC16 also belongs to a class of 8-bit RISC microcontrollers. Its general
structure is shown on the following map representing basic blocks. They
run at frequencies from 0 Hz up to 40 MHz, with instruction cycle (0-
57
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

100ns). They have 12 I/O pins, 4 oscillator selections with programmable


calibration, and Power-on Reset. PIC16 microcontrollers have up to 2kB
EPROM / ROM and up to 72 Byte data RAM.
The PIC18 is a family of 8-bit RISC MCs which operates at frequencies
up to 40MHz. The PIC 18Cxxx has a Controller Area Network (CAN)
peripheral interface into a 64- or 68-pin package and is upwards
compatible with the PIC12, 16, 17 devices. The following table compares
the above PIC categories:
Table 2-6. PIC 8-bit microcontrollers

Enhanced
Base Line Mid-Range PIC18
Mid-Range
PIC12F1XXX,
Families PIC10,12, 16 PIC12, 16
PIC16F1XXX
PIC18
No. of Pins 6-40 8-64 8-64 18-100
Up to 128
Prog Memory Up to 3 KB Up to 14 KB Up to 28 KB
KB
Up to 368
Data Memory Up to 134 Bytes Bytes
Up to 1.5 KB Up to 4 KB
Instruction
12-bit 14-bit 14-bit 16-bit
Length
Instruction set 33 35 49 83
Speed (MIPS) 5 5 8 Up to 16
Enhanced
Baseline + Mid-range + Mid-range
• Comparator · SPI · High +
• 8-bit ADC · I2C Performance • CAN
Feature • Data Memory · UART · Multiple • LIN
•Internal · PWM communication • USB
Oscillator · 10-bit ADC peripherals • Ethernet
· OP-Amps • 12-bit
ADC

2-4.2. Internal Architecture of PIC16


Nowadays, the PIC16F84 is one of the most famous microcontrollers, in
industrial applications. What sets a microcontroller apart from other
processors are special circuits to deal with the needs of real time
applications. The PIC16F84A has many features to maximize system
reliability, minimize cost, power saving operating modes and offer code
protection.The following figure depicts the pin-out of the PIC16 MCU. It
contains 13 I/O pins with individual direction control, high current
sink/source for direct LED drive and 8-bit timer/counter with 8-bit
programmable prescaler. As shown in figure 2-22, PIC16F84 has a total
of 18 pins. It is most frequently found in DIP (Dual In Package) but can
58
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

also be found in Surface Mount (SMD) case which is smaller than a DIP.
Pins on PIC16F84 microcontroller have the following meaning, as
indicated in table 2-7:

Fig. 2-22. Oin0out diagram of the PIC16F8X microcontroller.

Table 2-7. Pin assignment of PIC microcontroller.

Pin # Pin name Function Secondary Function


1 RA2 Port A. bit 2 -
2 RA3 Port A. bit 3
3 RA4 / TOCK1 Port A. bit 4 Timer 1
4 MCLR / VPP Reset Programming supply
5 VSS (GND) Ground
6 RB0 / INT Port B bit 0 Interrupt input
7 RB1 Port B bit 1
8 RB2 Port B bit 2
9 RB3 Port B bit 3
10 RB4 Port B bit 4
11 RB5 Port B bit 5
12 RB6 Port B bit 6 Clock line in progrm mode
13 RB7 Port B bit 7 Data line in program mode
14 VDD Supply Voltage
15 OSC1
16 OSC2
17 RA1 Port A. bit 1
18 RA0 Port A. bit 0
59
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

As shown in figure 2-23, the PIC core consists of the following elements:

CPU unit. The CPU of the PIC16 has a RISC core and is based on the
Harvard architecture. A shown in figure (2-3), the CPU is the connective
element between other blocks in the microcontroller, and executes the
user program.
Program memory (FLASH). This memory is used for for storing a
written program. Since memory made in FLASH technology can be
programmed and cleared more than once, it makes this microcontroller
suitable for device development.
EEPROM data memory. This memory needs to be saved when there is
no supply. It is usually used for storing important data that must not be
lost if power supply suddenly stops. For instance, one such data is an
assigned temperature in temperature regulators. If during a loss of power
supply this data was lost, we would have to make the adjustment once
again upon return of supply. Thus our device looses on self-reliance.

Fig. 2-23. Block diagram of the PIC16F8A microcontroller.

60
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

RAM: The RAM is the data memory used by a program during its
execution. All inter-results or temporary data during run-time are stored
in the RAM area.

PORTA and PORTB. These are physical connections between the PIC
and the outside world. Port A has 5 pins, and port B has 8 pins.

FREE-RUN TIMER. The free-run timer is a 8-bit register inside the PIC
microcontroller that works independently of the program. On every fourth
clock of the oscillator it increments its value until it reaches the maximum
(255), and then it starts counting over again from zero. As we know the
exact timing between each two increments of the timer contents, timer
can be used for measuring time which is very useful with so many
microcontroller applications.

i. Configuration Register
A set of configuration bits are used to select the various options. The
configuration bits can be programmed (read as '0'), or left (read as '1'), to
select various device configurations.

bit 4-13 CP: Code Protection bit (1= Code protection disabled, 0= All program memory is protected)
bit 3 PWRTE: Power-up Timer Enable bit (1= Power-up Timer is disabled, 0= Power-up Timer enabled)
bit 2 WDTE: Watchdog Timer Enable bit (1= WDT enabled, 0= WDT disabled)
bit 1 FOSC1: Oscillator Selection bits (11= RC oscillator, 10= HS osc, 01= XT osc, 00= LP osc)
bit 0 FOSC0: Oscillator Selection bits (11= RC oscillator, 10= HS osc, 01= XT osc, 00= LP osc)

Fig. 2-24. Configuration word of the pic16F8x microcontroller.

ii. I/O Ports


Physically, port is a register inside a microcontroller which is connected
by wires to the pins of a microcontroller. Some pins for the I/O ports are
multiplexed with an alternate function (like PA4/TOCKI ) for the
peripheral features. Selection of one of these two pin functions is done in
one of the configuration registers.

All port pins can be defined as input or output. PORTA is a 5-bit wide,
bi-directional port. The corresponding data direction register is TRISA.
Setting a TRISA bit (= 1) will make the corresponding PORTA pin an
input (i.e., put the corresponding output driver in a Hi-Impedance mode).
Clearing a TRISA bit (= 0) will make the corresponding PORTA pin an
output (i.e., put the contents of the output latch on the selected pin). Pin
RA4 is multiplexed with the Timer0 module clock input to become the
RA4/T0CKI pin. The RA4/T0CKI pin is a Schmitt Trigger input and an
61
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

open drain output. All other RA port pins have TTL input levels and full
CMOS output drivers.

Fig. 2-25. PORTA and TRISA registerof PIC16F8A microcontroller.

Fig. 2-25. PORTA and TRISA registerof PIC16F8A microcontroller.


62
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Fig. 2-26. Circuit diagrams of portA of the PIC16

Fig. 2-27. Circuit diagrams of portB of the PIC16

iii. Timer Modules


The PIC has two 16-bit Timer/Counters (Timer0 and Timer1). The
Timer0 module timer/counter has the following features:
• 8-bit timer/counter
• Readable and writable
• Internal or external clock select
• Edge select for external clock
63
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

• 8-bit software programmable prescaler


• Interrupt-on-overflow from FFh to 00h
The following figure shows a block diagram of the Timer0 module.

Fig. 2-27. Block diagram of the Timer0 of the PIC16F8A microcontroller.

The TMR0 interrupt is generated when the TMR0 register overflows


from FFh to 00h. This overflow sets bit T0IF (INTCON<2>). The
interrupt can be masked by clearing bit T0IE (INTCON<5>). Bit T0IF
must be cleared in software by the Timer0 module Interrupt Service
Routine before re-enabling this interrupt. TMR0 interrupt cannot awaken
the processor from SLEEP since the timer is shut-off during SLEEP

iv. Watchdog Timer


The PIC16F84A has a Watchdog Timer which can be shut-off only
through configuration bits. It runs off its own RC oscillator for added
reliability. There are two timers that offer necessary delays on power-up.
One is the Oscillator Start-up Timer (OST), intended to keep the chip in
RESET until the crystal oscillator is stable.

SLEEP mode offers a very low current power-down mode. The user can
wake-up from SLEEP through external RESET, Watchdog Timer or
through an interrupt. The RC oscillator option saves system cost while the
LP crystal option saves power.

v. The PIC Interrupt Map


The PIC has two external interrupt inputs (INT0, INT1).
The PIC16F84A has 4 sources of interrupt:
• External interrupt RB0/INT pin
• TMR0 overflow interrupt
• PORTB change interrupts (pins RB7:RB4)
• Data EEPROM write complete interrupt
The interrupt control register (INTCON) records interrupt requests in flag
bits. It also contains the individual and global interrupt enable bits.

64
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2-4.3. Architecture of PIC 16-bit Microcontrollers


There exist so many 16-bit PIC Microcontrollers, from Microchip. For
instance, the PIC24F, PIC24H, and PIC24E are all 16-bit MCUs. They
use a dual-bus 16-bit Harvard Architecture. MCU I/O and peripherals are
mapped in the data memory space. The upper part of the data memory of
these MCUs can optionally be mapped into program space via a feature
known as Program Space Visibility (PSV). The 16-bit Digital Signal
Controllers (such as dsPIC30F and dsPIC33F/E) contain additional
hardware enabling the execution of a MAC (multiply-accumulate)
operation in a single clock-cycle.

Fig. 2-28. Block diagram of microcontroller.

2-4.4. Architecture of PIC 32-bit Microcontrollers


Microchip's 32-bit portfolio with the MIPS M-Class, microAptiv or M4K
core offer high performance microcontrollers, and all the tools needed to
develop your embedded projects. With MPLAB® Harmony software
framework, low cost development tools, and pin/peripheral compatibility
from 16-bit product lines, PIC32 MCUs shorten time to market and allow
your designs to grow. PIC32 gives your application the processing power,
memory and peripherals your design needs

65
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2-5. Architecture of ARM Microcontrollers


The ARM microcontroller (MCU) architecture has become the de facto
standard for 32-bit microcontrollers with its broad adoption in the
embedded market and widespread support from software companies.
Standardization on ARM microcontroller cores has now made it easier
than ever to port code from one 32-bit microcontroller to another.

Fig. 2-29. Block diagram of microcontroller.

The Cortex series of ARM processors are usually utilized as


microcontrollers. They are widely employed in smart phones, such as
iPhones and so many other embedded systems. The central core of the
Cortex-M3 processor, based on a 3-stage pipeline Harvard bus
architecture, incorporates advanced features such as hardware single-
cycle multiply and hardware divide. The Cortex-M3 processor
implementation of the Thumb2 instruction set, plus features such as
unaligned data storage and atomic bit manipulation, deliver world class
32-bit performance. The configurable Cortex-M3 processor connects to
the Advanced High-Performance Bus (AHB), enabling designers to build
their subsystem and easily add peripheral functionality.

66
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2.5.1. Cortex-M0 Processor


The ARM Cortex-M0 processor is the smallest ARM processor available.
The exceptionally small silicon area, low power and minimal code
footprint of the processor enables developers to achieve 32-bit
performance at an 8-bit price point, bypassing the step to 16-bit devices.
The ultra-low gate count of the Cortex-M0 processor also enables its
deployment in analog and mixed signal devices

Fig. 2-30. Block diagram of ARM Cortex-M0 microcontroller.

The ARM Cortex-M1 processor is the first ARM processor designed


specifically for implementation in FPGAs. The Cortex-M1 processor
targets all major FPGA devices and includes support for leading FPGA
synthesis tools, allowing the designer to choose the optimal
implementation for each project. The Cortex-M1 processor enables
OEMs to achieve significant cost savings through rationalization of
software and tools investments across multiple projects spanning FPGA,
ASIC and ASSP, plus greater vendor independence through use of an
industry-standard processor.

2.5.2. Cortex-M3
The ARM Cortex-M3 (CM3) processor is built on a high-performance
32-bit processor core, with a 3-stage pipeline Harvard architecture,
making it ideal for embedded applications. Its microcontroller core
architecture is designed to replace many 8-bit and 16-bit devices. To
facilitate the design of cost-sensitive devices, the Cortex-M3 processor
implements tightly-coupled system components that reduce processor
area while improving interrupt handling and system debug capabilities.
The ARM Cortex-M3 has dedicated multi-tasking hardware including
task-switching interrupts. The integrated nested vectored interrupt
controller (NVIC) includes a Non-Maskable Interrupt (NMI) that can
67
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

provide up to 256 interrupt priority levels. The Cortex-M3 processor


implements a version of the Thumb instruction set based on Thumb-2
technology, ensuring high code density and reduced program memory
requirements.

Fig. 2-31. Block diagram of ARM Cortex-M3 microcontroller.

The System Control Block (SCB) is the programmers model interface to


provides system implementation information and system control,
including configuration, control, and reporting of system exceptions

The system timer, SysTick, is a 24-bit count-down timer. Use this as a


Real Time Operating System (RTOS) tick timer or as a simple counter.

The MPU improves system reliability by defining the memory attributes


for different memory regions. It provides up to eight different regions,
and an optional predefined background region.

2.5.3. Cortex-M4 (ARM's DSP Class Processor)


The ARM Cortex-M4 processor is an award winning processor
specifically developed to address digital signal control markets that
68
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

demand an efficient, easy-to-use blend of control and signal processing


capabilities. In the EFM32 Wonder Gecko, the combination of high-
efficiency signal processing functionality with the proven energy friendly
Gecko technology makes for an easy-to-use microcontroller with the
lowest energy consumption available. The Cortex-M4 processor has been
designed with a large variety of highly efficient signal processing features
applicable to digital signal control markets. The processor features
extended single-cycle multiply-accumulate (MAC) instructions,
optimized SIMD arithmetic, saturating arithmetic instructions and an
optional single precision Floating Point Unit (FPU). These features build
upon the innovative technology that characterizes the ARM Cortex-M
series processors.

2.5.4. Cortex-M7 Processor


The ARM Cortex-M7 processor is the most recent and highest
performance member of the energy-efficient Cortex-M processor family,
and enables partners to build the most sophisticated variety of MCUs and
embedded SoCs. The Cortex-M7 has been designed to deliver a very high
level of performance, while maintaining the excellent responsiveness and
ease-of-use of the ARMv7-M architecture. Its industry leading high-
performance and flexible system interfaces are ideal for a wide variety of
application areas including automotive, industrial automation, medical
devices, high-end audio, image and voice processing, sensor fusion,
advanced motor control and in the deployment of the Internet of Things

Fig. 2-32. Block diagram of ARM Cortex-M7 microcontroller.

69
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2-6. Comparison between 8051, PIC, AVR and ARM


 8051, PIC and AVR have Harvard architecture (separate memory
spaces for RAM and program memory). ARM has von Neumann
architecture (program and RAM in the same space).
 ARM has a 16 and/or 32 bit architecture. The others are byte (8-
bit) architecture.
 8051 and PIC have limited stack space - limited to 128 bytes for
the 8051, and as little as 8 words or less for PIC. Writing a C compiler for
these architectures must have been challenging, and compiler choice is
limited.
 8051, AVR and ARM can directly address all available RAM. PIC
can only directly address 256 bytes and must use bank switching to
extend it, though using a C compiler conceals this. You still pay a speed
penalty though.
 8051 and PIC need multiple clock cycles per instruction. AVR and
ARM execute most instructions in a single clock cycle.
 8051 and AVR are sufficiently similar that an AVR can usually
replace an 8051 in existing products with practically no hardware change.
Some AVRs are made with 8051 pinouts to drop right in. The Reset
polarity is the main difference.
 8051 and AVR instruction sets are different but sufficiently similar
that it's possible to translate 8051 assembler to AVR assembler line by
line (I have done this). Because an 8051 takes 12 (sometimes six) clocks
per instruction and an AVR takes only one, you have to modify timing
critical routines.
 AVR and ARM have the best compiler and application support,
including free GCC compilers.

Direct comparisons between PIC and Cortex-M3 (ARM) architectures are


difficult. Both are available in any number of different configurations.
While the Cortex-M3 is arguably more standardized than the PIC
implementations, there are still several implementation options available
to individual silicon fabricators (e.g. number of interrupts and depth of
priority scheme, memory protection, debug configuration etc.).In both
cases, there is a large set of devices with very different peripheral sets. F
or the purposes of meaningful comparison, we have selected the PIC18
architecture and will be looking at devices like the PIC18F44J11. On the
Cortex-M3 side, we have selected the STM32F101T4 from
STMicroelectronics. The features of these two devices are summarized in
the table below.

70
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

Table 2-7. Comparison between PIC and ARM microcontrollers.

PIC18F44J11 STM32F101T4
(ARM Cortex M3)
Program memory (flash) 16 Kbytes 16 Kbytes
Data memory (RAM) 3.8 Kbytes 4 Kbytes
Max clock frequency 48 MHz 36 MHz
GPIO pins 34 26
ADC 13-channel x 10-bit 10-channel x 12-bit
Timers 2x8-bit, 3 x 16-bit 2x16-bit+SysTick
Watchdog timer Y Y (Two)
SPI 1 1
I2C 1 1
USART 2 2
PWM 2 N/A
Comparators 2 N/A
RTC Y Y
Extern interrupt sources 4 (+30 internal) 43 (+ 16 internal)
Interrupt prioritization 2 levels 16 levels
Vector Interrupt Control N Y
Power-saving modes Idle/Sleep/DeepSleep Sleep/Stop/Standby
DMA 7-channel
Debug port In-Circuit Debug SWJ- JTAG port

While these two devices have been selected as they are similar in size, it
is worth noting that the PIC is “large” in the family, whereas the Cortex-
M3 is relatively “small” compared to other available Cortex-M3 options.
Both devices have reasonably small areas of ROM and RAM together
with manageable peripheral sets.

71
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2-6. Summary

The Intel 8051 is a general purpose 8-bit microcontroller. The basic


version of 8051 usually comes in a 40 pin dual-inline package (DIP)
including 32 I/O lines, two 16-bit Timers/Counters, 2 Interrupts, 128
Bytes on-chip RAM, 4k ROM and a serial UART channel. The 8031 is a
ROM-less version of the 8051. Also the 8751 is identical to 8051 but it
has an internal 4kB EPROM. The 8051 can address up to 64kB of
external RAM and 64kB of external ROM. The basic internal structure of
the 8051 microcontroller is shown below:

All 80C51 devices have separate address spaces for program and data
memory, as shown in Figures 1 and 2. The logical separation of program
and data memory allows the data memory to be accessed by 8-bit
addresses, which can be quickly stored and manipulated by an 8-bit CPU.
Nevertheless, 16-bit data memory addresses can also be generated
through the DPTR register. Program memory (ROM, EPROM) can only
be read, not written to. There can be up to 64k bytes of program memory.
In the 80C51, the lowest 4k bytes of program are on-chip. In the ROM-
less versions, all program memory is external. The read strobe for
external program memory is the PSEN (program store enable). Data
Memory (RAM) occupies a separate address space from Program
Memory. In the 80C51, the lowest 128 bytes of data memory are on-chip.
Up to 64k bytes of external RAM can be addressed in the external Data
Memory space. In the ROM-less version, the lowest 128 bytes are on-
chip.
72
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

The CPU generates read and write signals, RD and WR, as needed during
external Data Memory accesses. External Program Memory and external
Data Memory may be combined if desired by applying the RD and PSEN
signals to the inputs of an AND gate and using the output of the gate as
the read strobe to the external Program/Data memory.

The following figure shows the timers and their registers in 8951
microcontrollers.

Nowadays, the PIC16F84 is the most famous MCU, one can see today in
so many industrial applications. The following figure depicts the pin-out
diagram of the PIC16F84 microcontroller

The Microchip PIC microcontrollers are based on the Harvard RISC


microprocessor core. The normalized instruction set of such
microcontrollers are all equal in length (3 bytes) and few in number
73
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

The following table summarizes the different types of ARM processors


and microcontrollers (Embedded).

Processor Class Arch. Speed Notes


ARM7TDMI Emb v4T 15 MIPS @ 16.8 MHz
ARM720T App v4T 60 MIPS @ 59.8 MHz
ARM7EJ-S Emb v5TEJ Up to 133MHz Jazelle DBX
ARM920T App v4T 200 MIPS @180 MHz
ARM922T App v4T Up to 250MHz
ARM926EJ-S App v5TEJ 220 MIPS @200 MHz Jazelle DBX
ARM946E-S Emb v5TE Up to 210MHz
ARM966E-S Emb v5TE Up to 250MHz (VFP)
ARM1020E App v5TE Up to 325MHz 32K/32K cache
ARM1022E App v5TE Up to 325MHz 16K/16K cache
ARM1026EJ-S App/Emb v5TEJ Up to 325MHz Jazelle DBX
ARM1136J(F)-S App v6 Up to 550MHz (VFP)
ARM1176JZ(F)-S App v6 Up to 550MHz (VFP),
ARM1156T2(F)-S Emb v6T2 Up to 550MHz Thumb-2
Cortex-M3 Emb v7M 120 DMIPS @ 00MHz Thumb-2 only
Cortex-A8 App v7A Up to 800MHz
Cortex-A9 App v7A 2.0 DMIPS/MHz

74
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2-8. PROBLEMS
2-1) Show what are main features of the Intel MCs51 microcontroller
family?

2-2) Draw a general block diagram describing the internal architecture of


the 8051 microcontroller and explain briefly each block.

2-3) List and explain the significance and use of the Special Function
registers in the 8051 microcontroller.

2-4) The register that is used as a scratch pad in 8051 microcontroller is


a) Accumulator b) B register
c) Data register d) Accumulator and B register

2-5) The registers that contains the status information is


a) control registers b) instruction registers
c) program status word d) all of the mentioned

`2-6) What’s meant by a 32-bit microcontroller? What are their main


features over 8-bit microcontrollers?

2-7) Describe how interrupt signals are dealt with in 8051


microcontrollers.

2-8) The 8051 interrupt-service mechanism is such that on occurrence of


an interrupt service, the processor pushes the processor registers PCH
(program counter higher byte) and PCL (program counter higher byte) on
to the memory stack. (ii) The 8051 family processors save all register as
context of the program on context switching to another routine or ISR
(iii) The 8051 family processors require that all register defining the
context of the program must be saved by push instruction before context
switching by using PUSH instructions (iv) The 8051 family processors
require that all register except PCH and PCL that are part of the context
of the program must be saved by push instruction before context
switching by using PUSH instructions (v) 68HC11 registers save on to
the stack before an interrupt service routine starts (vi) 68HC1x stack
before an interrupt service routine starts the processor pushes the
processor registers PCH and PCL on to the memory stack.
(a) i, iv and v (b) ii, v (c) ii and vi (d) i and vi

2-9) The resistor which is attached to an I/O line of an MCU is called ___
a) Push-down resistor b) Pull-up resistor
c) Break down resistor d) Line resistor
75
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2

2-10) The register that provides control and status information about
serial port is in the 8051 microcontroller
a) IP b) IE
c) TSCON d) PCON and SCON

2-11) ARM processors where basically designed for _______ .


a) Main frame systems b) Distributed systems
c) Mobile systems d) Super computers

2-12) The main importance of ARM micro-processors is providing


operation with,
a) Low cost and low power consumption b) Higher degree of multi-
tasking
c) Lower error or glitches d) Efficient memory management

2-13) The address space in ARM is ___


a) 2^24 b) 2^64 c) 2^16 d) 2^32

2-14) In ARM, PC is implemented using ____ .


a) Caches b) Heaps
c) General purpose register d) Stack

2-15) 3. Which ARM registers can interact with the secondary storage ?
a) MAR b) PC c) IR d) R0

76
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 3

Chapter 3: Microcontrollers Memory Organization

3-1. Introduction
Microcontrollers have three general types of memory. In order to
effectively program a microcontroller, it is necessary to have a basic
understanding of these memory types. The memory types are illustrated
in the following graphic. They are: On-Chip Memory, External Code
Memory, and External Memory.

Figure 3-1. Memory typesin 8051 microcontrollers.

As shown in figure 3-1, the majority of microcontroller devices have


separate address spaces for program and data memory. The logical
separation of program and data memory allows the data memory to be
accessed by 8-bit addresses. However, 16-bit data memory addresses can
also be generated through the DPTR register. Like almost all
microcontrollers, the 8051 devices have read-only-memory (ROM) or
PROM or even EEPROM, as the program memory. PROM can be
programmed once (it’s sometimes called: one-time programmable OTP).
EPROM can be electrically programmed and erased with UV light
through a glass window in the microcontroller package. The electrically
erasable and programmable (EEPROM) memory and Flash memory
have replaced the traditional EPROM in almost all recent
microcontrollers, for program store. This is sometimes called the code
memory. In the 80C51 microcontrollers, there can be up to 64k bytes of
program memory. The lowest 4k bytes of program are usually on-chip. In
the ROMless versions (like 8031), all program memory is external. The
data memory is a volatile read-write memory (RAM), which occupies a
separate address space from program (code) memory. In the 80C51, the

Dr. Eng. Muhammad El-SABA 77


Introduction to Microcontrollers CHAPTER 3

lowest 128 bytes of data memory are on-chip. Up to 64k bytes of external
RAM can be addressed in the external Data Memory space. In the
ROMless version, the lowest 128 bytes are on-chip. The CPU generates
read and write signals, RD and WR, as needed during external Data
Memory accesses. External Program Memory and external Data Memory
may be combined if desired by applying the RD and PSEN signals to the
inputs of an AND gate and using the output of the gate as the read strobe
to the external Program/Data memory.

3-2. Memory Organization of the 8051


Figure 3-2 depicts the memory organization of the 8051 microcontroller.
The 8051 has separate address spaces for Program (code) Memory and
Data (RAM) Memory. The Program Memory can be up to 64K bytes
long. The lower 4K (8K for the 8052) may reside on-chip. The program
memory is write-protected so that an errant program can't change itself
accidentally and really make a mess out of things. The data memory can
be written to or read from as needed by the program.

External Memory Internal Memory Type Address

FFFFH
P
External ROM R |
(EA=0) O 64k
G |
R
A
Internal (On-Chip) M
EPROM 4kB/8kB
(EA=1) 0000H

FFFFH
D |
External RAM A 64k
T |
A
0000H

Internal (On-Chip)
RAM 128/256B
Fig. 3-2. Data and program memory of the 8051 microcontroller.

Dr. Eng. Muhammad El-SABA 78


Introduction to Microcontrollers CHAPTER 3

3-2.1. Data Memory (RAM) of the 8051 Microcontrollers


The 8051 microcontroller can address up to 64K bytes of Data Memory
external to the chip. The 8051 has 128 bytes of on-chip RAM (256 bytes
in the 8052) and includes a number of Special Function Registers (SFRs).
Figure 3-2 depicts the data memory (RAM) of the 8051 microcontroller.

Figure 3-2. Organization of the data memory (RAM) in 8051 microcontrollers.

All of the lower 128 bytes in the can be accessed by either direct or
indirect addressing. The Upper 128 can only be accessed by indirect
addressing. The Upper 128 bytes of RAM are not implemented in the
8051, but in the devices with 256 byte RAM.

i. Special Function Registers (SFRs)


The microcontroller uses the Special Function Registers (SFRs) to control
most of its functions. The SFRs include the Port latch EA, timers,
controls, etc. In many cases, each SFR will contain 8 bits, each of which
control a function or report status on a function. The SFRs reside in
register locations 80–FFH. They can be accessed using MOV instructions

Dr. Eng. Muhammad El-SABA 79


Introduction to Microcontrollers CHAPTER 3

with direct addressing. In addition, some of the SFRs are bit addressable.
This can be particularly useful when enabling a function without
modifying others in the register since an SFR can contain 8 unrelated
control and status functions.

Fig. 3-3(b). Map of the special function registers (SFRs).

ii. Direct and Indirect Address Area


The 128 bytes of internal RAM (00-7F) can be accessed by both direct
and indirect addressing. It can be divided into 3 segments as listed below.

1. Register Banks (Bank0-Bank3):


The memory banks occupy the locations 00H through 1FH (32 bytes).
The 8051 microcontroller devices default to register bank 0 after reset. To
use the other register banks, you have to change some bits (RS0 and RS1)
in the program status word (PSW), as we can see below in table 3-1. Each
bank contains 8 bytes, named as R0-R7. So, a number of instructions
refer to these RAM locations as R0 through R7. The selection of which of
the four banks is being referred to, is made on the basis of the bits RS0
and RS1 at execution time, according to the following table. The Reset
(RST) initializes the Stack Pointer (SP) to location 07H and it is
incremented once to start from location 08H, which is the first register

Dr. Eng. Muhammad El-SABA 80


Introduction to Microcontrollers CHAPTER 3

(R0) of the second register bank. Thus, in order to use more than one
register bank, the SP should be initialed to a different location of the
RAM where it is not used for data storage (i.e., higher part of the RAM).
Table 3-1. Register banks in 8051 microcontrollers and their selection bits.

Register Bank Address Range (R0-R7) RS0 RS1


(8 Bytes)
Memory Bank 0 00H-07H 0 0
Memory Bank 1 08H-0FH 0 1
Memory Bank 2 10H-17H 1 0
Memory Bank 3 18H-1FH 1 1

2. Bit Addressable Area:


This is a 16 bytes segment, 20H-2FH. Each one of the 128 bits of this
area can be directly addressed (0-7FH). The bits can be referred to, in
two ways. One way is to refer to their address i.e. 0 to 7FH. The other
way is by reference to bytes 20H- 2FH. Thus, bits 0-7 can also be referred
to as bits 20.0-20.7 and bits 8-FH are the same as 21.0-21.7 and so on.
Each of the 16 bytes in this segment can also be addressed as a byte.

3. Scratch Pad Area Bytes: 30H through 7FH are available to the user as
data RAM. However, if the stack pointer has been initialized to this, an
enough number of bytes should be left aside to prevent data destruction.
Figure (3-5) depicts the scratch Pad memory area, in the 8051
microcontroller.

Table 3-2. The internal RAM in 8051 microcontrollers

Address RAM Area


7F General Purpose Area
30
2F Bit addressable Area
20
1FH Register Bank 3
18H
17H Register Bank 2
10H
0FH Register Bank 1
08H
07H Register Bank 0
00H

Dr. Eng. Muhammad El-SABA 81


Introduction to Microcontrollers CHAPTER 3

Fig. 3-4. The scratch pad memory area, in 8051 microcontrollers.

Dr. Eng. Muhammad El-SABA 82


Introduction to Microcontrollers CHAPTER 3

The following figure depicts the SFR area in details. The SFR registers
can only be reached by direct addressing. In general, all MCS-51
microcontrollers have the same SFR as the 8051, and at the same
addresses in SFR space.

Fig. 3-5. Detailed map of the special function registers (SFRs).

Dr. Eng. Muhammad El-SABA 83


Introduction to Microcontrollers CHAPTER 3

As shown, the SFR area contains so many 8-bit control registers. The
description of these registers is as follows:

P0 (Port 0, Address 80h, Bit-Addressable): This is input/output port 0.


Each bit of this SFR corresponds to one of the pins on the
microcontroller. For example, bit 0 of port 0 is pin P0.0, bit 7 is pin P0.7.
Writing a value of 1 to a bit of this SFR will send a high level on the
corresponding I/O pin whereas a value of 0 will bring it to a low level.

SP (Stack Pointer, Address 81h): This is the stack pointer of the


microcontroller. This SFR indicates where the next value to be taken
from the stack will be read from in Internal RAM. If you push a value
onto the stack, the value will be written to the address of SP + 1. That is
to say, if SP holds the value 07h, a PUSH instruction will push the value
onto the stack at address 08h. This SFR is modified by all instructions
which modify the stack, such as PUSH, POP, LCALL, RET, RETI, and
whenever interrupts are provoked by the microcontroller.

DPL/DPH (Data Pointer Low/High, Addresses 82h/83h): The SFRs


DPL and DPH work together to represent a 16-bit value called the Data
Pointer. The data pointer is used in operations regarding external RAM
and some instructions involving code memory. Since it is an unsigned
two-byte integer value, it can represent values from 0000h to FFFFh (0
through 65,535 decimal).

PCON (Power Control, Addresses 87h): The Power Control SFR is


used to control the 8051's power control modes. Certain operation modes
of the 8051 allow the 8051 to go into a type of "sleep" mode which
requires much less power. These modes of operation are controlled
through PCON. Additionally, one of the bits in PCON is used to double
the effective baud rate of the 8051's serial port.

TCON (Timer Control, Addresses 88h, Bit-Addressable): The Timer


Control SFR is used to configure and modify the way in which the 8051's
two timers operate. This SFR controls whether each of the two timers is
running or stopped and contains a flag to indicate that each timer has
overflowed. Additionally, some non-timer related bits are located in the
TCON SFR. These bits are used to configure the way in which the
external interrupts are activated and also contain the external interrupt
flags which are set when an external interrupt has occured.

Dr. Eng. Muhammad El-SABA 84


Introduction to Microcontrollers CHAPTER 3

TMOD (Timer Mode, Addresses 89h): The Timer Mode SFR is used to
configure the mode of operation of each of the two timers. Using this
SFR your program may configure each timer to be a 16-bit timer, an 8-bit
auto-reload timer, a 13-bit timer, or two separate timers. Additionally,
you may configure the timers to only count when an external pin is
activated or to count "events" that are indicated on an external pin.

TL0/TH0 (Timer 0 Low/High, Addresses 8Ah/8Ch): These two SFRs,


taken together, represent timer 0. Their exact behavior depends on how
the timer is configured in the TMOD SFR; however, these timers always
count up. What is configurable is how and when they increment in value.

TL1/TH1 (Timer 1 Low/High, Addresses 8Bh/8Dh): These two SFRs,


taken together, represent timer 1. Their exact behavior depends on how
the timer is configured in the TMOD SFR; however, these timers always
count up. What is configurable is how and when they increment in value.

P1 (Port 1, Address 90h, Bit-Addressable): This is input/output port 1.


Each bit of this SFR corresponds to one of the pins on the
microcontroller. For example, bit 0 of port 1 is pin P1.0, bit 7 is pin P1.7.
Writing a value of 1 to a bit of this SFR will send a high level on the
corresponding I/O pin whereas a value of 0 will bring it to a low level.

SCON (Serial Control, Addresses 98h, Bit-Addressable): The Serial


Control SFR is used to configure the behavior of the 8051's on-board
serial port. This SFR controls the baud rate of the serial port, whether the
serial port is activated to receive data, and also contains flags that are set
when a byte is successfully sent or received.

SBUF (Serial Control, Addresses 99h): The Serial Buffer SFR is used
to send and receive data via the on-board serial port. Any value written to
SBUF will be sent out the serial port's TXD pin. Likewise, any value
which the 8051 receives via the serial port's RXD pin will be delivered to
the user program via SBUF. In other words, SBUF serves as the output
port when written to and as an input port when read from.

P2 (Port 2, Address A0h, Bit-Addressable): This is input/output port 2.


Each bit of this SFR corresponds to one of the pins on the
microcontroller. For example, bit 0 of port 2 is pin P2.0, bit 7 is pin P2.7.
Writing a value of 1 to a bit of this SFR will send a high level on the
corresponding I/O pin whereas a value of 0 will bring it to a low level.

Dr. Eng. Muhammad El-SABA 85


Introduction to Microcontrollers CHAPTER 3

IE (Interrupt Enable, Addresses A8h): The Interrupt Enable SFR is


used to enable and disable specific interrupts. The low 7 bits of the SFR
are used to enable/disable the specific interrupts, where as the highest bit
is used to enable or disable ALL interrupts. Thus, if the high bit of IE is 0
all interrupts are disabled regardless of whether an individual interrupt is
enabled by setting a lower bit.

P3 (Port 3, Address B0h, Bit-Addressable): This is input/output port 3.


Each bit of this SFR corresponds to one of the pins on the
microcontroller. For example, bit 0 of port 3 is pin P3.0, bit 7 is pin P3.7.
Writing a value of 1 to a bit of this SFR will send a high level on the
corresponding I/O pin whereas a value of 0 will bring it to a low level.

IP (Interrupt Priority, Addresses B8h, Bit-Addressable): The


Interrupt Priority SFR is used to specify the relative priority of each
interrupt. On the 8051, an interrupt may either be of low (0) priority or
high (1) priority. An interrupt may only interrupt interrupts of lower
priority. For example, if we configure the 8051 so that all interrupts are of
low priority except the serial interrupt, the serial interrupt will always be
able to interrupt the system, even if another interrupt is currently
executing. However, if a serial interrupt is executing no other interrupt
will be able to interrupt the serial interrupt routine since the serial
interrupt routine has the highest priority.

PSW (Program Status Word, Addresses D0h, Bit-Addressable): The


Program Status Word is used to store a number of important bits that are
set and cleared by 8051 instructions. The PSW SFR contains the carry
flag, the auxiliary carry flag, the overflow flag, and the parity flag.
Additionally, the PSW register contains the register bank select flags
which are used to select which of the "R" register banks are currently
selected.

ACC (Accumulator, Addresses E0h, Bit-Addressable): The


Accumulator is one of the most-used SFRs on the 8051 since it is
involved in so many instructions. The Accumulator resides as an SFR at
E0h, which means the instruction MOV A,#20h is really the same as
MOV E0h,#20h. However, it is a good idea to use the first method since
it only requires two bytes whereas the second option requires three bytes.

B (B Register, Addresses F0h, Bit-Addressable): The "B" register is


used in two instructions: the multiply and divide operations. The B
register is also commonly used by programmers as an auxiliary register to
temporarily store values.

Dr. Eng. Muhammad El-SABA 86


Introduction to Microcontrollers CHAPTER 3

When power is reset, the SFRs will have some default values (not
necessary zeros). The reset values of the SFRs is shown in the table
below

Table 3-3. Reset values of the RFSs

Dr. Eng. Muhammad El-SABA 87


Introduction to Microcontrollers CHAPTER 3

iii. External Data Memory (External RAM):


As we pointed out earlier, the 8051 microcontrollers can host an external
data memory (up to 64 kB). Figure 3-5 demonstrates how to connect
external data memory to the 8051 microcontroller, via a data latch. Also,
figure 3-6 depicts the timing diagram for external data memory during the
read cycle.

Fig. 3-5. Interfacing with external data memory (RAM) in 8051 microcontrollers.

Fig. 3-6. Timing diagram of external data memory Read in 8051 microcontrollers.

Dr. Eng. Muhammad El-SABA 88


Introduction to Microcontrollers CHAPTER 3

3-2.2. Program Memory of the 8051


The 8051 microcontroller can address up to 64K bytes of program
Memory. So, the microcontroller program (code) can be up to 64K bytes
long (from location 0000H to FFFFH). When the microcontroller is reset
(by RST), the CPU begin execution from the program memory location
0H. Figure 3-7 depicts the code memory map in the 8051 microcontroller.
As shown, the lower 4K (8K for the 8052) may reside on-chip.

Fig. 3-7(a). The program memory organization in 8051 microcontrollers.

Fig. 3-7(b). Details of the program memory map in 8051 microcontrollers.

Dr. Eng. Muhammad El-SABA 89


Introduction to Microcontrollers CHAPTER 3

3-2.3. Connecting an External Program Memory (ROM) to the 8051


Figure 3-8 demonstrates how to connect an external program memory to
the 8051 microcontroller, via a data latch. The read strobe for external
program memory is the PSEN (program store enable). Also, figure 3-9
depicts the timing diagram for external program memory read cycle.

Fig. 3-8. Execution from external code memory in 8051 microcontrollers.

Fig. 3-9. Timing diagram of program memory Read in 8051 microcontrollers.

3-2.4. Connecting External Serial EPROM to the 8051:


Serial memory devices are preferable than conventional parallel memory
devices when you use a microcontroller with low pin count (like
AT89Cx51) and when the application doesn't need a high data transfer
rates. In addition, serial memory devices require less board space and are
usually less expensive. Figure (3-10) demonstrates how to connect an
external serial EPROM to the 8051 microcontroller. As shown, the
EEPROM serial data in (Di) and serial data out (Do) pins can be
connected to 2 pins of the microcontroller.
Dr. Eng. Muhammad El-SABA 90
Introduction to Microcontrollers CHAPTER 3

In some applications you can connect both Di and Do both to the same
microcontroller I/O pin, thereby saving a pin. This is possible because
you can program the microcontroller I/O pins as input or output during
program execution.

Fig. 3-10. Connecting a serial EEPROM (like AT93CXXX) to Atmel 89Cx51


microcontrollers.

Dr. Eng. Muhammad El-SABA 91


Introduction to Microcontrollers CHAPTER 3

3-3. Memory Organization of PIC Microcontrollers


The following figure depicts the different memory types of the
PIC16F84A microcontroller. Each memory has its own distinct function
and means of access

Fig. 3-11. memory of the PIC 16F84A microcontrollers.

In the 16F84A (and indeed any PIC microcontroller), the EEPROM is not
placed in the main data memory map. Instead, it is addressed through the
EEADR register and data is transferred through the EEDATA register.
These are both special function registers (SFRs). PIC supports protection
of program memory at block resolution, Block size varies from device to
device but is otherwise fixed. This prevents reprogramming of the on-
chip flash memory. There is no protection scheme for data memory.
All internal RAM contents on PIC devices can be bit-addressed. Bit Set,
Bit Clear, Bit Test and Bit Toggle instructions support this mode.

3-3.1. Program Memory


Program memory is a flash memory to store the program. Even if power
is switched off the contents of the flash memory will not be lost. Flash
memory can be written to using the writer, but the number of times it be
rewritten is limited to 1000 times.

The following figure shows the PIC16F84A program memory map.


Looking at this diagram, we can see three things: the Program Counter,
the Stack and the actual program memory. One word is 14 bits long and
1024 words (1k words ) can be stored. We can see that the address range
of program memory is from 0000 to 03FFH. With its 13-bit Program
Counter, the microcontroller can theoretically address a range from 0000
to 1FFFH.

When the program starts running for the first time, for example on power-
up, the Program Counter is set to 0000h. This location in the program
memory is labeled the reset vector. Therefore, the first memory location
that it points to is the reset vector. The programmer must therefore place
the first instruction at this location. There exist other reserved locations

Dr. Eng. Muhammad El-SABA 92


Introduction to Microcontrollers CHAPTER 3

for peripheral interrupt (0004h) and configuration word (2007h). The


basic operation of the PIC is specified at this memory location. The
enable bits of the Power-up timer, and the Watch-dog timer as well as the
oscillator selection bits are set here. This area is behind the usual program
area and cannot be accessed by the program. These parameters must be
specified using the burner when burning the program into flash memory.

PIC instructions are little-endian. Since PIC data memory is 8-bits wide
and is only accessed in bytes, endianness is not relevant.

Fig. 3-12. Data memory of the PIC microcontrollers.

The following figure depicts the program memory of the PIC16-bit MCU
and DSC devices. The 24-Bit wide Program Memory is connected to the
core via a 24-bit bus. Instructions/Data are programmed into the lower
half of this space and occupy even addresses only (i.e. the program
counter always increments by 2). The total size of the user-addressable

Dr. Eng. Muhammad El-SABA 93


Introduction to Microcontrollers CHAPTER 3

portion of this memory space is 4M 24-bit words (12M Bytes). Currently,


the largest 16-bit MCUs implement 512k bytes of program memory.

Fig. 3-13. Program memory of the 16-nit PIC microcontrollers.

The program memory map is broken into the following addressable


regions:
 User Memory Space (Top Half)
 Reset Vector (start address: 0x000000)
 Primary Interrupt Vector Table (start address: 0x000004)
 Alternate Interrupt Vector Table (start address: 0x000100)
 User Program Flash Memory (start address: 0x000200)
 Data EEPROM
 Configuration Memory Space (Bottom Half - beginning at 0x800000)

3-3.2. Data Memory


The following figure shows the 16F84A data memory map. Bank
switching is used to access this memory. Each bank has a memory
capacity of 80 bytes (00h-4Fh). The PIC16F84A has two banks.

Dr. Eng. Muhammad El-SABA 94


Introduction to Microcontrollers CHAPTER 3

This memory is divided into two sections. The first 12 bytes (00h-0Bh) of
each bank are called SFR (Special Function Registers) and are used to
record the operating states of the PIC, the input/output (I/O) port
conditions and other conditions.
INDF: Data memory contents
by indirect addressing
TMR0:Timer counter
PCL: Low order 8 bits of
program counter
STATUS: Flag of calculation
result
FSR: Indirect data memory
address pointer
PORTA: PORTA DATA I/O
PORTB: PORTB DATA I/O
EEDATA: Data for EEPROM
EEADR: Address for EEPROM
PCLATH: Upper 5 bits of
program counter
INTCON: Interruption control
OPTIN_REG: Mode set
TRISA: Mode set for PORTA
TRISB: Mode set for PORTB
EECON1:Control Register for
EEPROM
EECON2:Write protection
Register for EEPROM

Fig. 3-14. Data memory and Special Function Register of the PIC16F8
microcontrollers.

There are 16 different registers in the SFR (11 in bank 0 and 5 in bank1).
The content of each register is managed by the PIC. Although there are a
total of 24 file registers, several of them are in both banks.
The remaining 68 bytes (0Ch-4Fh), from byte 13 upward, are called GPR
(General Purpose Registers) and can be used to temporally store results
and conditions while the program is running. The contents of the GPR are

Dr. Eng. Muhammad El-SABA 95


Introduction to Microcontrollers CHAPTER 3

the same in both banks, so even with bank switching the total capacity is
only 68 bytes.

The following figure shows the 16-bit PIC microcontroller data memory
map. The data memory map is broken into the following regions:

 User Memory Space (Top Half - 16k word (32k byte))


 Special Function Register (SFR) Space (0x0000 - 0x07FE)
 X Data RAM (start address: 0x0800)
 Y Data RAM (start address: product specific)
 DMA Dual-Port RAM (start address: product-specific)
 PSV Memory Space (Bottom Half - 16k word (32k byte))
 Optional 32k byte window into Program Memory Space using PSV
mechanism

Fig. 3-15. Data memory of the PIC microcontrollers.

3-3.3. 16-bit Registers


The 16-bit MCU and DSC devices have sixteen 16-bit working registers,
which are memory-mapped to the first 16 words in data memory. Each of
the working registers can act as a data, address or offset register. The 16th
working register (W15) operates as a software Stack Pointer for interrupts
and calls. Additionally, W0-W3 are used to hold the results of certain
DIV and MUL operations as shown.

Dr. Eng. Muhammad El-SABA 96


Introduction to Microcontrollers CHAPTER 3

Fig. 3-16. Core registers of the PIC microcontrollers.

The following core registers are also available on all 16-bit devices:

 CORCON: Used to set the configuration of the CPU. Provides the


ability to map program space into data space.
 PSVPAG: Used to select the 32k byte region of program memory
space that is mapped to the data address space.
 TBLPAG: Used to hold the upper 8-bits of a program-memory
address during table read/write operations.
 RCOUNT: Contains the loop counter for the REPEAT instruction.
 PCH:PCL: Program Counter.

Program counter LSb is always “0” when accessing instructions. The LSb
of the program memory address (PC<0>) is reserved as a byte select bit
for program memory accesses from data space that use Program Space
Visibility (PSV) or table instructions. Instructions exist in program
memory User space only (not Configuration space). The program counter
uses bits 0 to 22 only for addressing instructions in this space. The MSb
of the program counter (bit 23) will be a “1” when accessing data with
Table Read or Table Write operations in Configuration space.

Dr. Eng. Muhammad El-SABA 97


Introduction to Microcontrollers CHAPTER 3

Fig. 3-17. DSP-Specific Registers of the PIC microcontrollers.

Several of the standard working registers have additional functionality for


DSP operations as shown. Additionaly, there are several DSP-Specific
registers, including 2 40-bit accumulators (A & B) available for DSP
operations as shown:
 DCOUNT: Contains the loop counter for hardware DO loops.
 DOSTART: Contains the starting address for a hardware DO loop.
 DOEND: Contains the ending address for a hardware DO loop.
 ACCA/ACCB: 40-bit wide registers, utilized by DSP instructions to
perform mathematical and shifting operations.

3-3.4. Stack
The stack memory stores the program return address when a jump is
executed. For example if the same instructions are to be executed more
than once, a subroutine is used. A RETURN instruction signifies the end
of the subroutine and the program continues were it left off. A CALL
instruction tells the program to jump to a subroutine. When the CALL
instruction is encountered, the return address (the address of the

Dr. Eng. Muhammad El-SABA 98


Introduction to Microcontrollers CHAPTER 3

instruction immediately after the CALL) is stored at the top of the stack.
This operation is sometimes called a PUSH. When the subroutine
processing is finished and the RETURN instruction is executed, the
address at the top of the stack is put in the PC and the program continues
normal execution. This operation is sometimes called a POP. This way
multiple subroutines can be called and the processing will return to the
part of the program which called the subroutine. Since there are eight
stack registers, eight subroutine calls can be made sequentially. After the
eighth, a call will roll the contents of the eighth (and last register) back to
the top of the stack. When a return is executed, the PC will send the
program to the wrong address, and the program will not work properly.
For this reason only eight sequential subroutines calls can be made. A
return from a subroutine call must be done by the RETURN instruction.
Never use the JUMP instruction to return from a subroutine.

Fig. 3-18. Stack of the PIC microcontrollers.

3-3.5. Size of Data words in PIC Controllers


When the PIC18 series are referred to as 8-bit microcontrollers, it is the
size of the data words of these micros which is being specified.
Their registers and RAM are 8-bit wide, and computations and operations
are typically done on 8-bits at a time. However, since the PIC has
Harvard architecture, the data and program memories are kept completely
separate. This means that there is no link between the size of the data
words and the size of the program code words.

Dr. Eng. Muhammad El-SABA 99


Introduction to Microcontrollers CHAPTER 3

When looking at the different sub-groups in the 8-bit PIC family, you can
see that there are different groups with different code word sizes. The
PIC18's have 16-bit code words, while the PIC12's have 12-bit code
words. Once upon a time there was also a PIC14 with a 14-bit code word.
You may have noticed that PIC12=12-bit, PIC14=14-bit, but PIC18
doesn't correspond with an 18-bit code word. This is because the PIC18's
were developed as an upgrade to the PIC16 series and PIC16=16-bit.
Besides, other 8-bit microcontrollers and microprocessors can have 8, 16,
or 24 bit instructions. These instructions will occupy 1, 2, or 3 bytes of
memory. The first byte is the actual instruction, while the second and
third bytes will contain a memory address or immediate data that will be
used by the instruction.

Dr. Eng. Muhammad El-SABA 100


Introduction to Microcontrollers CHAPTER 3

3-4. Memory Organization of ARM Microcontroller


The Cortex-M3 memory map is summarized in the figure 3-19 and the
table below. As shown in figure, the processor has a fixed default
memory map that provides up to 4GB of addressable memory. This is a
unified address space covering both program and data regions as well as
peripherals and system control registers.

Fig. 3-19. The ARM memory map.

The memory map splits the memory map into regions. Each region has a
defined memory type, and some regions have additional attributes. The
Code, SRAM, and external RAM regions can hold programs. However,
ARM recommends that programs always use the Code region. The
SRAM and peripherals regions include optional bit-band regions. A bit-
band region maps each word in a bit-band alias region to a single bit in
the bit-band region. The bit-band regions occupy the lowest 1MB of the
SRAM and peripheral memory regions.

Dr. Eng. Muhammad El-SABA 101


Introduction to Microcontrollers CHAPTER 3

The processor also reserves regions of the Private Peripheral Bus (PPB)
address range for core peripheral registers.
Table 3-3. ARM Cortex-M3 memory map

The Cortex-M3 is a 32-bit processor and all internal registers are 32-bit.
Memory transfers of 8-bit bytes, 16-bit half-words and 32-bit words are
supported. In the case of bytes and half-words, the programmer needs to
specify whether the loaded value is to be treated as signed or unsigned. In
the case of signed values, the loaded value is sign-extended to create a
32-bit signed value in the destination register; in the case of unsigned
values, the upper part of the register is cleared to zero.

3-4.1. ARM Registers


ARM has 37 registers in total, all of which are 32-bits long.
• 1 dedicated program counter
• 1 dedicated current program status register
• 5 dedicated saved program status registers
• 30 general purpose registers

These are arranged into several banks, with the accessible bank being
governed by the processor mode. Each mode can access
• particular set of R0-R12 registers
• particular R13 (the stack pointer) and R14 (link register)
• R15 (the program counter)
• CPSR (current program status register) and privileged modes can also
access a particular SPSR (saved program status register)

Dr. Eng. Muhammad El-SABA 102


Introduction to Microcontrollers CHAPTER 3

The following figure summarizes the ARM core registers

Fig. 3-20. The ARM core registers.

ARM has sixteen registers visible at any one time. They are named R0 to
R15. All are 32 bits wide.

The registers may also be referred to by the following aliases:

All of the registers are general purpose, save for:


 R13 / SP which holds the stack pointer.
 R14 / LR the link register which holds the callers return address.
 R15 / PC which holds the program counter.
In addition to the main registers there is also a program status register
(PSR), exception mask registers and control register.

Dr. Eng. Muhammad El-SABA 103


Introduction to Microcontrollers CHAPTER 3

Fig. 3-21. Summary of the ARM register organization.

3-4.2. Stacks
The processor uses a full descending stack. This means the stack pointer
holds the address of the last stacked item in memory. When the processor
pushes a new item onto the stack, it decrements the stack pointer and then
writes the item to the new memory location. The processor implements
two stacks, the main stack and the process stack, with a pointer for each
held in independent registers,

Dr. Eng. Muhammad El-SABA 104


Introduction to Microcontrollers CHAPTER 3

3-5. Summary

Microcontroller devices have a fixed memory map. Within these maps,


areas are allocated for ROM, RAM, peripherals etc. Both also support a
scheme of memory mapped registers for system configuration and
control.

In most microcontrollers there is PROM or EPROM, or FLASH as the


program memory. PROM can be programmed once (it’s sometimes
called: one-time programmable OTP). EPROM can be programmed and
then erased with ultraviolet light through a glass window in the
microcontroller package. But this requires a special programmer and an
ultra violet light source for erasure.

The 8051 has three very general types of memory. To effectively program
the 8051 it is necessary to have a basic understanding of these memory
types. The memory types are: On-Chip Memory, External Code
Memory, and External RAM.

On-Chip Memory refers to any memory (Code, RAM, or other) that


physically exists on the microcontroller itself. On-chip memory can be of
several types, but we'll get into that shortly.

Dr. Eng. Muhammad El-SABA 105


Introduction to Microcontrollers CHAPTER 3

External Code Memory is code (or program) memory that resides off-
chip. This is often in the form of an external EPROM.
External RAM is RAM memory that resides off-chip. This is often in the
form of standard static RAM or flash RAM. Since code memory is
restricted to 64K, 8051 programs are limited to 64K. Some assemblers
and compilers offer ways to get around this limit when used with
specially wired hardware. However, without such special compilers and
hardware, programs are limited to 64K.
On-chip RAM is really one of two types: Internal RAM and Special
Function Register (SFR) memory. The layout of the 8051's internal
memory is presented in the following memory map.
The 8051 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). These registers are generally used to assist in
manipulating values and moving data from one memory location to
another.

Special Function Registers (SFRs) are areas of RAM that control specific
functionality of the 8051 processor. For example, four SFRs permit
access to the 8051s 32 input/output lines. Another SFR allows a program
to read or write to the 8051s serial port. Other SFRs allow the user to set
the serial baud rate, control and access timers, and configure the 8051s
interrupt system.

Dr. Eng. Muhammad El-SABA 106


Introduction to Microcontrollers CHAPTER 3

SFRs are accessed as if they were normal Internal RAM. The only
difference is that Internal RAM is from address 00h through 7Fh whereas
SFR registers exist in the address 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 8051's SFRs, their names, and
their address. As you can see in the following figure, although the
address range of 80H through FFH offers 128 possible addresses, there
are only 21 SFRs in a standard 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.

P0 (Port 0, Address 80h, Bit-Addressable): This is input/output port 0..


SP (Stack Pointer, Address 81h): This is the stack pointer of the
microcontroller.
DPL/DPH (Data Pointer Low/High, Addresses 82h/83h): The SFRs
DPL and DPH work together to represent a 16-bit value called the Data
Pointer.
PCON (Power Control, Addresses 87h): The Power Control SFR is
used to control the 8051's power control modes.
TCON (Timer Control, Addresses 88h, Bit-Addressable): The Timer
Control SFR is used to configure and modify the way in which the 8051's
two timers operate. Additionally, some non-timer related bits are located
in the TCON SFR. These bits are used to configure the way in which the

Dr. Eng. Muhammad El-SABA 107


Introduction to Microcontrollers CHAPTER 3

external interrupts are activated and also contain the external interrupt
flags which are set when an external interrupt has occured.
TMOD (Timer Mode, Addresses 89h): The Timer Mode SFR is used to
configure the mode of operation of each of the two timers. Using this
SFR your program may configure each timer to be a 16-bit timer, an 8-bit
auto-reload timer, a 13-bit timer, or two separate timers. Additionally,
you may configure the timers to only count when an external pin is
activated or to count "events" that are indicated on an external pin.
TL0/TH0 (Timer 0 Low/High, Addresses 8Ah/8Ch): These two SFRs,
taken together, represent timer 0.
TL1/TH1 (Timer 1 Low/High, Addresses 8Bh/8Dh): These two SFRs,
taken together, represent timer 1.
P1 (Port 1, Address 90h, Bit-Addressable): This is input/output port 1.
SCON (Serial Control, Addresses 98h, Bit-Addressable): The Serial
Control SFR is used to configure the behavior of the 8051's on-board
serial port.
SBUF (Serial Control, Addresses 99h): The Serial Buffer SFR is used
to send and receive data via the on-board serial port.
P2 (Port 2, Address A0h, Bit-Addressable): This is input/output port 2.
IE (Interrupt Enable, Addresses A8h): The Interrupt Enable SFR is
used to enable and disable specific interrupt.
P3 (Port 3, Address B0h, Bit-Addressable): This is input/output port 3.
IP (Interrupt Priority, Addresses B8h, Bit-Addressable): The
Interrupt Priority SFR is used to specify the relative priority of each
interrupt.
PSW (Program Status Word, Addresses D0h, Bit-Addressable): The
Program Status Word is used to store a number of important bits that are
set and cleared by 8051 instructions. The PSW SFR contains the carry
flag, the auxiliary carry flag, the overflow flag, and the parity flag.
ACC (Accumulator, Addresses E0h, Bit-Addressable): The
Accumulator is one of the most-used SFRs on the 8051 since it is
involved in so many instructions.
B (B Register, Addresses F0h, Bit-Addressable): The "B" register is
used in the multiply and divide operations.
A common practice when Microcontroller companies wish to develop a
new 8051 derivative is to add additional SFRs to support new functions
that exist in the new chip. For example, the Dallas Semiconductor
DS80C320 is upwards compatible with the 8051. This means that any
program that runs on a standard 8051 should run without modification on
the DS80C320. This means that all the SFRs defined above also apply to
the Dallas microcontroller.

Dr. Eng. Muhammad El-SABA 108


Introduction to Microcontrollers CHAPTER 3

The following figure gives a brief look at the accessing circuits of both
external data (RAM) memory and external program (EPROM) memory.

PIC program and data memory are in separate address spaces and are
addressed in different ways. Data memory in PIC devices is divided into
banks. All PIC peripherals which are included in the device are accessed
and controller via SFRs in fixed locations
PIC internal data memory is organized into up to 16 banks of 256 bytes,
giving a total of 4k bytes. Banks are accessed either via a 12-bit address
(using the MOVFF instruction) or via a 4-bit Bank Select Register (which
specifies the bank number) coupled with an 8-bit address.
The ARM7 and ARM9 based microcontrollers (such as ARM Cortex-M)
run on load-store RISC architecture with 32-bit registers and fixed op-
code length. The architecture provides a linear 4GB memory address
space. In contrast to the previously mentioned 8/16-bit devices, no
specific memory types are provided, since memory addressing is
performed via 32-bit pointers in microcontroller registers. Peripheral
registers are mapped directly into the linear address space. The Thumb
instruction set improves code density by providing a compressed 16-bit
instruction subset. The ARM7 and ARM9 cores are easy to use, cost-
effective, and support modern object-oriented programming techniques.
They include a 2-level interrupt system with a normal interrupt (IRQ) and
a fast interrupt (FIQ) vector. To minimize interrupt overhead, typical
ARM7/ARM9 microcontrollers provide a vectored interrupt controller.
The microcontroller operating modes, separate stack spaces, and Software
Interrupt (SVC) produce efficient use of Real-Time Operating Systems.

The ARM7 and ARM9 core provides thirteen general-purpose registers


(R0– R12), the stack pointer (SP) R13, the link register (LR) R14, which
holds return addresses on function calls, the program counter (PC) R15,
and a program status register (PSR)..

Dr. Eng. Muhammad El-SABA 109


Introduction to Microcontrollers CHAPTER 3

3-6. PROBLEMS

3-1) Describe the architecture of the special function registers in 8051


microcontrollers.

3-2) Describe the memory organization of the Atmel 2051


microcontroller

3-3) Show how to connect an external 32kB code EPROM to the 8051

3-4) Show how to connect an external 32 kB data Ram to the 8051.

3-5) The address space in ARM is ______ .


a) 2^24 b) 2^64 c) 2^16 d) 2^32

3-6) The decoded instruction is stored in ______ .


a) IR b) PC c) Registers d) MDR

3-7) The decoded instruction is stored in ______ .


a) IR b) PC c) Registers d) MDR

3-8) To get the physical address from the logical address generated by
ARM processor, we use ____
a) MAR b) MMU c) Overlays d) TLB
3-9) During transfer of data between a processor and memory we use ___
a) Cache b) TLB C) Buffers d) Registers
3-10) In ARM, PC is implemented using ____ .
a) Caches b) Heaps c) General purpose register d) Stack
3-11) The additional duplicate register used in ARM are called as ___
a) Copied-registers b) Banked registers c) EXtra registers d) External registers

3-12) The address system supported by ARM systems is/are ______


a) Little Endian b) Big Endian c) X-Little Endian d) Both a and b

3-13) The address system supported by ARM systems is/are ___ .


a) Little Endian b) Big Endian c) X-Little Endian d) Both a and b

Dr. Eng. Muhammad El-SABA 110


Introduction to Microcontrollers CHAPTER 4

Chapter 4: 8051 Instructions & Assembly Language

The microcontroller program is a group of the microcontroller


instructions that perform a certain task, or whatever you want the
microcontroller to do. It is usually written using a symbolic language
called “the microcontroller assembly language”. The assembly file, which
is called the source code, should be assembled by an assembler program
that generates a binary code, the microcontroller understands. In this
chapter, we recapitalize the 8051 instruction set and present a brief
description for each instruction.

4-1. Instruction Format in 8051 Assembly Language


The 8051 is an 8-bit microcontroller. This basically means that each
operation code (opcode) in its instruction set consists of a single 8-bit
value. This permits a maximum of 256 instruction codes (of which 255
are actually used in the 8051 instruction set).

The information encoded in an 8051 instruction includes a specification


of the operation to be performed (opcode), and the arguments (operands)
to be manipulated. The following figure depicts the instruction format for
the 8051 assembly language.

Opcode Operands
mnemonic Argument1 Argument2

A mnemonic is a reserved name (e.g., MOV) for a class of instruction


opcodes that have the same function.

The operands argument1, argument2, and argument3 are optional. There


may be from zero to three operands, depending on the opcode. When
present, they take the form of either literals or identifiers for data items.
Operand identifiers are either reserved names of registers or are assumed
to be assigned to data items declared in another part of the program.
When two operands are present in an instruction that modifies data, the
right operand is the source and the left operand is the destination.

Example 4-1:
DEC A ; Decrement the Accumulator (register A)
MOV B,#05 ; Move the constant 05 to the register B
JMP LOOP ; Jump to the above line, labeled LOOP

111
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

4-2. The 8051 Microcontroller Instruction Set (Alphabetical)


The instruction set of the MC 8051 has a rich set of addressing modes
plus the following features:
• Ability to access ports and other peripheral control and status registers
• has Ability to access individual bits of a port or register
• Good masking operation ability to test port and register bits individually
• Good interrupt infrastructure.

The following table summarizes the whole 8051 instruction set, in


alphabetical order with their corresponding opcodes. Some other details
(the instruction size in bytes and duration in cycles) are also indicated in
this table. In this summary we make use of the following notations:

Symbol Meaning

addr11 11-bit destination address. Used by ACALL &


AJMP. The branch will be within the same
2KB page of program memory as 1st byte of
following instruction.
addr16 16-bit destination address. Used by LCALL &
LJMP. A branch can anywhere within the 64K-
byte Program Memory address space
#data 8-bit constant included in instruction.
#data 16 16-bit constant included in instruction
direct 8-bit internal data location‟s address. This
could be an Internal Data RAM location (0-
127) or a SFR [i.e., I/O port, control register,
status register, etc. (128-255)].
@Ri 8-bit internal data RAM location (255)
addressed indirectly through register R1 or R0
Rn Register R7-RO of the currently selected
register bank.
rel Offset address. It is a signed (two‟s
complement) 8-bit. Range from -127 to 128
relative to first byte of the following
instruction. Used by SJMP and conditional
jumps.
bit Direct addressed bit in Internal Data RAM or
Special Function Register.

112
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Table 4-1. The 8051 microcontroller instructions.

MNEMONIC Bytes Cycles MNEMONIC Bytes Cycles

ADD A,Rn 1 1 MOV direct,A 2 1


ADD A,direct 2 1 MOV direct,Rn 2 2
ADD A,@Ri 1 1 MOV direct1,direct2 3 2
ADD A,#data 2 1 MOV direct,@Ri 2 2
ADDC A,Rn 1 1 MOV direct,#data 3 2
ADDC A,direct 2 1 MOV @Ri,A 1 1
ADDC A,@Ri 1 1 MOV @Ri,direct 2 2
ADDC A,#data 2 1 MOV @Ri,#data 2 1
SUBB A,Rn 1 1 MOV DPTR,#data16 3 2
SUBB A,direct 2 1 MOVC A,@A+PC 1 2
SUBB A,@Ri 1 1 MOVC A,@A+DPTR 1 2
SUBB A,#data 2 1 MOVX A,@Ri 1 2
INC A 1 1 MOVX A,@DPTR 1 2
INC Rn 1 1 MOVX @ Ri,A 1 2
INC direct 2 1 MOVX @ DPTR,A 1 2
INC @ Ri 1 1 PUSH direct 2 2
INC DPTR 1 2 POP direct 2 2
DEC A 1 1 XCH A,Rn 1 1
DEC Rn 1 1 XCH A,direct 2 1
DEC direct 2 1 XCH A,@Ri 1 1
DEC @ Ri 1 1 XCHD A,@Ri 1 1
MUL AB 1 4 CLR C 1 1
DIV AB 1 4 CLR bit 1 2
DA A 1 1 SETB C 1 1
ANL A,Rn 1 1 SETB bit 2 1
ANL A,direct 2 1 CPL C 1 1
ANL A,@Ri 1 1 CPL bit 2 1
ANL A,#data 2 1 ANL C,bit 2 2
ANL direct,A 2 1 ANL C,bit NOT 2 2
ANL direct,#data 3 2 ORL C,bit 2 2
ORL A,Rn 1 1 ORL C,bit NOT 2 2
ORL A,direct 2 1 MOV C,bit 2 1
ORL A,@Ri 1 1 MOV bit,C 2 2
ORL A,#data 2 1 ACALL addr11 2 2
ORL direct,A 2 1 LCALL addr16 3 2
ORL direct,#data 3 2 RET 1 2
XRL A,Rn 1 1 RETI 1 2
113
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

MNEMONIC Bytes Cycles MNEMONIC Bytes Cycles

XRL A,direct 2 1 AJMP addr11 2 2


XRL A,@Ri 1 1 LJMP addr16 3 2
XRL A,#data 2 1 SJMP rel 2 2
XRL direct,A 2 1 JMP @ A+DPTR 1 1 2
XRL direct,#data 3 2 JZ rel 2 2
CLR A 1 1 JNZ rel 2 2
CPL A 1 1 JC rel 2 2
RL A 1 1 JNC rel 2 2
RLC A 1 1 JB bit,rel 3 2
RR A 1 1 JNB bit,rel 3 2
RRC A 1 1 JBC bit,rel 3
SWAP A 1 1 CJNE A,direct,rel 3 2
MOV A,Rn 1 1 CJNE A,#data,rel 3 2
MOV A,direct 2 1 CJNE Rn,#data,rel 3 2
MOV A,@Ri 1 1 CJNE @ Ri,#data,rel 3 2
MOV A,#data 2 1 DJNZ Rn,rel 2 2
MOV Rn,A 1 1 DJNZ direct,rel 3 2
MOV Rn,direct 2 2 NOP 1 1
MOV Rn,#data 2 1

4-3. The 8051 Addressing Modes


An "addressing mode" refers to how you are addressing a given memory
location. In summary, the addressing modes are as follows, with an
example of each:

Immediate Addressing MOV A,#20h


Direct Addressing MOV A,30h
Indirect Addressing MOV A,@R0
External Direct MOVX A,@DPTR
Code Indirect MOVC A,@A+DPTR

Each of these addressing modes provides important flexibility

4-3.1. Immediate Constant Addressing


The value of a constant can immediately follow the opcode in Program
Memory. For example, MOV A,#20 loads the Accumulator with the
decimal number 20. The same number could be specified in hexa as 64H.

114
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

4-3.2. Direct Addressing: In the direct addressing mode the operand is


specified by an 8-bit address field in the instruction. Only internal Data
RAM and SFRS can be directly addressed.
4-3.3. Indirect Addressing: In indirect addressing the instruction
specifies a register which contains the address of the operand. Both
internal and external RAM can be indirectly addressed. The address
register for 8-bit addresses can be R0 or R1 of the selected register bank,
or the Stack Pointer. The address register for 16-bit addresses is the 16-bit
data pointer register, DPTR.
4-3.4. Indexed Addressing: Only Program Memory can be accessed
with indexed addressing, and it can only be read. This addressing mode is
intended for reading look-up tables in Program Memory. An
Identification-bit base register (either Data Pointer DPTR or Program
Counter PC) points to the base of the table, and the Accumulator is setup
with the table entry number. The address of the table entry in Program
Memory is formed by adding the Accumulator data to the base pointer.
Another type of indexed addressing is used in the “case jump” instruction
or "jump table". In this case the destination address of the jump
instruction is computed as the sum of the base pointer and the
Accumulator data.
4-3.5. Register Addressing Modes
The register addressing modes are specific to the manipulation of the
8051 registers. There exist two categories of register manipulating
instructions:
i- General Register Instructions: The register banks, containing
registers R0 through R7, can be accessed by certain instructions which
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 occupies an address byte. When the instruction is executed one of
the eight registers in the selected bank is accessed. One of four banks is
selected at execution time by the two bank select bits in the PSW.
ii- Register-Specific Instructions: Some instructions are specific to a
certain register. For example, some instructions always operate on the
Accumulator, or Data Pointer, etc., so no address byte is needed to point
to it. The opcode itself does that. Instructions that refer to the
Accumulators as A assemble as accumulator-specific opcodes.

115
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

4-4. The 8051 Instructions By Category


The 8051 microcontroller instructions can be divided into the following
categories:

 Arithmetic Instructions
 Data Transfer Instructions
 Logic Instructions
 BOOLEEN Instructions
 Branching (JUMP & CALL) Instructions
In the following subsections we'll briefly describe the 8051 instructions,
according to the above categories.

4-4.1. Arithmetic Instructions


The menu of arithmetic instructions is listed in the table 5-2 below.

Table 4-2. Arithmetic instructions.

Mnemonic Operation
Addressing Modes Time
Dir Ind Reg Imm (us)
ADD A,<byte> A=A+<byte> x x x x 1
ADDC A,<byte> A=A+<byte>+C x x x x 1
SUBB A,<byte> A= A-<byte>-C x x x x 1
INC A A = A+1 Accumulator only 1
INC <byte> <byte>=<byte>+1 x x x 1
INC DPTR DPTR = DPTR+1 Data Pointer only 2
DEC A A = A-1 Accumulator only 1
DEC <byte> <byte>=<byte>-1 x x x 1
MUL AB B:A = A.B A & B only 4
DIV AB A = INT [A/B] A & B only 4
B = MOD[A/B]
DA Decimal Adjust Accumulator only 1

The following table indicates the addressing modes that can be used with
each instruction to access the <byte> operand. For example, the ADD
A,<byte> instruction can be written as follows:

ADD A,7FH (direct addressing)


ADD A,@RO (indirect addressing)
ADD A,R7 (register addressing)
ADD A, # 127 (immediate constant)

116
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

All of the arithmetic instructions execute in 1us except the INC DPTR
instruction, which takes 2 ns, and the multiply and divide instructions,
which take 4 ns. Note that any byte in the internal data memory space can
be incremented or decremented without going through the Accumulator.

One of the INC instructions operates on the 16-bit Data Pointer (DPTR).
The Data Pointer (DPTR) is used to generate 16-bit addresses for external
memory, so being able to increment it in one 16-bit operation is a useful
feature. The MUL AB instruction multiplies the Accumulator by the data
in the B register and puts the 16-bit product into the concatenated B and
Accumulator registers (B:A).

Note: 16-Bit Math

As we have pointed out earlier, the 8051 is an 8-bit microcontroller. This


basically means that each machine language opcode in its instruction set
consists of a single 8-bit value. This permits a maximum of 256
instruction codes (of which 255 are actually used in the 8051 instruction
set). The 8051 also works almost exclusively with 8-bit values. The
Accumulator is an 8-bit value, as is each register in the Register Banks,
the Stack Pointer (SP), and each of the many Special Function Registers
(SFRs) that exist in the architecture. In reality, the only values that the
8051 handles that are truly 16-bit values are the Program Counter (PC)
that internally indicates the next instruction to be executed, and the Data
Pointer (DPTR) which the user program may utilize to access external
RAM as well as directly access code memory. Other than these two
registers, the 8051 works exclusively with 8-bit values.

4-4.2. Data Transfer Instructions


The data transfer instructions are listed in the following tables. Table 4-3,
depicts the transfer instructions that access internal data memory and
Table 4-4 depicts the transfer instructions that access external data
memory. Table 4-5 depicts the lookup table instructions that read
program memory.

The MOV operand2, operand1 copies the value of operand2 into


operand1. The value of operand2 is not affected. Both operand1 and
operand2 must be in Internal RAM. The MOVX operand2, operand1
instructions transfer data between the Accumulator and a byte of external
data memory (external RAM). This is why “X” is appended to MOV.
There are two types of instructions, differing in whether they provide an
8-bit or 16-bit indirect address to the external data RAM.
117
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Table 4-3. Data transfer instructions.

Mnemonic Operation Addressing Modes Time


Dir Ind Reg Im (us)
MOV A,<src> A = <src> x x x x 1
MOV <dest>,A <dest> = A x x x 1
MOV <dest>,<src> <dest> = <src> x x x x 2
MOV DPTR,#data16 DPTR = 16-bit data x 2
PUSH <src> INC SP; x 2
MOV "@SP",<src>
POP <dest> MOV <dst>,"@SP" x 2
DEC SP
XCH A, <byte> A and <byte> x 1
exchange
XCHD A,@Ri A and Ri exchange x 1
lower nibble

Table 4-4. Transfer instructions that access external data memory

Address Bus Mnemonic Operation Time


Width (us)
8-bit MOVX A,@Ri Read ext RAM @Ri 2
8-bit MOVX @Ri,A Write ext RAM @Ri 2
16-bit MOVX A,@DPTR Read ext RAM @DPTR 2
16-bit MOVX @DPTR,A Write ext RAM @DPTR 2

In the first type, the contents of R0 or R1 in the current register bank


provide an 8-bit address multiplexed with data on P0. Eight bits are
sufficient for external I/O expansion decoding or for a relatively small
RAM array. For somewhat larger arrays, any output port pins can be used
to output higher-order address bits. These pins are controlled by an output
instruction preceding the MOVX. In the second type of MOVX
instruction, the Data Pointer generates a 16-bit address. P2 outputs the
high-order eight address bits (the contents of DPH), while P0 multiplexes
the low-order eight bits (DPL) with data. The P2 Special Function
Register retains its previous contents, while the P2 output buffers emit the
contents of DPH. This form of MOVX is faster and more efficient when
accessing very large data arrays (up to 64K bytes), since no additional
instructions are needed to set up the output ports. It is possible to use both
MOVX types in some situations. A large RAM array with its high-order
address lines driven by P2 can be addressed via the Data Pointer, or with
code to output high-order address bits to P2, followed by a MOVX
instruction using R0 or R1.
118
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Table 4-5. The lookup table instructions that read program memoy.

Mnemonic Operation Time


(us)
MOVC A,@A+DPTR Read Program memory at (A+DPTR) 2
MOVC A,@A+PC Read Program memory at (A+PC) 2

The MOVC A,@A+<base-reg> instructions load the Accumulator with


a code byte or constant from program memory. The address of the byte
fetched is the sum of the original unsigned 8-bit Accumulator contents
and the contents of a 16-bit base register, which may be either the Data
Pointer (DPTR) or the PC. Note that the first instruction, in the above
table can be used to lookup a table of up to 256 entries (numbered from 0
to 55). The number of desired entries is loaded in A, and the Data Pointer
(DPTR) is set up to point to the beginning of the table.

4-4.3. Logical Instructions


The logical instructions are listed in the following table:

Table 4-6. Logical instructions.

Mnemonic Operation Addressing Modes Time


Dir Ind Reg Im (us)
ANL A,<byte> A = A .AND. <byte> x x x x 1
ANL <byte>,A <byte>=<byte> .AND. A x 1
ANL <byte>,#data <byte>=<byte>.AND.#data 2
ORL A,<byte> A = A .ORL. <byte> x x x x 1
ORL <byte>,A <byte>=<byte> .ORL. A x 1
ORL <byte>,#data <byte>=<byte>.ORL.#data 2
XRL A,<byte> A = A .XRL. <byte> x x x x 1
XRL <byte>,A <byte>=<byte> .XRL. A x 1
XRL <byte>,#data <byte>=<byte>.XRL.#data 2
CLR A A= 00H Accumulator Only 1
CPL A A= .NOT.A Accumulator Only 1
RL A Rotate A Left 1 bit Accumulator Only 1
RLC A Rotate A Left through Accumulator Only 1
Carry
RR A Rotate A Right 1 bit Accumulator Only 1
RRC A Rotate A Right through Accumulator Only 1
Carry
SWAP A Swap nibbles in A Accumulator Only 1

119
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

4-4.4. Boolean Instructions


The Boolean instructions are listed in table 4-7

Table 4-7. Boolean instructions.

Mnemonic Operation Time (us)


ANL C,bit C=C .AND. bit 2
ANL C,/bit C=C .AND. NOT.bit 2
ORL C,bit C=C .OR. bit 2
ORL C,/bit C = C .OR. NOT.bit 2

MOV C,bit C = bit 1


MOV bit,C Bit = C 2
CLR C C= 0 1
CLR bit bit = 0 1
SETB C C=1 1
SETB bit bit = 1 1
CPL C C= .NOT. C 1
CPL bit bit = .NOT. bit 1
JC rel Jump if C=1 2
JNC rel Jump if C=0 2
JB bit/rel Jump if bit = 1 2
JNB bit/rel Jump if bit = 0 2
JBC bit/rel Jump if bit =1; CLR bit 2

120
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

4-4.5. Branching (Jump & Call Subroutine) Instructions


When an 8051 is first initialized, it resets the PC to 0000h. The 8051 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. The
conditional jump instructions are listed in table 4-8

Table 4-8. Jump instructions of the 8051 microcontroller

Mnemonic Operation Time (us)


JMP addr Jump to addr 2
JMP @A+DPTR Jump to A+DPTR 2
CALL addr Call subroutine at addr 2
RET Return from subroutine 2
RETI Return from interrupt routine 2
NOP No operation 1

AJMP addr11 (absolute jump) transfers program execution to the


indicated address, which is formed at run-time by concatenating the high-
order five bits of the PC (after incrementing the PC twice), opcode bits 7
through 5, and the second byte of the instruction. The destination must
therfore be within the same 2KB (211) block of program memory as the
first byte of the instruction following AJMP.
SJMP rel (short jump) instruction lets the PC incremented by 2 and then
the relative offset is added to the PC to get the new address. The next
instruction will come from there. This is good for short jumps (+/- 127
locations from the incremented PC address).
The ACALL addr11 (absolute call) instruction unconditionally calls a
subroutine located at the indicated address. The instruction increments the
PC twice to obtain the address of the following instruction, then pushes
the 16-bit result onto the stack (low-order byte first) and increments the
Stack Pointer twice. The destination address is obtained by successively
concatenating the five high-order bits of the incremented PC, opcode bits
7 through 5, and the second byte of the instruction. The subroutine called
must therefore start within the same 2KB (2 11) block of the program
memory as the first byte of the instruction following ACALL. No flags
are affected.

121
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Example: Assume that SP initially equals 07H and the label SUBRTN is
at program memory location 0345H. After executing the following
instruction:

ACALL SUBRTN
at location 0123H, SP contains 09H, internal RAM locations 08H and
09H will contain 25H and 01H, respectively, and the PC contains 0345H.

LCALL addr16 (long call) calls a subroutine located at the indicated


address. The instruction adds three to the program counter to generate the
address of the next instruction and then pushes the 16-bit result onto the
stack (low byte first), incrementing the Stack Pointer by two. The high-
order and low-order bytes of the PC are then loaded, respectively, with
the second and third bytes of the LCALL instruction. Program execution
continues with the instruction at this address. The subroutine may
therefore begin anywhere in the full 64KB program memory space.
Example: Assume we've initially the Stack Pointer equals 07H and the
label SUBRTN is assigned to program memory location 1234H. After
executing the instruction:

LCALL SUBROTN

at location 0123H, the Stack Pointer will contain 09H, internal RAM
locations 08H and 09H will contain 26H and 01H, and the PC will
contain 1234H.

4-4.6. Conditional Jump Instructions


The conditional jump instructions are listed in table 4-9
Table 4-9. Jump instructions of the 8051 microcontroller

Mnemonic Operation Addressing Modes Time


Dir Ind Reg Im (us)
JZ rel Jump if A = 0 Accumulator Only 2
JNZ rel Jump if A ≠ 0 Accumulator Only 2
DJNZ <byte>,rel Decrement and x x 2
jump if not 0
CJNE A,<byte>,rel jump if A ≠ <byte> x x 2
CJNE A,#data,rel jump if <byte> ≠ x x 2
#data

122
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

The DJNZ instruction (decrement and jump if not zero) is usually used in
loop control. For instance, for looping 10 times, load a counter byte with
10 and terminate the loop with DJNZ to the beginning of loop, as follows:

MOV COUNTER,#10
LOOP: (begin loop)
:
:
(end loop)
DJNZ COUNTER,LOOP
(continue)

4-5. Stack Operations in 8051 Microcontrollers


You may notice that there exist 2 instructions to handle stack operations
(PUSH and POP) in the data transfer instructions of the 8051. Stack is
simply a memory device that holds the return address for a call. In a more
technical language, the stack is a Last-in-first-out (LIFO) memory buffer.

Figure 4-10. Illustration of the stack operation of the 8051 microcontroller.

The PUSH instruction, locates on the stack the contents of the address,
first to increase the stack pointer and then follow the contents of the
address is copied into RAM indicating the stack pointer SP.

1 (SP) = (SP) +1 Increase Stack pointer to the next position


Putting on the stack (address pointed to by SP)
2 ((SP)) = (Address)
content management

123
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Figure 4-10. Illustration of the stack PUSH operation of the 8051 microcontroller.

The POP instruction reads the contents of the address of the stack
indicating the SP (stack pointer) and places it in the specified address,
then decrements the stack pointer SP leaving the position.

Recovered in the direction of the contents of


1 (Address) = ((SP))
the stack (pointed to by SP)
Decrement Stack Pointer to the previous
2 (SP) = (SP) -1
position

Figure 4-10. Illustration of the stack POP operation of the 8051 microcontroller.

What happens is that before branching to the subroutine, the location of


the next instruction after the call is pushed onto the stack. When the
return is encountered the return address is popped off of the stack and
placed into the PC so that the next instruction fetched is the one after the
call. This is sort of like stacking (pushing) books in a pile, one on top of
another with the most recent addition on top of the stack. Then as a book
is taken off of the stack (popped) the next one is on top. As each byte of
the two byte return address is pushed onto the stack, the stack pointer is
incremented once. Then when the return is encountered and each byte of
the two byte return address is popped off of the stack, the stack pointer is
decremented once for each byte. The end result is that the stack pointer is
124
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

always pointing to the current position on the stack where the next byte of
address would be popped off.
To explain this again a little more explicitly, when the call is encountered,
the stack pointer is incremented and the first (low) byte is pushed onto the
stack. Then the stack pointer (SP) is incremented again and the second
(high) byte is pushed. When the return is encountered, the first (high)
byte is popped off the stack and the stack pointer is decremented. Then
the second (low) byte is popped off of the stack and then the stack pointer
is decremented. The stack pointer (SP) provides the address in internal
RAM where the first byte that is to be popped is located. This is a little
confusing to some but it happens automatically for calls and returns. But
the stack can be used to pass data between routines and is commonly used
in C and other languages. The data to be passed is pushed onto the stack
and the other routine is called or jumped to and the data is popped off of
the stack into registers for use by the second routine.

Care must be taken to make sure there are an equal number of pushes and
pops. One of the hardest bugs to find is a mismatch in pushes and pops. It
causes the program to act in wild and mysterious ways that is difficult to
decipher. To get rid of such problems, just note that there must be a return
for every call and a pop for every push or there will be problems.

4-6. The 8051 Assembly Programming


The assembly language of a specific microcontroller is composed of the
set of instructions which are specific to this microcontroller. In this
chapter we‟ll present the main features of the 8051 microcontroller
assembly language and how it can be used to write application programs
for 8051-based systems.

After writing your program in assembly language, which is called the


source code, you can translate it into machine language (assemble it)
using a special assembler program. A microcontroller assembler (like
A51) is a program that allows you to write the microcontroller
instructions in symbolic form, which is much more easy to read and
understand, and then it translates the microcontroller instructions (or
assembles them) into a binary code. The result of the assembler (the
binary code) is then downloaded to the microcontroller. However,
programs are really stored as hex numbers inside microcontrollers. The
Assembler program usually does that additional translation (from binary
to hexadecimal code).

125
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

4-6.1. Instruction Format for AS51 Assembler


Assembly language follows some format that we describe here, in the
following figure.

Label: Opcode Operands ; Comment


mnemonic Argument1 Argument2

Fig. (4-11). The basic instruction format for A51 assembler.

where Label is an optional reference to the instruction address in the code


memory and should be followed by a colon ":". A label is a way of telling
the assembler that this line has a name that can be referred to later to get
back to it. A comment is always started with a semicolon “;” and tells the
assembler to ignore all the following on that line because it is a comment.
Labels and comments are not actually a part of the instruction core.

The opcode is a reserved name (e.g., MOV or ADD) for a class of


instruction. The operands argument1, argument2 are optional. There may
be from zero to three operands, depending on the opcode. When present,
they take the form of either literals or identifiers for data items.

Operand identifiers are either reserved names of registers or are assumed


to be assigned to data items declared in another part of the program.
When two operands are present in an instruction that modifies data, the
right operand is the source and the left operand is the destination. The
above table indicates the reserved words of the A51 assembler. Don‟t use
these words as labels in your source code.

Table 4-1. The Assembler A51 Reserved Names:

Word Address Word Address Word Address


AC =00D6 SM0 =009E SM1 =009E
ACC =00E0 P0 =0080 SM2 =009D
ACC.0 =00E0 P0.0 =0080 SP =0081
ACC.1 =00E1 P0.1 =0081 T2CON =00C8
ACC.2 =00E2 P0.2 =0082 T2CON.0 =00C8
ACC.3 =00E3 P0.3 =0083 T2CON.1 =00C9
ACC.4 =00E4 P0.4 =0084 T2CON.2 =00CA
ACC.5 =00E5 P0.5 =0085 T2CON.3 =00CB
ACC.6 =00E6 P0.6 =0086 T2CON.4 =00CC
ACC.7 =00E7 P0.7 =0087 T2CON.5 =00CD
B =00F0 P1 =0090 PCON =0087
B.0 =00F0 P1.0 =0090 TCON =0088
B.1 =00F1 P1.1 =0091 TCON.0 =0088
126
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Word Address Word Address Word Address


B.2 =00F2 P1.2 =0092 TCON.1 =0089
B.3 =00F3 P1.3 =0093 TCON.2 =008A
B.4 =00F4 P1.4 =0094 TCON.3 =008B
B.5 =00F5 P1.5 =0095 TCON.4 =008C
B.6 =00F6 P1.6 =0096 TCON.5 =008D
B.7 =00F7 P2 =00A0 TCON.6 =008E
CPRL2 =00C8 P2.0 =00A0 TCON.7 =008F
CT2 =00C9 P2.1 =00A1 TF0 =008D
CY =00D7 P2.2 =00A2 TF1 =008F
DPH =0083 P2.3 =00A3 TF2 =00CF
DPL =0082 P2.4 =00A4 TH0 =008C
EA =00AF P2.5 =00A5 TH1 =008D
ES =00AC P2.6 =00A6 TH2 =00CD
ET0 =00A9 P2.7 =00A7 TI =0099
ET1 =00AB P3 =00B0 TL0 =008A
ET2 =00AD P3.0 =00B0 TL1 =00CB
EX0 =00A8 P3.1 =00B1 TL2 =00CC
EX1 =00AA P3.2 =00B2 TMOD =0089
EXEN2 =00CB P3.3 =00B3 TR0 =008C
EXF2 =00CE P3.4 =00B4 TR1 =008E
F0 =00D5 P3.5 =00B5 TR2 =00CA
IE =00A8 P3.6 =00B6 T2CON =00C8
IE.0 =00A8 P3.7 =00B7 T2CON.0 =00C8
IE.1 =00A9 PS =00BC T2CON.1 =00C9
IE.2 =00AA PSW =00D0 T2CON.2 =00CA
IE.3 =00AB PSW.0 =00D0 T2CON.3 =00CB
IE.4 =00AC PSW.1 =00D1 T2CON.4 =00CC
IE.5 =00AD PSW.2 =00D2 T2CON.5 =00CD
IE.6 =00AE PSW.3 =00D3 T2CON.6 =00CE
IE.7 =00AF PSW.4 =00D4 T2CON.7 =00CF
IE0 =0089 PSW.5 =00D5 IP =00B8
IE1 =00bB SBUF =0099 IP.0 =00B8
INT0 =00B2 TB8 =009B IP.1 =00B9
INT1 =00B3 RS0 =00D3 IP.2 =00BA
PCON =0087 RS1 =00D4 IP.3 =00BB
PT0 =00B9 PX0 =00B8 IP.4 =00BC
PT1 =00BB PX1 =00BA IP.5 =00BD
PT2 =00BD IT0 =0088 IP.6 =00BE
RI =0098 TXD =00B1 IP.7 =00BF
RXD =00B0 TCLK =00CC RCLK =00CD

With most instructions, especially those involving data transfer, the


instruction is first, followed by at least 1 space, then the destination
followed by a comma, and then the source. For instance, the MOV
instruction can be written in the following general format:

127
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

MOV <destination>, <source>

The destination is where the result of the instruction will end up and the
source is where the data is coming from.

As we stated above, you can use any suitable assembler program (like
A51) to write or edit instructions in a symbolic form, and then convert
these instructions into object code or hex numbers. Part of the byte is the
opcode and the other part is which register is affected or used. Here is an
example of the problem of adding 2 plus 2: This file will be called
example1.asm

Example1.asm:

mov R0,#2
mov A,#2
add A,R0

The first line of example1.asm moves a 2 into register R0. The second
line moves a 2 into the accumulator. This is all the data we need for the
program. The third line adds the accumulator with R0 and stores the
result back into the accumulator A, destroying the 2 that was originally in
it. The accumulator has a 4 in it now and R0 still has a 2 in it.
Next we will read a switch, and light a LED if the switch is pressed. Bit 0
of P1 will be the switch. When the switch is closed or pressed, bit 0 will
be a 1, and if the switch is open or not pressed, bit 0 will be a 0. Bit 0 of
P0 will be the LED. If bit 0 is a 0 the LED is off and if bit 0 is a 1, the
LED will be on. All the other bits of both P0 and P1 will be ignored and
assumed to be all 0's, for the sake of discussion. This will be
expample2.asm

Example2.asm:
start: mov A,P1 ;read the switch
mov P0,A ;write to the led
sjmp,start ;go to start

The first line has a label. In this case it is start. All labels are followed by
the colon symbol “:” which tells the assembler that this is a label. Also a
comment (preceded by „;‟) is added to the line to remind you of what that
line does.

128
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

As we've shown in the last chapter, there are several ways of addressing
variables in the microcontroller. One is the register addressing, R0, R1,
R2, and so on. Another is by direct addressing. This uses the actual
address in internal ram where the variable is. Using a name with the .rs
directive is a form of direct addressing. Here the assembler assigns the
actual address of the named variable by which order the .rs's are in.

If the variable first was actual location 0 then the variable secnd would be
actual location 1. Location and address mean the same thing. When the
assembler assembles the program, the names are dropped (to protect the
innocent) and the actual addresses are used.
Another form of addressing is called immediate addressing. This is the
form used in the original 2 plus 2 problem. It is indicated by the # symbol
in front of the number. This tells the assembler that the number is in the
instruction, not somewhere else. Also this method was used in the above
example where the variables first and secnd were loaded with a 2. The 2
was in the instruction not somewhere else. But when we started getting
the numbers to add we used direct addressing, using the names. Here the
2's were in locations and not in the instruction. Here are those instructions
and what type of addressing was used in each:

first: .rs 1 ;this is a directive not instructon


secnd: .rs 1 ;so is this one
mov first,#2 ;direct,immediate
mov secnd,#2 ;direct,immediate
mov A,first ;implied,direct
add A,secnd ;implied,direct

Here's the original 2 plus 2 problem and the addressing modes of each
instruction:

mov R0,#2 ;register,immediate


mov A,#2 ;implied,immediate
add A,R0 ;implied,register

Notice that each instruction can have two different addressing modes, one
for the destination and one for the source. Also notice that the A is an
implied address. Register refers strictly to the registers R0, R1, R2, and
so on, even though we've referred previously to the accumulator as a
register. In microprocessors, the accumulator is the A register. In the
microcontroller the accumulator is in the special function registers but the
instruction implies that the accumulator will be used as either the source
or the destination, depending on the instruction.
129
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Implied addressing is a method of addressing that shortens the number


of bytes any particular instruction assembles into. The idea of implied
addressing is to cram as much as possible into as few bytes as possible of
the microcontroller memory. Implied addressing limits choices in the use
of the instruction, you always have to use the accumulator as either the
source or the destination, but it shrinks the size of the instruction, so that
more instructions can fit inside the micro. This is a choice made by the
maker of the micro, and is not up for discussion. It's a trade off of
flexibility vs. size. That's why you'll see lots of instructions that use the
accumulator.

In the case of an instruction like add A,secnd, two bytes are


assembled. The first byte says that this is an add instruction and that the
accumulator is implied as the destination. The second byte is the direct
address of the source variable, secnd. This is transparent to the
programmer because we are using an assembler, but the underlying
results are noteworthy when trying to cram the most into the
microcontroller.
Another form of addressing variables is called register indirect or just
plain indirect addressing. This is a little more complicated. Here the
address is held in a register, either R0 or R1. The following is another
example of the 2 plus 2 problem using register indirect addressing. This is
example5.asm

Example5.asm:

buffer: .rs 2 ;reserve 2 locations for data


mov R0,#buffer ;set R0 to start of buffer
mov @R0,#2 ;put 2 in buffer 1st location
inc R0 ;increment R0 to point to 2nd byte
mov @R0,#2 ;put 2 in buffer 2nd location
mov R0,#buffer ;set R0 to start of buffer
mov A,@R0 ;get the first 2
inc R0 ;step to the second 2
add A,@R0 ;add second 2 to first 2

Line 1 is again is a reserve storage directive, but this time we are


reserving two locations, one for each 2 in the problem. Line 2 sets R0 to
point to the first location of the buffer we've created with the .rs directive.
As stated before, the # means immediate, but in this case the assembler
sees that the first character after the # is not a number, and, instead finds
the label buffer and gets the direct address of where it is in the internal
130
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

ram and puts that address in R0, immediately. That's what happens on
that one line! Line 3 stores a 2 in the first location of buffer.

The @ symbol tells the assembler that the following register holds the
address (indirect) of where to put the 2 into. So after this instruction, the
first byte of buffer has a 2 in it. Line 4 increments or steps R0 to the
second location in buffer. If R0 had the address of the first byte, then
incrementing it by 1 now results in the address of the second byte being
in R0. Line 5 does the same thing that line 3 did, except that the 2 is
stored in the second byte of buffer. Line 6 does the same thing that line
2 did, getting R0 to point to the first location in buffer. Line 7 moves
the first byte of buffer (the first 2) into the accumulator. Line 8 steps
R0 to the address of the second 2 in buffer. Line 9 adds the second 2 to
the first 2 and stores the result in the accumulator. Repeating what we did
for the other example programs, here are the addressing modes of each
line:

buffer: .rs 2 ;this is a directive


mov R0,#buffer ;register,immediate
mov @R0,#2 ;indirect,immediate
inc R0 ; adding 1 to R0
mov @R0,#2 ;indirect,immediate
mov R0,#buffer ;register,immediate
mov A,@R0 ;implied,indirect
inc R0 ; adding 1 to R0
add A,@R0 ;implied,indirect

4-6.2. Handling Interrupts in 8051 Assembly Language


As we have mentioned so far, an interrupt is some event which
interrupts the normal program execution. In fact, the program flow is
always sequential; being altered only by those instructions which cause
program flow to branch or jump in some way. However, interrupts give
us a mechanism to "put on hold" the normal program flow, execute an
interrupt service routine (ISR), and then resume normal program flow as
if we had never left it. This interrupt service routine (ISR), which is
sometimes called interrupt handler, is only executed when a certain event
(interrupt) occurs. The event may be one of the timers "overflowing,"
receiving a character via the serial port, transmitting a character via the
serial port, or one of two "external events." The 8051 may be configured
so that when any of these events occur the main program is temporarily
suspended and control passed to a special section of code which
presumably would execute some function related to the event that
131
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

occurred. Once complete, control would be returned to the original


program. The main program never even knows it was interrupted. For
example, let‟s say we have a large 16k program executing many
subroutines performing many tasks. Lets also suppose that we want our
program to automatically toggle the P3.0 port every time timer 0
overflows. The code to do this is as simple as follows:

JNB TF0, SKIP_TOGGLE


CPL P3.0
CLR TF0
SKIP_TOGGLE:

Since the TF0 flag is set whenever timer 0 overflows, the above code will
toggle P3.0 every time timer 0 overflows.

In order to use any of the interrupts in the MCS-51, the following three
steps must be taken.

 Set the EA (enable all) bit in the IE register to 1 (use SETB).


 Set the corresponding individual interrupt enable bit in the IE register
to 1 (using SETB instruction).
 Begin the interrupt service routine at the corresponding Vector
Address of that interrupt (using LCALL).

The following program shows how to use interrupts in the serial comm.-
unication between the 8051 and other computers, via the serial port.

/* ***************************************************************
Interrupt Serial I/O functions for the 8051:
***************************************************************** „
These functions perform buffered serial I/O via interrupts. The 8051 hardware
generates an interrupt (if enabled) whenever the RI or TI flags are set in the SCON
register: INTERRUPT = TI | RI;
The RI flag (and interrupt) occurs whwnever a character is detected and received by
the UART. The TI flag (and interrupt) occur whenever the transmitter finishes
sending a character and is ready for the next. Both RI and TI must be cleared
manually by the program in order to "turn off" the interrupt.

Receiving data:
When the character is received, an interrupt is generated. The interrupt handler checks
the RI flag, and finding a character present, clears the TI flag, and stores the character
in a circular buffer.
132
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

The Chkch() function when called by the application program checks the Read/Write
pointers to the receive buffer, and if it finds them to be different, removes the oldest
character from the buffer and returns it .If the pointers are the same (buffer is empty),
a -1 is returned.

Transmitting data:
The T8 bit (unused in MODE 1) is used to record the condition of the transmitter. It
is set to one when a character is sent, and set to zero when no character is available.
This is required so that we can know when the transmitter has to be re-started. We
cannot use the TI bit directly, since it must be kept clear to avoid continuous *
interrupts.When Putch() is called, it first checks to insure that there is available space
in the transmitter output buffer. If there is not ,it enters a loop, waiting for it. The next
transmit interrupt will remove a character from the buffer, making room for the new
one. Note, a multi-tasking kernal etc. should "swap" at this point, to *allow another
task to run while waiting for TX buffer space.

If space is available, the character is inserted into the queue .The T8 flag is tested, and
if clear, the TI bit is manually set to cause an interrupt. This is required since TI was
cleared and no character loaded the last time. If T8 is NOT set, we assume that a
character is being transmitted, and will generate an interrupt when it is finished. When
the interrupt occurs, the interrupt handler notices the TI bit set, clears it, loads the next
character from the output buffer int the UART, and sets T8 so we know another
interrupt will occur. If no data is available, the T8 bit is cleared, so that we know to
"kick " the transmitter */
#
include <8051io.h> // 1001 I/O definitions
#include <8051reg.h> // 1001SFR definitions
#defineINTBASE 0100$ // Base address for interrupt vector table
#defineSRSIZE 1 // Size of RX buffer
#defineSTSIZE 1 // Size of TX buffer
register char SRbuf[SRSIZE], SRwp, SRrp; /* RX buffer & pointers/*
register char STbuf[STSIZE], STwp, STrp; /* TX buffer & pointers

/* ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main program... Display a "welcome" message, and echo input to output
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

main)(
{
int a;
SRwp = SRrp = SRbuf; /* Initialize RX buffer to EMPTY/*
STwp = STrp = STbuf; /* Initialize TX buffer to EMPTY/*
IE |= 0x90; /* Enable serial interrupt/*
SCON &= 0xF7; /* Clear T8 to force "kick/* "
Putstr("This is a test;" (:
for(;;) /* Loop to echo characters/*
If ((a = Chkch()) != -1) Putch(a);
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
133
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Putstr(char *string) // Write a string to the serial port


{
while(*string( Putch(*string++);
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Write a character to the serial port output buffer
Putch() asm
{
MOV A,STwp ; Get TX write pointer
MOV R1,A ; Save for later
INC A ; Advance pointer
CJNE A,#STbuf+STSIZE ; PU1 Buffer has wrapped
MOV A,#STbuf ; Reset to start
PU1: CJNE A,STrp,PU2 ; Buffer is full, wait
SJMP PU1 ; Keep trying
PU2: MOV R2,A „ Save
MOV R0,#-5 ; Offset to parameter
LCALL auto0 ; Set up address
MOV A,[R0] ; Get char to write
MOV [R1],A ‫ك‬Save in buffer
MOV STwp,R2 ; Set new pointer
JB SCON.3,PU3 ; Transmitter is already running
SETB SCON.1 ; give it a kick-start
PU3: EQU
}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //// Test for a character received from the serial port
Chkch() asm
{
MOV A,SRrp Get RX read pointer
CJNE A,SRwp,; CH1 Any data pending;
MOV A,#-1 No, return -1
MOV B,A Full 16 bit int
RET
CH1: MOV R0,A Set up pointer
MOV A,[R0] Get character under pointer
INC R0 Advance to next
CJNE R0,#SRbuf+SRSIZE,; CH2 Buffer overflow
MOV R0,#SRbuf Reset pointer
CH2: MOV SRrp,R0 Save new pointer
MOV B,#0 Zero high
}///////////////////////////////////////////////////////////////////////////////////////////////////
///////// Serial interrupt handler
asm {
// Take over interrupt vector, save registers & jump to handler
SI1: EQU Record code address
ORG INTBASE+$23 Position to serial I/O interrupt
PUSH PSW Save flags
PUSH A Save ACC
LJMP SI1 Enter handler
134
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

ORG SI1 Restore program counter


PUSH R0 Save R0
// ///// Test for character received & buffer if found
JNB SCON.0, SI3 ; No data waiting
MOV R0,SRwp Get RX write pointer
CLR SCON.0 Indicate data RXed
MOV [R0],SBUF Write to buffer
INC R0 Advance
CJNE R0,#SRbuf+SRSIZE,; SI2 Buffer overflow
MOV R0,#SRbuf Reset buffer pointer
SI2: MOV SRwp,R0 Resave RX write pointer

// Check for character waiting to transmit


SI3: JNB SCON.1,; SI3A Transmitter not ready
CLR SCON.1 Reset transmitter
MOV A,STrp Get TX read pointer
CJNE A,STwp,; SI4 Data to send;
CLR SCON.3 Shut down transmitter
// Restore registers & exit interrupt
SI3A: POP R0 Restore R0
POP A Restore ACC
POP PSW Restore PSW
RETI
// Character was found - remove from buffer & send
SI4: MOV R0,A Set pointer
MOV SBUF,[R0] Get data
INC R0 Advance pointer
CJNE R0,#STbuf+STSIZE,; SI5 Buffer overflow
MOV R0,#STbuf Reset pointer
SI5: MOV STrp,R0 Resave TX write pointer
SETB SCON.3 ;Indicate transmitter in use
SJMP SI3A ;And exit
}

4-6.3. The 8051 Development Tools


As we mentioned earlier, the microcontroller assembler is a program that
allows you to write the microcontroller instructions in symbolic form,
which is much easier to read and understand, and then it converts
microcontroller instructions into binary or hex numbers. You use an
assembler with the object in mind of generating a file to download to the
microcontroller.

i. AS31 Assembler Program


AS31 is a free is an 8051 macro assembler (originally written by Ken
Stauffer). It includes important features and emits object modules
(*.OBJ), and standard Intel-hex output format for use with EPROM and
microcontroller programmers. AS31 is a good tool for building small
135
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

8051-based projects that are written in 100% 8051 assembly language.

ii. A51 Assembler Program


The A51 assembler program, for the 8051 microcontroller family,
translates an assembler source file into a relocatable object module. The
Assembler A51 supports all 8051 derivatives from companies like Intel,
Atmel, Analog Devices, Cypress, Dallas Semiconductor, Infineon, OKI,
Philips, SMC, Synopsis, TDK, Temic, and Triscend.

If the DEBUG control is used, the object file contains full symbolic
information for debugging. In addition to the object file, the A51
assembler generates a list file which may optionally include symbol table
and cross reference information. The A51 assembler is fully compatible
with Intel ASM-51 source modules.

Fig. (4-3). Compiling and assembling microcontroller source code.

The A51 assembler supports all members of the 8051 family. The special
function register (SFR) set of the 8051 is predefined. However, the
NOMOD51 control lets you override these definitions with processor-
136
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

specific include files. The A51 assembler is shipped with include files for
the 8051, 8051Fx, 8051GB, 8052, 80152, 80451, 80452, 80515, 80C517,
80C515A, 80C517A, 8x552, 8xC592, 8xCL781, 8xCL410 and 80C320
microcontrollers. You can easily create include files for other 8051 family
members.

The A51 Assembler program is usually bundled as a part of an integrated


development environment (IDE). The IDE's, like Vision2 from Keil
Software Inc., usually have a toolset that includes an assembler, a C-
compiler, a linker, a HEX converter, a debugger, and other associated
tools for a particular device family like the 8051, 251. All of the tools or
programs in a toolset are dedicated to generating target code for a specific
family of chips. The Vision2 IDE includes the following components:

C-source code compiler (C51)


Macro Assembler (A51 Assembler )
Linker/Locator (BL51)
Object-HEX Converter (OH51)

iii. AS51 Directives


The ASM directive signals the beginning of a block of assembler source
text to merge into the .SRC file generated using the SRC directive. The
ENDASM directive signals the end of the source text block. This source
text can be thought of as in-line assembly. However, it is output to the
source file generated only when using the SRC directive. The source text
is not assembled and output to the object file.

In µVision you may set a file specific option for C source files that
contain ASM/ENDASM sections as follows:

1. Right click on the file in the Project Window — Files tab


2. Choose Options for... to open Options — Properties page
3. Enable Generate Assembler SRC file
4. Enable Assemble SRC file.

µVision generates an assembler source file (.SRC) and translates this file
with the Assembler which generates an object file (.OBJ). The linker
links this object file with other object files from the project and creates
the target application program.

Note: The ASM and ENDASM directives may occur only in the source
file as part of a #pragma.

137
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Example4.asm
extern void test ();

void main (void) {


test ();

#pragma asm
JMP $ ; endless loop
#pragma endasm
}

The ENDASM directive signals the end of a block of assembler source


text to merge into the .SRC file generated using the SRC directive. The
ASM and ENDASM directives may occur only in the source file as part
of a #pragma.

Example5.asm
extern void test ();

void main (void) {


test ();
#pragma asm
JMP $ ; endless loop
#pragma endasm
}

The SRC « (filename) » directive creates an assembler source (.SRC) file


instead of an object (.OBJ) file. The source file may be assembled with
the assembler. The source file is saved as filename if specified.
Otherwise, the source file is saved as the path and base name of the C
source file with a .SRC extension.

Examples8.asm
C51 SAMPLE.C SRC
C51 SAMPLE.C SRC(SML.ASM)
#pragma src

You use the ROM directive to specify the size of the program memory.
This directive affects the coding of the JMP and CALL instructions. It
tkes the arguments are (SMALL), (COMPACT), (LARGE), (D512K), or
(D16M) and the default is LARGE.
138
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Table 5.2. Assembler AS51 Directives


Option Description
SMALL CALL and JMP instructions are coded as ACALL and
AJMP. The maximum program size may be 2 KBytes.
The entire program must be allocated within the 2 KByte
program memory space.
COMPACT CALL instructions are coded as LCALL. JMP
instructions are coded as AJMP within a function. The
size of a function must not exceed 2 KBytes. The entire
program may, however, comprise a maximum of 64
KBytes. The type of application determines whether or
not ROM (COMPACT) is more advantageous than
ROM (LARGE). Any code space saving advantages in
using ROM (COMPACT) must be empirically
determined.
LARGE CALL and JMP instructions are coded as LCALL and
LJMP. This allows you to use the entire address space
without any restrictions. Program size is limited to 64
KBytes. Function size is also limited to 64 KBytes.
D512K† 19-bit ACALL and AJMP instructions are generated.
(Dallas 390& Maximum program size may be 512 KBytes. This mode
variants) is available only for the Dallas 390 & compatible MCUs.
D16M† 24-bit LCALL instructions and 19-bit AJMP
(Dallas 390) instructions are generated. Max program size is 16MB.

Examples9.asm
C51 SAMPLE.C ROM (SMALL)
#pragma ROM (SMALL)

iv. Asembler Startup Code


Startup code is executed immediately upon reset of the target system. The
Keil startup code performs (optionally) the following operations in order:
 Clears internal data memory
 Clears external data memory
 Clears paged external data memory
 Initializes the small model reentrant stack and pointer
 Initializes the large model reentrant stack and pointer
 Initializes the compact model reentrant stack and pointer
 Initializes the 8051 hardware stack pointer
 Transfers control to code that initializes global variables
139
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

Following is a list of the startup files that are available.

Table 5.4. Assembler AS51 Directives


Startup File Description
STARTUP.A51 Startup code for classic 8051 devices.
START_AD.A51 Startup code for Analog Devices MCU‟s.
START390.A51 Startup code for Dallas MCU‟s
START4XX.A51 Startup code for Dallas MCU‟s
STARTLPC.A51 Startup code for Philips LPC700 devices series.
START900.A51 Startup code for Philips LPC90x - LPC93x devices.
START950.A51 Startup code for Philips LPC95x - LPC99x devices.
START_MX.A51 Startup code for Philips 80C51MX devices.
START751.A51 Startup code for Philips 80C75x devices.
START_XC.A51 Startup code for Infineon XC800 devices.
STARTUP32.A51 Startup code for ST uPSD32xx devices.
STARTUP34.A51 Startup code for ST uPSD33xx devices.
STARTUP34.A51 Startup code for ST uPSD34xx devices.

Copy the appropriate startup file from the \KEIL\C51\LIB\ folder into
your project folder and make any changes to the copy. Each startup file
provides constants you may change to control the operations performed at
startup.

v. Variable Initialization Code


The variable initialization files INITxxx.A51 contains the initialization
routine for variables in the memory areas bit, data, idata, pdata, xdata,
and far that were explicitly initialized. Variable initializations for the
memory areas code and far const are directly inserted into the ROM
image and do not require initialization by INITxxx.A51. The same is true
for the memory type const xdata when you use the XCROM directive.

The INIT_TNY.A51file is a reduced version of INIT.A51that may be


used for projects that do not contain XDATA memory. You should use
this file when you write code for single-chip devices, like the Philips LPC
series, that contain variable initializations in data space.

If your system is equipped with a watchdog timer, you can integrate a


watchdog refresh into the initialization code using the watchdog macro.
This macro needs to be defined only if the initialization takes longer than
the watchdog cycle time. For example, if you are using an Infineon C515,
the macro could be defined as follows:

140
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

WATCHDOG MACRO
SETB WDT
SETB SWDT
ENDM

If the C application contains variables in the far memory space that are
initialized, you need to set the initialization file the XBANK define to 1.

141
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

4-7. Summary
The 8051 is an 8-bit microcontroller. This basically means that each
machine language opcode in its instruction set consists of a single 8-bit
value. This permits a maximum of 256 instruction codes (of which 255
are actually used in the 8051 instruction set).

An addressing mode refers to how you are addressing a given memory


location. In summary, the addressing modes are as follows, with an
example of each:

Immediate Addressing MOV A,#20h


Direct Addressing MOV A,30h
Indirect Addressing MOV A,@R0
External Direct MOVX A,@DPTR
Code Indirect MOVC A,@A+DPTR

Each of these addressing modes provides important flexibility.


Alphabetical List of 8051/8052 Instructions
ACALL: Absolute Call
ADD, ADDC: Add Accumulator (With Carry)
AJMP: Absolute Jump
ANL: Bitwise AND
CJNE: Compare and Jump if Not Equal
CLR: Clear Register
CPL: Complement Register
DA: Decimal Adjust
DEC: Decrement Register
DIV: Divide Accumulator by B
DJNZ: Decrement Register and Jump if Not Zero
INC: Increment Register
JB: Jump if Bit Set
JBC: Jump if Bit Set and Clear Bit
JC: Jump if Carry Set
JMP: Jump to Address
JNB: Jump if Bit Not Set
JNC: Jump if Carry Not Set
JNZ: Jump if Accumulator Not Zero
JZ: Jump if Accumulator Zero
LCALL: Long Call
LJMP: Long Jump
MOV: Move Memory 142
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

MOVC: Move Code Memory


MOVX: Move Extended Memory
MUL: Multiply Accumulator by B
NOP: No Operation
ORL: Bitwise OR
POP: Pop Value From Stack
PUSH: Push Value Onto Stack
RET: Return From Subroutine
RETI: Return From Interrupt
RL: Rotate Accumulator Left
RLC: Rotate Accumulator Left Through Carry
RR: Rotate Accumulator Right
RRC: Rotate Accumulator Right Through Carry
SETB: Set Bit
SJMP: Short Jump
SUBB: Subtract From Accumulator With Borrow
SWAP: Swap Accumulator Nibbles
XCH: Exchange Bytes
XCHD: Exchange Digits
XRL: Bitwise Exclusive OR

Each of these instructions has several variants. For instance, the MOV
instruction may have one of the following formats:

Instructions OpCode Bytes Cycles Flags


MOV @R0,#data 0x76 2 1 None
MOV @R1,#data 0x77 2 1 None
MOV @R0,A 0xF6 1 1 None
MOV @R1,A 0xF7 1 1 None
MOV @R0,iram addr 0xA6 2 2 None
MOV @R1,iram addr 0xA7 2 2 None
MOV A,#data 0x74 2 1 None
MOV A,@R0 0xE6 1 1 None
MOV A,@R1 0xE7 1 1 None
MOV A,R0 0xE8 1 1 None
MOV A,R1 0xE9 1 1 None
MOV A,R2 0xEA 1 1 None
MOV A,R3 0xEB 1 1 None
MOV A,R4 0xEC 1 1 None
MOV A,R5 0xED 1 1 None
MOV A,R6 0xEE 1 1 None
MOV A,R7 0xEF 1 1 None
143
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

MOV A,iram addr 0xE5 2 1 None


MOV C,bit addr 0xA2 2 1 C
MOV DPTR,#data16 0x90 3 2 None
MOV R0,#data 0x78 2 1 None
MOV R1,#data 0x79 2 1 None
MOV R2,#data 0x7A 2 1 None
MOV R3,#data 0x7B 2 1 None
MOV R4,#data 0x7C 2 1 None
MOV R5,#data 0x7D 2 1 None
MOV R6,#data 0x7E 2 1 None
MOV R7,#data 0x7F 2 1 None
MOV R0,A 0xF8 1 1 None
MOV R1,A 0xF9 1 1 None
MOV R2,A 0xFA 1 1 None
MOV R3,A 0xFB 1 1 None
MOV R4,A 0xFC 1 1 None
MOV R5,A 0xFD 1 1 None
MOV R6,A 0xFE 1 1 None
MOV R7,A 0xFF 1 1 None
MOV R0,iram addr 0xA8 2 2 None
MOV R1,iram addr 0xA9 2 2 None
MOV R2,iram addr 0xAA 2 2 None
MOV R3,iram addr 0xAB 2 2 None
MOV R4,iram addr 0xAC 2 2 None
MOV R5,iram addr 0xAD 2 2 None
MOV R6,iram addr 0xAE 2 2 None
MOV R7,iram addr 0xAF 2 2 None
MOV bit addr,C 0x92 2 2 None
MOV iram addr,#data 0x75 3 2 None
MOV iram addr,@R0 0x86 2 2 None
MOV iram addr,@R1 0x87 2 2 None
MOV iram addr,R0 0x88 2 2 None
MOV iram addr,R1 0x89 2 2 None
MOV iram addr,R2 0x8A 2 2 None
MOV iram addr,R3 0x8B 2 2 None
MOV iram addr,R4 0x8C 2 2 None
MOV iram addr,R5 0x8D 2 2 None
MOV iram addr,R6 0x8E 2 2 None
MOV iram addr,R7 0x8F 2 2 None
MOV iram addr,A 0xF5 2 1 None
MOV iram addr,iram addr 0x85 3 2 None
144
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

4-8. PROBLEMS

1) Write a template file, which may be used to generate any assembly


program, using A51 macro assembler.

2) Explain all the interrupts, which are supported by the 8051


microcontrollers, giving a brief description of each .

3) Explain the term "Vectored Interrupts", give an example of its use and
describe how the 8051 microcontrollers obtains the address of an
interrupt vector in relation to its Type number.

4) For an 8051 microcontroller, describe the sequence of events which


occur following an interrupt up to the point when normal operation is
resumed.

145
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4

146
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

Chapter 5: PIC Instructions &Assembly Language

The PIC instruction set is the set of instructions that a PIC


microcontroller supports. These instructions are written into the program
Flash memory and executed by the microcontroller on startup.

Although there are many models of PIC microcontrollers, the nice thing
is that they are upward compatible with each other and a program
developed for one model can very easily, in many cases with no
modifications, be run on other models of the family. The basic assembler
instruction set of PIC microcontrollers consists of only 33 instructions
and most of the family members (except the newly developed devices)
use the same instruction set. A program developed for one model can run
on another model with similar architecture without any changes.

Although there are several hundred models of PIC microcontrollers, the


family can be broken down into three main groups, which are:
12-bit instruction word (e.g., 12C5XX, 16C5X)
Instruction set consists of only 33 instructions.
14-bit instruction word (e.g., 16F8X, 16F87X)
The instruction set consists of 35 instructions.
16-bit instruction word (e.g., 17C7XX, 18C2XX)
The 16-bit microcontrollers are at the high end of the PIC
microcontroller family. The devices in this group have 23 instructions
in addition to the 35 instructions found on the 14-bit microcontrollers.

All three groups share the same RISC architecture and the same
instruction set, with a few additional instructions available for the 14-bit
models, and many more instructions available for the 16-bit models.
Instructions occupy only one word in memory, thus reducing the required
program memory. Instructions and data are transferred on separate buses,
so the overall system performance is improved.

5-1. PIC Instruction Format


It is interesting to take a little time here to understand further the way the
instruction code is made up of. Most instructions take a single program
memory word (16 bits), but there are three instructions that require two
program memory locations. Each single-word instruction is a 16-bit word
divided into an opcode, which specifies the instruction type and one or
more operands, which specify the operation of the instruction.
147
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

The PIC 16 Series has four possible instruction word formats, as shown
in figure 5-1.
• Byte-oriented operations
• Bit-oriented operations
• Literal operations
• Control operations

The instruction word, which is transferred down the program bus, is made
up of 14 bits. These appear as bits 0 to 13 in the figure. The opcode, the
actual instruction part of the instruction word, always occupies the
highest bits of the instruction word.

.
Fig. 5-1. Formats of the PIC Mid-Range Microcontrollers
148
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

Most byte-oriented instructions have three operands:


1. The file register (specified by ‗f‘)
2. The destination of the result (specified by ‗d‘)
3. The accessed memory (specified by ‗a‘)

The file register designator ‗f‘ specifies which file register is to be used
by the instruction. The destination designator ‗d‘ specifies where the
result of the operation is to be placed. If ‗d‘ is zero, the result is placed in
the WREG register. If ‗d‘ is one, the result is placed in the file register
specified in the instruction.

All bit-oriented instructions have three operands:


1. The file register (specified by ‗f‘)
2. The bit in the file register (specified by ‗b‘)
3. The accessed memory (specified by ‗a‘)

The bit field designator ‗b‘ selects the number of the bit affected by the
operation, while the file register designator ‗f‘ represents the number of
the file in which the bit is located.

The literal instructions may use some of the following operands:


• A literal value to be loaded into a file register (specified by ‗k‘)
• The desired FSR register to load the literal value into (specified by ‗f‘)
• No operand required (specified by ‗—‘)
The control instructions may use some of the following operands:
• A program memory address (specified by ‗n‘)
• The mode of the CALL or RETURN instructions (specified by ‗s‘)
• The mode of the table read and write instructions (specified by ‗m‘)
• No operand required (specified by ‗—‘)
This is the part of the instruction word that ends up in the ―Instruction
Decode and Control‖ unit, but it is not always the same length. If the
instruction is the type that contains a file address, then it is of the first
format shown. The most significant 6 bits hold the opcode, while the least
significant 7 bits are used to hold the address. These bits are transferred
onto the Direct Address bus. In fact, because the PIC only has a small
memory, only the least significant 5 bits are used, as can be seen from the
Direct Address bus size indicated. Bit 7 holds the d bit. Different
instruction word patterns are used for the other instruction categories.

It should be noted that PIC instructions are little-endian. Since PIC data
memory is 8-bits wide and is only accessed in bytes, endianness is not
relevant
149
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

5-2. PIC Instruction Set (By Category)


The PIC instructions are highly orthogonal. They are usually programmed
into the Flash memory of the processor, and automatically executed by
the microcontroller on startup.

The instruction set and may be grouped into the functional groups, shown
in the following figure:

Fig. 5-2. Instruction set of PIC mid-range Microcontrollers, with examples.

150
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

5-3. PIC Instruction Set (Alphabetic)


The PIC18 instruction set adds many enhancements to the previous PIC
instruction sets, while maintaining an easy migration from these PIC
instruction sets.

Table 5-1. PIC instruction set (alphabetic oeder)

151
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

Table 5-1 (Cont.). PIC instruction set (alphabetic oeder)

152
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

5-4. PIC Addressing Modes


The 16-bit MCU devices support three native addressing modes for
accessing data memory, along with several forms of immediate
addressing. Data access may be performed using file register addressing,
register direct or indirect addressing, and immediate addressing, allowing
a fixed value to be used by the instruction. The data memory address
range accessed by each addressing mode is summarized below:

Fig. 5-3. Addressing modes of the PIC Microcontrollers

Fig. 5-4. Formats of the PIC Mid-Range Microcontrollers

5-4.1. File Register (or Memory Direct) Addressing


File Register (or Memory Direct) addressing provides the ability to
operate on data stored in the lower 8k bytes of data memory ("NEAR"
RAM). Instructions use a predetermined address as an operand. The
majority of instructions that use file register addressing provide
byte/word access to the lower 8k bytes data memory, with the exception
of the MOV instruction which provides word access to all 64k bytes.

153
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

This allows the loading of the data from any location in data memory to
any working register (W0:W15), and storing the contents of any working
register to any location in data memory. Examples of File Register
addressing are shown below:

5-4.2- Register Direct Addressing


Register direct addressing is used to access the contents of the 16 working
registers (W0:W15). Any working register may be used for any
instruction that supports this addressing mode. Instructions using this
addressing mode use the contents of the specified working register as
operands for the operation to be performed. This addressing mode
supports both byte and word access. Sample instructions which utilize
register direct addressing are shown below:

Fig. 5-5. Formats of the PIC Mid-Range Microcontrollers

154
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

5-4.3-Register Indirect Addressing


Register Indirect addressing is used to indirectly access any location in
data memory by treating the contents of a working register as an Effective
Address (EA) to data memory. Essentially, the contents of the working
register become a pointer to the location in data memory which is to be
accessed by the instruction. Additionally, the contents of the working
register may be modified pre or post operation, providing an efficient
mechanism for processing data stored sequentially in memory. The
following examples illustrate indirect addressing with pre/post
increment/decrement modification

155
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

5-5. Stack Operations


The 16-bit MCU and DSC devices feature a software stack which
facilitates function calls and exception handling. W15 is the default Stack
Pointer (SP). After any Reset, it is initialized to 0x0800 (0x1000 for
PIC24E and dsPIC33E devices). This ensures that the SP will point to
valid RAM and permits stack availability for exceptions, which may
occur before the SP is set by the user software. The user may reprogram
the SP during initialization to any location within data space. The SP
always points to the first available free word (Top-of-Stack) and fills the
software stack, working from lower addresses towards higher addresses.
It pre-decrements for a stack POP(read) and post-increments for a stack
PUSH (write).

The software stack is manipulated using the PUSH and POP instructions.
The PUSH and POPinstructions are the equivalent of a MOV instruction,
with W15 used as the destination pointer.

156
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

5-6. PIC Development Tools


The PIC manufacturers supply computer software for development
known as MPLAB, assemblers and C/C++ compilers, and
programmer/debugger hardware.

Fig. 5-6. Formats of the PIC Mid-Range Microcontrollers

As we mentioned earlier, the microcontroller assembler is a program that


allows you to write the microcontroller instructions in symbolic form,
which is much easier to read and understand, and then it converts
microcontroller instructions into binary or hex numbers. You use an
assembler with the object in mind of generating a file to download to the
microcontroller.
• MPLAB IDE, free Integrated Development Environment
• MPLAB SIM, software simulator
• MPLAB C30, C compiler (free Student Version).

157
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

While several commercial compilers are available, in 2008, Microchip


released their own C compilers, C18 and C30, for the line of 18F 24F and
30/33F processors.

As of 2013, Microchip offers their XC series of compilers, for use with


MPLAB. Microchip will eventually phase out its older compilers, such as
C18, and recommends using their XC series compilers for new designs.

Several third parties develop C language compilers for PICs, many of


which integrate to MPLAB or have their own IDE. A fully featured
compiler for the PIC-BASIC language to program PIC microcontrollers is
available from meLabs, Inc. Mikroelektronika offers PIC compilers in C,
Basic and Pascal programming languages.

5-6.1 PIC Assembler


You are now beginning to see how complex even a simple assembler
program can become. We need every means possible of keeping the
program as short and understandable as possible. A few options are now
described.

i. Assembler directives
Assembler directives are commands inserted in PIC source code that
control the operation of the assembler. They are not part of the program
itself and are not converted into machine code. Many assembler directives
will only be used when a good knowledge of the programming language
has been achieved, so we will refer to a small number of selected
examples at this stage. The use of some of these is illustrated in Program
6.5, ASD1. The assembler directives are placed in the second column,
with the instruction mnemonics. We have already met some of the most
commonly used directives, but END is the only one

1 Page
Forces a page break when printing.
2. Title
Defines the program name printed in the list fi le header line, if you want
it to be different from the source code fi le name.
3. Equ
EQU is probably the second most commonly used directive, because it
allows literal and register labels to be defi ned, and we have already used
it routinely. It assigns a label to any numerical value (hex, binary, decimal
or ASCII), and the assembler then replaces the label with the number.
This allows recognizable labels to be used instead of numbers
158
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

4. Include
This directs the assembler to include a block of source code from a named
fi le on disk. If necessary, the full file path must be given. The text fi le is
included as though it had been typed into the source code editor, so it
must conform to the usual assembler syntax, but any program block,
subroutine or macro could be included in source code files to be
included, and opens the way for the user to create libraries of reusable
program modules. Use of this option is recommended when the basics
have been mastered. The standard header files, which use labeling which
is consistent with the SFR labels are supplied with the development
system files for all processors.
5. Org
Sets the code ―origin,‖ meaning the address which will be allocated to the
fi rst instruction following this directive. We have already seen (Program
6.2) how it is necessary to set the origin of the interrupt service routine as
004. The default origin is 000, the first program
6. Config
The config directive allows the configuration bits to be specified in the
source code, so that they do not have to be set up each time when
downloading.
7. End
Informs the assembler that the end of the source code has been reached.
This is the one directive that must be present.
8. Data, Zero, Set, Res
Allow program constants and data blocks to be defined and memory
allocated for specified purposes.
9. Macro. . . . Endm
A macro is a block of source code that is inserted into the program when
its name is used as an instruction. In ASD1, for example, DELAY is the
name of the macro, and its insertion in the main program can be seen in
the list fi le. Thus using a macro is equivalent to creating a new
instruction from standard instructions, or an automatic copy and paste
operation. The directive MACRO defines the start of the block (with a
label), ENDM terminates it. It effectively allows you to create your own
instruction mnemonics (see also LOCAL and EXITM).

ii. Numerical Types


Literal values given in PIC source code can be written using different
number systems. The default is hexadecimal, so if the type is not
specified, the assembler will assume it is hex. However, it is very
159
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

important to note that the assembler will still get confused between
numbers and labels if the hex number starts with a letter (i.e., A, B, C, D,
E, or F). The literal must start with a number, so use a leading zero at all
times. Then 8-bit literals will be written as three digits, with the first
always zero (000–0FF). The numerical types supported by the PIC
assembler MPASM are:

• hexadecimal
• decimal
• binary
• octal
• ASCII

To specify a type, the initial letter of the type can be used with quotes,
such as:
H‘3F‘
D‘47‘
B‘10010011‘
A‘K‘

iii. Dealing with Data


We have seen that it is easy to move single bytes of data to or from data
memory, whether the memory is SFRs or memory locations dedicated to
holding particular variables. We did this in the most recent program
example, with the instructions:

movlw D'100'
movwf delcntr2

In using these instructions, we specify the actual address of the memory


location required. In this example, delcntr2 is a label clearly specifying
an address

We now introduce our first PIC assembly program. It is a simple data


moving program. The program example lights an LED if the associated
micro-switch is pressed. Even this simple task requires some thought,
however. As the port input goes low when the button is pressed, the
program needs to set the output bit (to light the LED) if the input is low
and clear it if it is high. This implies a selection process—in a high-level
language we might call this an if. . .else structure. The simple skip
instruction is not able to do this on its own. One way to do this is to
preset the output bit with one value and then change it if we fi nd it has
been set wrong.
;The “main” program starts here
160
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

movlw 00 ;clear all bits in port A and B


movwf porta
movwf portb
loop bcf portb, 3 ;preclear port B, bit 3
btfss porta, 3
bsf portb, 3 ;but set it if button pressed
;
bcf portb, 4 ;preclear port B, bit 4
btfss porta, 4
bsf portb, 4 ;but set it if button pressed
goto loop
end

iv. Subroutines
The subroutine is a program section structured in such a way that it can
be called from. At some point in the main program there may be an
instruction Call SR1. Program execution then switches to Subroutine1,
identified by its label. The subroutine must be terminated with a ―return
from subroutine‖ instruction. Program execution then continues from the
instruction after the Call instruction anywhere in the program. A
subroutine called from within another subroutine is called a nested
subroutine. In doing this, it must be remembered that every time a
subroutine is called one Stack location is taken up, which becomes free
again on the subroutine return. If we call a subroutine from within
another, then two Stack locations are used up, or three if there is another
nested call

Fig. 5-7. Calling a subroutine


161
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

A simple example of a delay subroutine is shown below.

;Delay of 5ms approx. Instruction cycle time is 5us.


delay5 movlw D'200' ;200 cycles called,each taking
5x5=25us
movwf delcntr1
del1 nop ;1 inst. cycle
nop ;1 inst. cycle
decfsz delcntr1,1 ;1 inst. cycle, when no skip
goto del1 ;2 inst. cycles
return

The subroutine opens by moving a number into the memory location


delcntr1. In this case the number is 200D, although this can be varied to
produce delays of different lengths. The time duration of this delay
subroutine can be worked out with ease, by considering the time taken by
each instruction in the loop. The subroutine opens by moving a number
into the memory location delcntr1. In this case the number is 200D,
although this can be varied to produce delays of different lengths

v. Macros
We are finding in every program we see that program development for a
RISC processor is laborious, due to the limited function of each
individual instruction. A CISC instruction set, with its somewhat more
powerful instructions, offers some modest advantage. Is there a way we
can get around the minimalist nature of the instruction set while
remaining in the assembler environment? One answer to this problem is
by the use of macros. A macro is a grouping of instructions, defined by
the programmer and given a name. Once defined, the macro can be used
in the program at any time. In some ways a macro offers the convenience
of a subroutine, but it is used differently. When the source code is
assembled, the macro is expanded out into the original instructions that
made it up. Therefore, using macros is a form of shorthand in
programming rather than a way of structuring the program. The macro
itself is contained within the directives macro and endm. The macro
movlf moves a data constant into a memory location. It applies two
arguments, const and address.

;macro to move a literal value to a fi le


movlf macro const,address
movlw const
movwf address
endm

162
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

v. Interrupt handling
When writing interrupt handlers in PIC assembler, there are constraints
(e.g. cannot access arrays using calculated index, call other functions and
access ROM variables etc). These must be followed for correct operation.
If the interrupt priority scheme is not used only one handler is required;
two are required if the priority scheme is used. The interrupt handlers
must be installed by putting a GOTO instruction at the vector location.
Typically this is done with a short section of inline assembler within the
C application. If the priority scheme is used, two vectors are required.
The examples below show definition of vector tables and handlers.

; include standard device header file


#include p18f452.inc

; the following code will be located at 0x0000 - reset vector


org 0x0000
goto Main ; jump to main entry point

; the following code will be located at 0x00088 – high-priority


interrupt vector
org 0x0008
goto int_hi ; jump to handler

; the following code will be located at 0x0018 – low-priority


interrupt vector
org 0x0018
goto int_lo ; jump to handler

Main
; write your main program here.
;
int_hi
;
write your high-priority interrupt service routine here
;
retfie ;use retfie to return
int_lo
;
write your low-priority interrupt service routine here.
;
retfie ;use retfie to return
end

5-6.2. PIC Assembly Program Template (for PIC12Fxxx)


With all the features and limitations of PIC assembly programs, we
present a template example of such programs. The template is dedicated
for PIC23Fxxx, but can be used with other compatible microcontrollers.
A good practice is to clear any control fi le registers that you are not
using. The only exception to this is the comparator module, which is in a
low-power mode if the CMCON (comparator module control) register is
clear, but is turned completely off if you set bits 0–2, as shown in the
template below. Even if you are going to use interrupts in the program,
163
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

you should not set the global interrupt enable until everything else is
confi gured. You can then use the ret-file instruction to leave Init and
enable global interrupts. If you don‘t want to enable interrupts at this
point, end Init with the return instruction. If you are not using interrupts,
you can remove the ISR.
;*************************************
; Written by: ..
; Date:
; Version: ...
; Dedicated for PIC ..
;*************************************
; Program Description:
;
list P=12F675
include “c:\pic\p12f675.inc”
;
;Declarations:
W_temp equ 20 h
STATUS_temp equ 21 h
org 0 ; fi rst instruction to be executed
goto Start ;
org 4 ; interrupt service routine
goto isr ;
;
;Subroutines:
Init bsf STATUS, RP0 ; goes to Bank 1
call 3FFh ; calls calibration address
movwf OSCCAL ; moves w. reg into OSCCAL
movlw b’xxxxxx’ ; sets up which pins are inputs
movwf TRISIO ; and which are outputs
movlw b’xxxxxx’ ; sets up which pins have
movwf WPU ; weak pull-ups enabled
movlw b’xxxxxxxx’ ; sets up timer and some pin
movwf OPTION_REG ; settings
clrf PIE1 ; turns off peripheral ints
clrf IOC ; disables GPIO change int.
clrf VRCON ; turns off comparator V. ref.
clrf ANSEL ; makes GP0:3 digital I/O pins
bcf STATUS, RP0 ; back to Bank 0
clrf GPIO ; resets input/output port
movlw b’00000111’ ; turns off comparator
movwf CMCON ;
clrf T1CON ; turns off TMR1
clrf ADCON0 ; turns off A to D conv.
movlw b’0xxxxxxx’ ; sets up interrupts
movwf INTCON ;
retfi e or return ;
isr movwf W_temp ; stores w. reg in temp register
movfw STATUS ; stores STATUS in temporary
movwf STATUS_temp ; register
(Write the interrupt service routine here)
movfw STATUS_temp ; restores STATUS register to
movwf STATUS ; original value
swapf W_temp, f ; restores working register to
swapf W_temp, w ; original value
retfi e or ; returns, enabling GIE
return;
;
164
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

; Program Start
Start call Init ; initialization routine
Main (Write your program here)
END

5-6.3. In-circuit Debugging & Emulation


All newer PIC devices feature an ICD (in-circuit debugging) interface,
built into the CPU core, that allows for interactive debugging of the
program in conjunction with MPLAB IDE. MPLAB ICD and MPLAB
REAL ICE debuggers can communicate with this interface using the
ICSP interface. Microchip offers three full in-circuit emulators: the
MPLAB ICE2000 (parallel interface, a USB converter is available); the
newer MPLAB ICE4000 (USB 2.0 connection); and most recently, the
REAL ICE (USB 2.0 connection). All such tools are typically used in
conjunction with MPLAB IDE for source-level interactive debugging of
code running on the target.

165
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

5-7. Summary

In this Chapter the basic rules of assembler programming were


introduced, along with some of the instructions from the PIC 16
Series instruction set
The assembly language of a specific microcontroller is composed of the
set of instructions which are specific to this microcontroller. In this
chapter we‘ll present the main features of the PIC microcontroller
assembly language and how it can be used to write application programs
for PIC16-based systems.

There are several variations of the PIC instruction set. Older devices (not
considered here) support 12-bit and 14-bit instruction sets. The PIC18
series support 16-bit instructions and is backwards compatible with
PIC16. Although instructions are 16-bits, the ALU and memory
interfaces are still 8-bit so these are regarded as 8-bit devices. The basic
PIC18F instruction set contains 77 instructions. Each PIC instruction
takes four clock periods to execute (instruction cycle time). Jumps take
two instruction cycles.

All PIC microcontrollers handle (and address) data in 8-bit chunks.


However, the unit of addressability of the code space is not generally the
same as the data space. For example, PICs in the baseline (PIC12) and
mid-range (PIC16) families have program memory addressable in the
same word-size as the instruction width, i.e. 12 or 14 bits respectively. In
contrast, in the PIC18 series, the program memory is addressed in 8-bit
increments (bytes), which is different from the instruction width of 16
bits. In order to be clear, the program memory capacity is usually stated
166
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

in number of (single-word) instructions, rather than in bytes.

PICs have a hardware call stack, which is used to save return addresses.
The hardware stack is not software-accessible on earlier devices, but this
changed with the 18 series devices.

Hardware support for a general-purpose parameter stack was lacking in


early series, but this greatly improved in the 18 series, making the 18
series architecture suitable to high-level language compilers.

PIC's instructions vary from about 33 instructions for the low-end PICs to
over 77 instructions for the high-end PICs. The instruction set includes
instructions to perform a variety of operations on registers directly, the
accumulator and a literal constant or the accumulator and a register, as
well as for conditional execution, and program branching.

In general, PIC instructions fall into 4 classes

• Byte-oriented operations
• Bit-oriented operations
• Literal operations
• Control operations

167
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5

5-8. Problems

5-1) Open a new project in MPLab under the suggested name Bit_Set.
Copy Program Example 1 (in page 161) into it as source file. Build the
project and simulate. With the Stimulus Controller create inputs signals
for Port A, pins 3 and 4, selecting Toggle for Action. Open a Watch
window with PCL, PORTA, PORTB and W register as observed
variables. Step through the program, ―fi ring‖ the inputs at appropriate
moments, noting the effect. Change the program so that:

(1) Port B, bits 3 and 4 are set if the respective buttons are pressed
(2) Different bits in Port B are set when the buttons are pressed.

168
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Chapter 6: ARM Instructions &Assembly Language

The ARM instruction set is the set of instructions that ARM micro-
controller supports. The first thing to do when programming an
embedded system is to understand the instruction set of the target device.
All ARM instructions are 32 bits long. Actually, there are two instruction
sets that the ARM core can use: Regular ARM code with 32bit
instructions, and a subset of this called THUMB, which is 16bit long.
Naturally, the ARM set is more powerful, but the most used instructions
can be found in both. Here is a typical 32-bit ARM instruction:
10101011100101010010100111101011. Fortunately, we don't have to
write ARM programs using such codes. Instead we use assembly
language.

6-1. ARM Instruction Format


The general instruction format of ARM microprocessors and
microcontrollers takes the following shape:

Fig. 6-1. Basic format of ARM instructions


169
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

An instruction operand can be an ARM register, a constant, or another


instruction-specific parameter. Instructions act on the operands and often
store the result in a destination register. When there is a destination
register in the instruction, it is usually specified before the operands.
Operands in some instructions are flexible in that they can either be a
register or a constant. Many general data processing instructions have a
flexible second operand. This is shown as Operand2 in the descriptions of
the syntax of each instruction.

Actually, the ARM has many possible instruction word formats, as shown
in figure 6-2.

Fig. 6-2. Formats of the ARM instruction format

For the matter of demonstration, the following figure illustrates the


encoding format of the ARM's load and store instructions. Memory
access operations have a conditional execution field in bit 31, 03, 29, and
28. The load and store instructions can be conditionally executed
depending on a condition specified in the instruction. Now look at the
following examples:

170
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

CMP R1, R2
LDREQ R3, [R4]
LDRNE R3, [R5]

Fig.6-3. Encoding ARM load/store instructions

171
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

6-2. ARM Instruction Set


The original (and subsequent) ARM implementation was hardwired
without microcode. The 32-bit ARM architecture (and most 64-bit
architecture) includes the following RISC features:

Fixed instruction width of 32 bits to ease decoding and pipelining,


Load/store architecture.
Mostly single clock-cycle execution.
ARMv6 and later, except some microcontroller versions, support
unaligned accesses for half-word and single-word instructions
Uniform 16×32-bit register file (including program counter, stack pointer
and link register).
Conditional execution of most instructions reduces branch overhead.
Arithmetic instructions alter condition codes only when desired.
32-bit barrel shifter can be used with most arithmetic instructions.
Powerful indexed addressing modes.
A link register supports fast leaf function calls.
Fast, 2-priority-level interrupt system with switched register banks.

All instructions can access r0-r14 directly. Most instructions also allow
use of the program counter (PC).

Modern ARM processors have several instruction sets:

The original 32-bit ARM instruction set,


The more restricted, but space efficient, 16-bit Thumb instruction set,
The newer mixed 16/32-bit Thumb-2 instruction set,
Jazelle DBX for Java byte codes,
The NEON 64/128-bit SIMD multimedia instruction set,
The vector floating point (VFP) instruction set..

6-2.1. ARM Instruction Set (Alphabetic)


The following table summarizes the ARM Cortex-M3 microcontrollers
instructions in alphabetic order. These microcontrollers implement a
version of the Thumb (16-bit) instruction set.

angle brackets, <>, enclose alternative forms of the operand


braces, {}, enclose optional operands
the Operands column is not exhaustive
Op2 is a flexible second operand that can be either a register or a constant
most instructions can use an optional condition code suffix

172
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Table 6-1. ARM Cortex-M3 instructions summary

Mnemonic Operands Description Flags

ADC, ADCS {Rd,} Rn, Op2 Add with Carry N,Z,C,V

ADD,
{Rd,} Rn, Op2 Add N,Z,C,V
ADDS

ADD,
{Rd,} Rn, #imm12 Add N,Z,C,V
ADDW

ADR Rd, label Load PC-relative Address -

AND,
{Rd,} Rn, Op2 Logical AND N,Z,C
ANDS

ASR, ASRS Rd, Rm, <Rs|#n> Arithmetic Shift Right N,Z,C

B label Branch -

BFC Rd, #lsb, #width Bit Field Clear -

BFI Rd, Rn, #lsb, width Bit Field Insert -

BIC, BICS {Rd,} Rn, Op2 Bit Clear N,Z,C

BKPT #imm Breakpoint -

BL label Branch with Link -

BLX Rm Branch indirect with Link -

BX Rm Branch indirect -

CBNZ Rn, label Compare and Branch if Non Zero -

CBZ Rn, label Compare and Branch if Zero -

CLREX - Clear Exclusive -

CLZ Rd, Rm Count Leading Zeros -

CMN Rn, Op2 Compare Negative N,Z,C,V

CMP Rn, Op2 Compare N,Z,C,V

173
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Mnemonic Operands Description Flags


Change Processor State, Disable
CPSID i Interrupts
-

Change Processor State, Enable


CPSIE i Interrupts
-

DMB - Data Memory Barrier -

DSB - Data Synchronization Barrier -

EOR, EORS {Rd,} Rn, Op2 Exclusive OR N,Z,C

ISB - Instruction Synchronizatio Barrier -

IT - If-Then condition block -

Load Multiple registers,


LDM Rn{!}, reglist increment after
-

LDMDB, Load Multiple registers,


Rn{!}, reglist decrement before
-
LDMEA

LDMFD, Load Multiple registers,


Rn{!}, reglist increment after
-
LDMIA

LDR Rt, [Rn, #offset] Load Register with word -

LDRB,
Rt, [Rn, #offset] Load Register with byte -
LDRBT

Rt, Rt2, [Rn,


LDRD Load Register with two bytes -
#offset]

LDREX Rt, [Rn, #offset] Load Register Exclusive -

Load Register Exclusive with


LDREXB Rt, [Rn] Byte
-

Load Register Exclusive with


LDREXH Rt, [Rn] Halfword
-

LDRH,
Rt, [Rn, #offset] Load Register with Halfword -
LDRHT

174
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Mnemonic Operands Description Flags

LDRSB,
Rt, [Rn, #offset] Load Register with Signed Byte -
LDRSBT

LDRSH, Load Register with Signed


Rt, [Rn, #offset] Halfword
-
LDRSHT

LDRT Rt, [Rn, #offset] Load Register with word -

LSL, LSLS Rd, Rm, <Rs|#n> Logical Shift Left N,Z,C

LSR, LSRS Rd, Rm, <Rs|#n> Logical Shift Right N,Z,C

Multiply with Accumulate, 32-bit


MLA Rd, Rn, Rm, Ra result
-

Multiply and Subtract, 32-bit


MLS Rd, Rn, Rm, Ra result
-

MOV,
Rd, Op2 Move N,Z,C
MOVS

MOVT Rd, #imm16 Move Top -

MOVW,
Rd, #imm16 Move 16-bit constant N,Z,C
MOV
Move from Special Register to
MRS Rd, spec_reg general register
-

Move from general register to


MSR spec_reg, Rm Special Register
N,Z,C,V

MUL,
{Rd,} Rn, Rm Multiply, 32-bit result N,Z
MULS

MVN,
Rd, Op2 Move NOT N,Z,C
MVNS

NOP - No Operation -

ORN, ORNS {Rd,} Rn, Op2 Logical OR NOT N,Z,C

ORR, ORRS {Rd,} Rn, Op2 Logical OR N,Z,C

POP reglist Pop registers from stack -

175
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Mnemonic Operands Description Flags

PUSH reglist Push registers onto stack -

RBIT Rd, Rn Reverse Bits -

REV Rd, Rn Reverse byte order in a word -

Reverse byte order in each


REV16 Rd, Rn halfword
-

Reverse byte order in bottom


REVSH Rd, Rn halfword and sign extend
-

ROR, RORS Rd, Rm, <Rs|#n> Rotate Right N,Z,C

RRX, RRXS Rd, Rm Rotate Right with Extend N,Z,C

RSB, RSBS {Rd,} Rn, Op2 Reverse Subtract N,Z,C,V

SBC, SBCS {Rd,} Rn, Op2 Subtract with Carry N,Z,C,V

Rd, Rn, #lsb,


SBFX Signed Bit Field Extract -
#width

SDIV {Rd,} Rn, Rm Signed Divide -

SEV - Send Event -

RdLo, RdHi, Rn, Signed Multiply with Accumulate


SMLAL (32 x 32 + 64), 64-bit result
-
Rm

RdLo, RdHi, Rn, Signed Multiply (32 x 32), 64-bit


SMULL result
-
Rm

Rd, #n, Rm {,shift


SSAT Signed Saturate Q
#s}
Store Multiple registers,
STM Rn{!}, reglist increment after
-

STMDB, Store Multiple registers,


Rn{!}, reglist decrement before
-
STMEA

STMFD, Store Multiple registers,


Rn{!}, reglist increment after
-
STMIA

176
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Mnemonic Operands Description Flags

STR Rt, [Rn, #offset] Store Register word -

STRB,
Rt, [Rn, #offset] Store Register byte -
STRBT

Rt, Rt2, [Rn,


STRD Store Register two words -
#offset]

STREX Rd, Rt, [Rn, #offset] Store Register Exclusive -

STREXB Rd, Rt, [Rn] Store Register Exclusive Byte -

Store Register Exclusive


STREXH Rd, Rt, [Rn] Halfword
-

STRH,
Rt, [Rn, #offset] Store Register Halfword -
STRHT

STRT Rt, [Rn, #offset] Store Register word -

SUB, SUBS {Rd,} Rn, Op2 Subtract N,Z,C,V

SUB,
{Rd,} Rn, #imm12 Subtract N,Z,C,V
SUBW

SVC #imm Supervisor Call -

{Rd,} Rm {,ROR
SXTB Sign extend a byte -
#n}

{Rd,} Rm {,ROR
SXTH Sign extend a halfword -
#n}

TBB [Rn, Rm] Table Branch Byte -

TBH [Rn, Rm, LSL #1] Table Branch Halfword -

TEQ Rn, Op2 Test Equivalence N,Z,C

TST Rn, Op2 Test N,Z,C

Rd, Rn, #lsb,


UBFX Unsigned Bit Field Extract -
#width

177
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Mnemonic Operands Description Flags

UDIV {Rd,} Rn, Rm Unsigned Divide -

Unsigned Multiply with


RdLo, RdHi, Rn,
UMLAL Accumulate (32 x 32 + 64), 64-bit -
Rm result

RdLo, RdHi, Rn, Unsigned Multiply (32 x 32), 64-


UMULL bit result
-
Rm

Rd, #n, Rm {,shift


USAT Unsigned Saturate Q
#s}

{Rd,} Rm {,ROR
UXTB Zero extend a Byte -
#n}

{Rd,} Rm {,ROR
UXTH Zero extend a Halfword -
#n}

WFE - Wait For Event -

WFI - Wait For Interrupt -

6-2.2. ARM Instruction Set (By Category)


As shown in the above table, the instructions supported by the Cortex-M3
processor, may be divided into the following basic groups.Nearly all
instructions are General data processing operations; including arithmetic
and bitfield instructions, memory access operations, load and store in
many guises and branches for jumping around code for loops. The speed
of instructions almost follows this scheme as well. Data instructions
usually happen in a cycle; memory ops uses two or three and branches
uses 3 or 4. The whole timing thing is actually a lot more complicated
than this, but it's a useful rule of thumb.

i. Memory access instructions


The following table shows the memory access instructions.

Table 6-2.

Mnemonic Brief description Example

ADR Generate PC-relative address ADR

178
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Mnemonic Brief description Example

CLREX Clear Exclusive CLREX

LDM{mode} Load Multiple registers LDM and STM

Load Register using LDR and STR,


LDR{type}
immediate offset immediate offset

Load Register using register LDR and STR, register


LDR{type}
offset offset

Load Register with LDR and STR,


LDR{type}T
unprivileged access unprivileged

Load Register using PC-


LDR LDR, PC-relative
relative address

LDREX{type} Load Register Exclusive LDREX and STREX

POP Pop registers from stack PUSH and POP

PUSH Push registers onto stack PUSH and POP

STM{mode} Store Multiple registers LDM and STM

Store Register using LDR and STR,


STR{type}
immediate offset immediate offset

Store Register using register LDR and STR, register


STR{type}
offset offset

Store Register with LDR and STR,


STR{type}T
unprivileged access unprivileged

STREX{type} Store Register Exclusive LDREX and STREX

ii. Arithmetic instructions


ARM includes integer arithmetic operations for add, subtract, and
multiply; some versions of the architecture also support divide operations.
ARM supports 32-bit x 32-bit multiplies with either a 32-bit result or 64-
bit result, though Cortex-M0 / M0+ / M1 cores don't support 64-bit
results. Some ARM cores also support 16-bit x 16-bit and 32-bit x 16-bit
multiplies. The divide instructions are only included in the following
ARM architectures:
179
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

ARMv7-M and ARMv7E-M architectures always include divide


instructions
ARMv7-R architecture always includes divide instructions in the
Thumb instruction set, but optionally in its 32-bit instruction set
ARMv7-A architecture optionally includes the divide instructions.

The instructions might not be implemented, or implemented only in the


Thumb instruction set, or implemented in both the Thumb and ARM
instruction sets, or implemented if the Virtualization Extensions are
included

iii. Multiply and divide instructions


The following table shows the Multiply and divide instructions

Table 6-3.

Mnemonic Brief description Example

Multiply with Accumulate, 32-bit


MLA MUL, MLA, and MLS
result

Multiply and Subtract, 32-bit


MLS MUL, MLA, and MLS
result

MUL Multiply, 32-bit result MUL, MLA, and MLS

SDIV Signed Divide SDIV and UDIV

Signed Multiply with Accumulate UMULL, UMLAL,


SMLAL
(32x32+64), 64-bit result SMULL, and SMLAL

Signed Multiply (32x32), 64-bit UMULL, UMLAL,


SMULL
result SMULL, and SMLAL

UDIV Unsigned Divide SDIV and UDIV

Unsigned Multiply with


UMULL, UMLAL,
UMLAL Accumulate (32x32+64), 64-bit
SMULL, and SMLAL
result

Unsigned Multiply (32x32), 64-bit UMULL, UMLAL,


UMULL
result SMULL, and SMLAL

180
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

iv. Shift & Rotate Operations


Register shift operations move the bits in a register left or right by a
specified number of bits, the shift length. Register shift can be performed:
directly by the instructions ASR, LSR, LSL, ROR, and RRX, and the
result is written to a destination register during the calculation of
Operand2 by the instructions that specify the second operand as a register
with shift. The result is used by the instruction. The permitted shift
lengths depend on the shift type and the instruction. Register shift
operations update the carry flag except when the specified shift length is
0. A rotate is like a shift except that the bits shifted in to the left (right)
end are those which are coming out of the right (left) end.

Table 6-4.

Mnemonic Brief description Examples

ASR Arithmetic Shift Right ASR, LSL, LSR, ROR, RRX

LSL Logical Shift Left ASR, LSL, LSR, ROR, RRX

LSR Logical Shift Right ASR, LSL, LSR, ROR, RRX

ROR Rotate Right ASR, LSL, LSR, ROR, RRX

RRX Rotate Right with Extend ASR, LSL, LSR, ROR, RRX

Here are the explanation of shift and rotate operations:

LSL #n Logical shift left immediate

n is the number of bit positions by which the value is shifted. It has the
value 0..31. An LSL by one bit is shown below:

After n shifts, n zero bits have been shifted in on the right and the carry is
set to bit 32-n of the original word. Note that if there is no shift specified
after the LSL, LSLÊ#0 is used, which has no effect.

181
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

ASL #n Arithmetic shift left immediate

This is a synonym for LSL #n and has an identical effect.

LSR #n Logical shift right immediate

n is the number of bit positions by which the value is shifted. It has the
value 1..32. An LSR by one bit is shown below:

After n of these, n zero bits have been shifted in on the left, and the carry
flag is set to bit n-1 of the original word.

ASR #n Arithmetic shift right immediate

n is the number of bit positions by which the value is shifted. It has the
value 1..32. An ASR by one bit is shown below:

If ' sign' is the original value of bit 31 then after n shifts, n 'sign' bits have
been shifted in on the left, and the carry flag is set to bit n-1 of the
original word.
ROR #n Rotate right immediate

n is the number of bit positions to rotate in the range 1..31. A rotate right
by one bit is shown below:

182
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

After n of these rotates, the old bit n is in the bit 0 position; the old bit (n-
1) is in bit 31 and in the carry flag. Note that a rotate left by n positions is
the same as a rotate right by (32-n). Also note that there is no rotate right
by 32 bits. The instruction code which would do this has been reserved
for rotate right with extend.

RRX Rotate right one bit with extend

This special case of rotate right has a slightly different effect from the
usual rotates. There is no count; it always rotates by one bit only. The
pictorial representation of RRX is is shown below. The old bit 0 is shifted
into the carry. The old content of the carry is shifted into bit 31.

v. Bitfield instructions
The following table shows the instructions that operate on adjacent sets of
bits in registers or bitfields.

Table 6-5.

Mnemonic Brief description Example

BFC Bit Field Clear BFC and BFI

BFI Bit Field Insert BFC and BFI

SBFX Signed Bit Field Extract SBFX and UBFX

SXTB Sign extend a byte SXT and UXT

SXTH Sign extend a halfword SXT and UXT

UBFX Unsigned Bit Field Extract SBFX and UBFX

UXTB Zero extend a byte SXT and UXT

UXTH Zero extend a halfword SXT and UXT

183
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

vi. General data processing instructions


This group contains the instructions which do most of the manipulation of
data in ARM programs. The following table shows the data processing
instructions.

Table 6-6
Mnemonic Brief description Examples

ADC Add with Carry ADD, ADC, SUB, SBC, and RSB

ADD Add ADD, ADC, SUB, SBC, and RSB

ADDW Add ADD, ADC, SUB, SBC, and RSB

AND Logical AND AND, ORR, EOR, BIC, ORN

BIC Bit Clear AND, ORR, EOR, BIC, ORN

CLZ Count leading zeros CLZ

CMN Compare Negative CMP and CMN

CMP Compare CMP and CMN

EOR Exclusive OR AND, ORR, EOR, BIC, ORN

MOV Move MOV and MVN

MOVT Move Top MOVT

MOVW Move 16-bit constant MOV and MVN

MVN Move NOT MOV and MVN

ORN Logical OR NOT AND, ORR, EOR, BIC, ORN

ORR Logical OR AND, ORR, EOR, BIC, ORN

RBIT Reverse Bits REV, REV16, REVSH, and RBIT

Reverse byte order in a


REV REV, REV16, REVSH, and RBIT
word

Reverse byte order in


REV16 REV, REV16, REVSH, and RBIT
each halfword

184
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Mnemonic Brief description Examples

Reverse byte order in


REVSH bottom halfword and REV, REV16, REVSH, and RBIT
sign extend

RSB Reverse Subtract ADD, ADC, SUB, SBC, and RSB

SBC Subtract with Carry ADD, ADC, SUB, SBC, and RSB

SUB Subtract ADD, ADC, SUB, SBC, and RSB

SUBW Subtract ADD, ADC, SUB, SBC, and RSB

TEQ Test Equivalence TST and TEQ

TST Test TST and TEQ

vii. Branch and Control instructions


The branch and control group provides the ability to locate any point in
the program with a single operation. The following table shows the
branch and control instructions. The basic instruction is a simple branch,
whose mnemonic is just B. The format of the instruction is:

B{cond} <expression>

Table 6-7.

Mnemonic Brief description Examples

B Branch B, BL, BX, and BLX

BL Branch with Link B, BL, BX, and BLX

BLX Branch indirect with Link B, BL, BX, and BLX

BX Branch indirect B, BL, BX, and BLX

CBNZ Compare and Branch if Non Zero CBZ and CBNZ

CBZ Compare and Branch if Zero CBZ and CBNZ

IT If-Then IT

185
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Mnemonic Brief description Examples

TBB Table Branch Byte TBB and TBH

TBH Table Branch Halfword TBB and TBH

viii. Conditional execution


On most processors, you can only use branches conditionally, but on
ARM systems you can attach the conditionals to all instructions. Most
data processing instructions can optionally update the condition flags in
the Application Program Status Register (APSR) according to the result
of the operation. Some instructions update all flags, and some only update
a subset. If a flag is not updated, the original value is preserved. See the
instruction descriptions for the flags they affect.

You can execute an instruction conditionally, based on the condition flags


set in another instruction, either:
immediately after the instruction that updated the flags
after intervening instructions that have not updated the flags.

Conditional execution is available by using conditional branches or by


adding condition code suffixes to instructions. The condition code suffix
enables the processor to test a condition based on the flags. If the
condition test of a conditional instruction fails, the instruction does not
execute. Conditional instructions, except for conditional branches, must
be inside If-Then instruction block. Use the CBZ and CBNZ instructions
to compare the value of a register against zero and branch on the result.

ix. Condition flags


The APSR register contains the following condition flags:
N: Set to 1 when the result of operation is negative, cleared to 0 otherwise.
Z: Set to 1 when the result of operation was zero, cleared to 0 otherwise.
C: Set to 1 when the operation resulted in a carry, cleared to 0 otherwise.
V: Set to 1 when the operation caused overflow, cleared to 0 otherwise.

A carry occurs:
if the result of an addition is greater than or equal to 232
if the result of a subtraction is positive or zero
result of inline barrel shifter operation in move or logic instruction.

Overflow occurs when the sign of the result, in bit31, does not match the
sign of the result had the operation been performed at infinite precision
186
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

x. Miscellaneous instructions
The following table shows the remaining Cortex-M3 instructions.

Table 6-8.

Mnemonic Brief description Example

BKPT Breakpoint BKPT

CPSID Change Processor State, Disable Interrupts CPS

CPSIE Change Processor State, Enable Interrupts CPS

DMB Data Memory Barrier DMB

DSB Data Synchronization Barrier DSB

ISB Instruction Synchronization Barrier ISB

MRS Move from special register to register MRS

MSR Move from register to special register MSR

NOP No Operation NOP

SEV Send Event SEV

SVC Supervisor Call SVC

WFE Wait For Event WFE

WFI Wait For Interrupt WFI

xi. DSP enhancement instructions


To improve the ARM architecture for digital signal processing and
multimedia applications, DSP instructions were added to the set. These
are signified by an "E" in the name of the ARMv5TE and ARMv5TEJ
architectures. E-variants also imply T, D, M and I. They include
variations on signed multiply, saturated add and subtract, and count
leading zeros

xii. Software Interrupts


In some ARM processors the SWI, instruction is used to call the
operating system routines. The SWI format has absolutely no variants or
options. The general form of SWI is:
187
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

SWI{cond} <expression>

SWI will perform tasks as disparate as displaying characters on the


screen, setting the auto-repeat speed of the keyboard and loading a file
from the hard disc. When a SWI is executed, the CPU enters supervisor
mode, saves the return address in R14_SVC, and jumps to location 8.
From here, the operating system takes over.

188
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

6-3. ARM Addressing Modes


The various addressing modes that are defined in a given instruction set
architecture define how assembly code in that architecture can identify
the operands of instructions. An addressing mode specifies how to
calculate the effective memory address of an operand by using
information held in registers and/or constants contained within a machine
instruction or elsewhere. There are different ways to specify the address
of the operands for any given operations such as load, add or branch. The
different ways of determining the address of the operands are called
addressing modes. The following table shows different addressing modes
of ARM processor and how all instructions fit into a single word (32
bits).
Table 6-9. ARM addressing modes, with examples.

Name Alternative Name ARM Examples


Immediate Literal MOV R0, #15
Register direct Register to register MOV R0, R1
Direct Absolute LDR R0, MEM
Register indirect Indexed, base LDR R0, [R1]
Register indirect, with Pre-indexed, base LDR R0, [R1, #4]
offset with displacement
Register indirect , pre Pre-indexed, auto- LDR R0, [R1, #4]!
incrementing indexing
Register indirect, post Post-indexing, LDR R0, [R1], #4
incrementing auto-indexing
Register indirect, Register Double Reg LDR R0, [R1, R2]
indexed indirect
Register indirect, indexed Double Reg LDR R0, [R1, r2,LSL]
with scale indirect with scale
Program counter relative LDR R0, [PC, #offset]

6-3.1. Immediate (Literal) Addressing


In Immediate Addressing, the Operand is part of instruction, such that
Operand is written in the address field. This immediate addressing mode
does not have an effective address, and sometimes, is not considered to be
an addressing mode. Examples of immediate addressing in ARM
instructions are shown below:
CMP R0, #22
ADD R1, R2, #18
MOV R1, #30
AND R0, R1, #0xFF000000
CMN R0, #6400 ; update the N, Z, C and V flags
CMPGT SP, R7, LSL #2 ; update the N, Z, C and V flags

189
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Fig. 6-4. Immediate addressing modes of ARM processors and Microcontrollers

6-3.2. Register Indirect Addressing


Register indirect addressing means that the location of an operand is held
in a register. It is also called indexed addressing or base addressing.
Register indirect addressing mode requires three read operations to access
an operand. It is very important because the content of the register
containing the pointer to the operand can be modified at runtime.
 Read the instruction to find the pointer register
 Read the pointer register to find the oprand address
 Read memory at the operand address to find the operand
Some examples of using register indirect addressing mode:
Instruction Comment
LDR R2, [R0] ; Load R2 with the word pointed by R0
STR R2, [R3] ; Store the word in R2 in the location pointed by R3

6-3.3. Indirect Addressing with an Offset


ARM supports a memory-addressing mode where the effective address of
an operand is computed by adding the content of a register and a literal
offset coded into load/store instruction. For example,

Instruction Effective Address Comment


LDR R0, [R1, #20] R1 + 20 ; loads R0 with the word
pointed at by R1+20

6-3.4. Auto-indexing Pre-indexed Addressing


This is used to facilitate the reading of sequential data such as arrays,
tables, and vectors. A pointer register is used to hold the base address. An
offset can be added to achieve the effective address. For example,

Instruction Effective Address Comment


LDR R0, [R1, #4]! R1 + 4 ; loads R0 with the word pointed at
by R1+4 then update the pointer by
adding 4 to R1
190
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

6-3.5. Auto-indexing Post-indexing Addressing Mode


This is similar to the above, but it first accesses the operand at the
location pointed by the base register, then increments the base register.
For example,

Instruction Effective Address Comment


LDR R0, [R1], #4 R1 ; loads R0 with the word pointed
at by R1 then update the pointer
by adding 4 to R1

Note that in pre-indexed address –the address generated is used


immediately, as follows:
o [Rn, <expression>]{!}
o [Rn, {-}Rm]{!}
o [Rn, {-}Rm <shift> count]{!}
In post-indexed address the address generated later replaces the base
register, as follows:
o [Rn], <expression>
o [Rn], {-}Rm
o [Rn], {-}Rm <shift> count
Examples
LDR r0,[r1,#4] ; Load word addressed by R1+4.
STR r0,[r1],#4 ; Store R0 to word addressed by R1. Increment R1 by 4.
LDR r0,[r1,#4]! ; Load word addressed by R1+4. Increment R1 by 4.
LDRLS pc,[r1,r0,LSL #2] ; Jump table idiom: load routine address into
PC from R1 + R0 * 4.

6-3.6. Program Counter Relative (PC Relative) Addressing Mode


Many instructions have restrictions on whether you can use the Program
Counter (PC) or Stack Pointer (SP) for the operands or destination
register.
Register R15 is the program counter (PC). If you use R15 as a pointer
register to access operand, the resulting addressing mode is called PC
relative addressing. The operand is specified with respect to the current
code location. Please look at this example,
Instruction Effective Address Comment
LDR R0, [R15, #24] R15 + 24 ; loads R0 with the word
pointed at by R1+24

Bit[0] of any address you write to the PC with a BX, BLX, LDM, LDR,
or POP instruction must be 1 for correct execution, because this bit
191
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

indicates the required instruction set, and the Cortex-M3 processor only
supports Thumb instructions.

6-3.7. Stack Operations


Traditionally, a stack grows down in memory, with the last “pushed”
value at the lowest address. The ARM also supports ascending stacks,
where the stack structure grows up through memory. The value of the
stack pointer can either:
• Point to the last occupied address (Full stack) and so needs pre-
decrementing (before the push)
• Point to the next occupied address (Empty stack) and so needs post-
decrementing (after the push)
The stack type to be used is given by the postfix to the instruction:
• STMFD / LDMFD : Full Descending stack
• STMFA / LDMFA : Full Ascending stack.
• STMED / LDMED : Empty Descending stack
• STMEA / LDMEA : Empty Ascending stack

Fig. 6-5. Examples of the ARM stack operations

192
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

6-4. ARM Development Tools


The ARM manufacturers supply computer software for development,
assemblers and C/C++ compilers, and programmer/debugger hardware.

The Cortex-M3 is well supported by a wide range of tools from many


suppliers. In particular, the RealView Developer Suite (RVDS) and Keil
Microcontroller Developer Kit (MDK) from ARM provide full support

6-4.1. ARM Integrated Development Environments (IDE’s)


The μVision IDE from Keil combines project management, make
facilities, source code editing, program debugging, and complete
simulation in one powerful environment.

i. Keil MDK - ARM


Keil MDK-ARM is a complete software development environment for all
ARM processor-based microcontrollers. MDK-ARM is easy to learn and
use, yet powerful enough for the most demanding embedded applications.

Fig. 6-6. Snapshot of ARM MDK

193
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

ii. ARM DS-5 Development Studio


ARM DS-5 is a flexible and powerful suite of software development tools
for ARM application processors and System-on-Chip (SoC) devices. The
supported devices include Cortex-A, Cortex-R, Cortex-M, ARM11, RM9
and ARM7

The ARM Development Studio 5 (DS-5) Community Edition is a free


professional quality tool chain developed by ARM to accelerate the
development of native (C/C++) embedded Linux and Android
applications. Based on DS-5 Ultimate Edition, this toolkit offers essential
debug and system analysis for you to create robust and highly optimized
applications for ARM processor-based devices. ARM DS-5 Development
Studio includes ARM Compiler and Linaro GCC.. It incorporates a
highly optimizing C/C++ compiler, assembler, linker and libraries for
bare-metal software development

194
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

6-4.2. ARM Assembly Language


To program an ARM-based microcontroller in assembly, you need to
know how the core processor actually works and write in a way it can
understand. A complete document on assembly is nothing but a full
user's manual for a CPU. This would require an entire book in itself,
which is not the intention of this book. My intention here is to give an
introduction to ARM assembly. We explain the most important
instructions of the ARM instruction sets, what you can and cannot do
with them. We also cover how to use ARM assemblers to assemble the
code and how to make your assembly and C files work together.

Writing programs using ARM machine code is possible but not practical.
Instead, we write programs using ARM assembly language.

Instructions are expressed using mnemonics, e.g. the word “ADD”


instead of the machine code 0xE08. Assembly language must still be
translated into machine code. This is done an assembler For instance,
consider the following assembly program

start
MOV total, a ; Make the first number the subtotal
ADD total, total, b ; Add the second number to the subtotal
ADD total, total, c ; Add the third number to the subtotal
ADD total, total, d ; Add the fourth number to the subtotal
stop B ; stop

The corresponding machine code, which can be generated by an ARM


assembler, is as follows:

1 00000000 AREA Demo, CODE, READONLY


2 00000000 IMPORT main
3 00000000 EXPORT start
4 00000000
5 00000000 start
6 00000000 E1A00001 MOV r0, r1
7 00000004 E0800002 ADD r0, r0, r2
8 00000008 E0800003 ADD r0, r0, r3
9 0000000C E0800004 ADD r0, r0, r4
10 00000010
11 00000010 EAFFFFFE stop B stop
12 00000014
13 00000014 END

195
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Every ARM machine code instruction is 32-bits long . 32-bit instruction


word must encode operation (instruction) and all the required instruction
operands. Example the instruction: add r0, r0, r2 is encoded as follows:

or

Which can be written in hexadecimal as

i. ARM Toolchain Assembler Features


As we mentioned earlier, the microcontroller assembler is a program that
allows you to write the microcontroller instructions in symbolic form,
which is much easier to read and understand, and then it converts
microcontroller instructions into binary or hex numbers. You use an
assembler with the object in mind of generating a file to download to the
microcontroller. Even for a given processor, there can be differences in
how you write assembly. Assemblers aren't difficult to write, and there's
nothing to stop professionals from writing and improving different kinds
of assemblers.

The assembler of the GNU toolchains is known as the GNU assembler or


GAS.

ii. ARM Assembler Syntax


The instructions are only part of functional assembly, you also need
directives to tie code together, control sections and alignment, create data,
etc. Somewhat fittingly, directives seem to be as unportable as assembly
itself: directives for one assembler might not work under others.
Symbols
Data (variable and constant) and functions are collectively known as
symbols and, just like in C, these have declarations and definitions.

Labels
Any label (a valid identifier on a separate line ending with a colon) is
196
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

potentially a symbol definition, but it's better to distinguish between


global and local labels. Simply put, a label is global if there is a „.global
lname‟ directive attached to it that makes it visible to the outside world.
Local labels are everything else, and conventionally start with ‘.L’,
though this is not required. If you want to use symbols from outside, you
have to use ‘.extern lname’.

Alignment
A very important and sneaky issue is alignment. You are responsible for
aligning code and data, not the assembler. In C, the compiler did this for
you and the only times you might have had problems was with alignment
mismatches when casting, but here both code and data can be misaligned;
in assembly, the assembler just strings your code and data together as it
finds it, so as soon as you start using anything other than words you have
the possibility of misalignments.

Fortunately, alignment is very easy to do: „.align n‟ aligns to the next 2n


byte boundary and if you don't like the fact that n is a power here, you
can also use „.balign m‟, which aligns to m bytes. These will update the
current location so that the next item of business is properly aligned. Yes,
it applies to the next item of code/data; it is not a global setting, so if you
intend to have mixed data-sizes, be prepared to align things often. Here
are a few examples of how these things would work in practice.

@ ARM and THUMB versions of plot function


@ void plot(int x, int y, u16 clr)
@ External declaration
.extern vid_page @ extern u16 *vid_page;

@ ARM function definition


@ void plot_arm(int x, int y, u16 clr)
.align 2 @ Align to word boundary
.arm @ This is ARM code
.global plot_arm @ This makes it a real symbol
.type plot_arm STT_FUNC @ Declare plot_arm to be a function.

plot_arm: @ Start of function definition


add r1, r1, lsl #2
add r0, r1, lsl #5
ldr r1,=vid_page
ldr r1, [r1]
mov r0, r0, lsl #1
strh r2, [r1, r0]
bx lr

197
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

@ THUMB function definition


@ void m5_plot_thumb(int x, int y, u16 clr)
.align 2 @ Align to word boundary
.thumb_func @ This is a thumb function
.global plot_thumb @ This makes it a real symbol
.type plot_thumb STT_FUNC @ Declare plot_thumb to be a function.
plot_thumb: @ Start of function definition
lsl r3, r1, #2
add r1, r3
lsl r1, #5
add r0, r1
ldr r1,=vid_page
ldr r1, [r1]
lsl r0, #1
strh r2, [r1, r0]
bx lr

The functions above show the basic template for functions: three lines of
directives, and a label for the function. Note that there is no required
order for the four directives, so you may see others as well. In fact, the
.global directive can be separated completely from the rest of the
function's code if you want. Also note the use of .extern to allow access
to vid_page, which in tonclib always points to the current back buffer. To
be honest, it isn't even necessary because the assembler assumes that all
unknown identifiers come from other files.

Definition of variables
Of course, you can also have data in assembly, but before we go there a
word about acceptable number formats and number uses. GAS uses the
same number representations as C: plain numbers for decimals, „0‟ for
octal and „0x‟ for hexadecimal. There is also a binary representation,
using the „0b‟ prefix: for example, 0b1100 is 12. I've already used
numbers a couple of times now, and you should have noticed that they're
sometimes prepended by „#‟. The symbol is not actually part of the
number, but is the indicator for an immediate value.
It is also possible to perform arithmetic on numbers in assembly. That is
to say, you can have something like „mov r0, #1+2+3+4‟ to load 10 into
r0. Not only arithmetic, but bit operations will work too, which can be
handy if you want to construct masks or colors. Note, this only works for
constants.

Adding data to the assembly code


And now for adding data to your code. The main data directives are .byte,
.hword, and .word, which create bytes, halfwords and words,
198
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

respectively. If you want you can count .float among them as well, but
you don't want to because floats are evil on the GBA. Their use is simple:
put the directive on a line and add a number after it, or even a comma-
separated list for an array. If you add a label in front of the data, you have
yourself a variable. There are also a few directives for strings, namely
.ascii, .asciz and .string. .asciz and .string differ from .ascii in that they
add the terminating '\0' to the string, which is how strings usually work.
Just like the other data directives, you can make an array of strings by
separating them with commas. You can see some examples below; note
that what should have been the hword_var will definitely be misaligned
and hence useless.

.align 2
word_var: @ int word_var= 0xCAFEBABE
.word 0xCAFEBABE
word_array: @ int word_array[4]= { 1,2,3,4 }
.word 1, 2, 3, 4 @ NO comma at the end!!
byte_var: @ char byte_var= 0;
.byte 0
hword_var: @ NOT short hword_var= 0xDEAD;
.hword 0xDEAD @ due to bad alignment!
str_array: @ Array of NULL-terminated strings:
.string "Hello", "Nurse!"

Data & Code Sections


So far, we described how to make code and variables and now we have to
put them into the proper sections. A section is a contained area where
code and data are stored; the linker uses a linkscript to see where the
different sections are and then adds all your symbols and links
accordingly. The format for sections is „.section secname‟, with optional
„, "flags", %type‟ information I'll get to in a minute.

Traditionally, the code section called .text and the data section is called
.data, but there are a few more to consider: the general sections .bss and
.rodata, and the GBA-specific .ewram and .iwram. In principle, these
four are data sections, but they can be used for code by setting the correct
section flags. Note that .ewram stands for the EWRAM section
(0200:0000h), .iwram is IWRAM (0300:0000h) and .rodata is ROM
(0800:0000). The .bss section is a section intended for variables that are
either uninitialized or filled with zero. It is placed in IWRAM, just like
the .data. You may also see .sbss which stands for „small bss‟ and has
similar function as standard .bss, but placed in EWRAM.

The data sections can be used to indicate different kinds of data symbols.
199
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

For example, constants should go into .rodata. Non-zero initialized data


goes into .data, and zero or uninitialized data is to be placed into .bss.
You still have to indicate the amount of storage you need for each bss-
variable. This can be done with „.space n‟, which indicates n zero bytes,
or „.comm name, n, m‟, which creates a bss symbol called name, allocates
n bytes for it and aligns it to m bytes too.

// C symbols and their asm equivalents


// === C versions ===
int var_data = 12345678;
int var_zeroinit = 0;
int var_uninit;
const u32 const_array[4] = { 1, 2, 3, 4 };
u8 char1 [256] EWRAM_BSS;

@ === Assembly versions ===


@ alignment and global directives are removed for clarity
@ --- Non-zero Initialized data ---
.data
var_data:
.word 12345678
@ -- Zero initialized data ---
.bss
var_zeroinit:
.space 4

@ --- Uninitialized data ---


@ NOTE: .comm takes care of section, label and alignment for you
@ so those things need not be explicitly mentioned
.comm var_uninit,4,4

@ --- Constant (initialized) data ---


.section .rodata
cst_array:
.word 1, 2, 3, 4

@ --- Non-zero initialized data in ewram ---


.section .sbss
char1:
.space 256

That was data in different sections, now for code. The normal section for
code is .text, which will equate to ROM or EWRAM depending on the
linker specs. As IWRAM is too far away from ROM to jump to in one go,
so to make it work you have to load the address of your function in a
register and then jump to it using bx.
200
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Interrupt Handling
The example below shows the definition of interrupt vector tables and
exception handlers when writing in assembly code for Cortex-M3
microcontrollers

; Vector Table Mapped to Address 0 at Reset


AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors
DCD __initial_sp ; Initial SP
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler
DCD MemManage_Handler
DCD BusFault_Handler
DCD UsageFault_Handler
DCD 0, 0, 0, 0 ; Reserved
DCD SVC_Handler
DCD DebugMon_Handler
DCD 0 ; Reserved
DCD PendSV_Handler
DCD SysTick_Handler
; External Interrupts from here
DCD InterruptHandler0
DCD InterruptHandler1
DCD InterruptHandler2
; etc
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler
IMPORT __main
LDR R0, =__main
BX R0
ENDP
InterruptHandler0
; write your IRQ0 handler here
;
BX lr
END

iii. ARM Assembler Directives


The following table summarizes the most famous ARM assembler
directives.

201
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Table 6-10. ARM Assembler directives

Directive .syntax Description


.align .align This is the generic .align directive. For
expression the ARM however if the first
[, expression]argument is the assembler will behave
as if the argument is 2 (ie pad to the
next 4 byte boundary).
.arch .arch name Select the target architecture.
Specifying .arch clears any previously
selected architecture
.arch_extension .arch_extension Add or remove an architecture
name extension. May be used many times
.arm .arm Performs same action as .code 32.
.bss This switches to the .bss section.
.cantunwind Prevents unwinding through the
current function. No personality
routine or exception table data is
required or permitted.
.code .code [16 | 32] This directive selects the instruction
set being generated. The value 16
selects Thumb, and the value 32
selecting ARM
.cpu name Select the target processor. Valid
values for name are the same as for the
-mcpu commandline option
.eabi_attribute .eabi_attribute Set EABI object attribute tag to value.
tag, value
.even Aligns to an even-numbered address
.fnend Marks the end of a function with an
unwind table entry.
.fnstart Marks the start of a function with an
unwind table entry.
.force_thumb Forces selection of Thumb nstructions,
.fpu name Select the floating-point unit
.handlerdata Marks the end of the current function,
and the start of the exception table
entry for that function.
.ltorg This directive causes the contents of
the literal pool to be dumped into the
current section (assumed to be .text).
.pool This is a synonym for .ltorg.

202
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

Directive .syntax Description


.req name .req This creates an alias for register name
register name called name.
.save .save reglist Generate unwinder annotations to
restore the registers in reglist.
.setfp .setfp fpreg, Make all unwinder annotations
spreg [, #offset] relative to a frame pointer. Without
this the unwinder will use offsets from
the stack pointer.
.thumb Performs the same action as .code 16.
.unreq .unreq alias- This undefines a register alias which
name was previously defined using the req,

203
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

6-4.3. In-circuit Debugging & Emulation


All ARM devices feature an ICD (in-circuit debugging) interface, built
into the CPU core that allows for interactive debugging of the program.
Cortex-M3 devices are debugged via a standard JTAG or Serial wire
debugger (SWD) connector.

The μVision Debugger can be configured as a Simulator1 or as a Target


Debugger .The Simulator is a software-only product that simulates most
features of a microcontroller without the need for target hardware. By
using the Simulator, you can test and debug your embedded application
before any target hardware or evaluation board is available. μVision also
simulates a wide variety of peripherals including the serial port, external
I/O, timers, and interrupts. Peripheral simulation capabilities vary
depending on the device you have selected.

Fig. 6-7. Snapshot of ARM debugging window

The Target Debugger is a hybrid product that combines μVision with a


hardware debugger interfacing to your target system. The following
debug devices are supported:

 JTAG/OCDS Adapters that connect to on-chip debugging systems


like the ARM Embedded ICE

204
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

 Target Monitors that are integrated with user hardware and that are
available on many evaluation boards

 Emulators that connect to the MCU pins of the target hardware

 In-System Debuggers that are part of the user application program


and
 Provide basic test functions.

205
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

6-5. Summary

Every processor must be able to do basic data processing: arithmetic and


bit manipulation. They should also have instructions to access memory,
and be able to jump from one place in the code to another of conditionals
and loops and such. However, different processors will have different
ways of doing these things, and some operations of one set might not be
present in another. For example, ARM lacks a division instruction, and
can't perform data processing on memory directly. However, the ARM
instruction set has some benefits too, like a fair amount of general-
purpose registers and a simple instruction set, for the proper definition of
“simple”. And it has a very nifty way of dealing with bit-shifts

ARM architecture (32-bit) is the most widely used architecture in mobile


devices, and most popular 32-bit one in embedded systems. Each ARM
instruction takes four clock periods to execute (instruction cycle time).
Jumps take two instruction cycles. The ARM Instruction Set has the
following Main features
 All instructions are 32 bits long.
 Most instructions execute in a single cycle.
 Every instruction can be conditionally executed.
 Load/store architecture
• Data processing instructions act only on registers
• Specific memory access instructions with auto-indexing addressing.

ARM's instructions vary from about 35 instructions for the low-end


ARMs to over 80 instructions for the high-end ARMs. The instruction set
includes instructions to perform a variety of operations on registers
directly, the accumulator and a literal constant or the accumulator and a
register, as well as for conditional execution, and program branching. The
following Table is a summary of ARM addressing modes.

206
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

ARM Software Development Tools


Documentation set for ARM software development tools, including the
following product families:
 ARM DS-5 Development Studio is a suite of tools for embedded
development on all ARM processor-based devices. It includes:
o DS-5 Debugger: An operating system aware debugger for
ARM software, for debugging bare-metal systems, the Linux kernel, and
Linux and native Android applications. Also supports CoreSight trace.
o Streamline Performance Analyzer: ARM's profiling tool,
presenting a system-wide dashboard of hardware and software
performance counters for ARM processors and Mali GPUs.
o ARM C/C++ compilation tools: ARM Compiler 5 and ARM
Compiler 6 generate size and performance optimized code for ARM
processors.
o Fixed Virtual Platforms: Models of ARM systems to test
software execution without a hardware target.
o Eclipse IDE: Extensible platform for code authoring and
project management.
 Keil MDK-ARM supports embedded microcontroller software
development on Cortex-M, Cortex-R and classic ARM devices. It
includes:
o µVision IDE: Includes project management, code editing
and RTOS-aware debug tools.
o ARM C/C++ compilation tools: ARM Compiler 5 generates
small-footprint code for microcontrollers.
o RTX: Deterministic real-time operating system with source
code.
o Middleware: Drivers and software stacks for embedded
development.

207
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6

6-6. Problems
6-1) Each instruction in ARM machines is encoded into ____ Word .
a) 2 byte b) 3 byte c) 4 byte d) 8 byte
6-2) Memory can be accessed in ARM systems by _____ instructions .
i) Store ii) MOVE iii) Load iv) arithmetic v) logical
a) i,ii,iii b) i,ii c) i,iv,v d) iii,iv,v
6-3) Write an assembly language program to swap the contents of ARM
register r0 and r1
6-4) All instructions in ARM are conditionally executed .
a) True b) False
6-5) The effective address of the instruction written in Post-indexed
mode, MOVE[Rn]+Rm is ___ .
a) EA = [Rn] b) EA = [Rn +Rm] c) EA = [Rn] +Rm d) EA = [Rm] +Rn]
6-6) Design and write an ARM assembly language program that will
reverse the bits in a register so that the register containing d31, d30, ....
d1, d0 now contains d0, d1, ...... d30, d31.
6-7) Write an ARM assembly language program to add up all the
numbers that are great than 5 in the number array NUM1. Look at the
following given code for details and complete it.
;The semicolon is used to lead an inline comment
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
; Linker requires __Vectors to be exported
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors
DCD 0x20001000 ; stack pointer value when stack is empty
DCD Reset_Handler ; reset vector
ALIGN
;Your Data section
SUM DCD 0
SUMP DCD SUM
N DCD 7
NUM1 DCD 3, -7, 2, -2, 10, 20, 30
POINTER DCD NUM1
; The program
; Linker requires Reset_Handler
AREA MYCODE, CODE, READONLY
ENTRY
EXPORT Reset_Handler
Reset_Handler
; User Code Starts here
; Complete the program to add up all the numbers in the array NUM1 that are greater than 5.

208
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Chapter 7: Microcontroller Programming with C

7-1. Introduction
The C programming language is a general-purpose programming
language that provides code efficiency, elements of structured
programming, and a rich set of operators. C is not a big language and is
not designed for any one particular area of application. Its generality
combined with its absence of restrictions, makes C a convenient and
effective programming solution for a wide variety of software tasks.
Many applications can be solved more easily and efficiently with C than
with other more specialized languages.

C, prized for its efficiency, is the natural choice for developing embedded
systems. The structure of a C program developed for a microcontroller is
basically the same as the structure of a standard C program, with a few
minor changes. The structure of a typical microcontroller-based C
program is shown in the following figure.

#include <xxxx.h> /* your include files */


#define ...... /* your define statements here */
int ...... /* your global declarations here */
char ......
void func1() /* your functions here */
{
:
}
void main(void) /* ****** The main function here ***********/
{
while (1) /* Start an endless loop */
{
: /* write instructions to be executed */
}
:
} /* ***************** End of program ******************* */

Figure 7-1. General structure of a C-51 program.

In order to program a microcontroller in C, only the basic set of


statements and simple data structures are probably needed. However, full
treatment of the C-language is not being attempted here.

209
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-2. Programming with C51 Language


The Keil C51 is the industry-standard toolchain for all 8051-compatible
devices, it supports classic 8051, Dallas 390, NXP MX, extended 8051
variants, and C251 devices. The µVision IDE/Debugger integrates
complete device simulation, interfaces to many target debug adapters, and
provides various monitor debug solutions. The Cx51 Compiler is a
complete implementation of the ANSI (American National Standards
Institute) standard for the C language. It is dedicated to generating
extremely fast and compact code for the 8051 microcontrollers. The Cx51
Compiler provides you with the flexibility of programming in C and the
code efficiency and speed of assembly language.

The C language on its own is not capable of performing certain


operations that would normally require intervention from the operating
system (such as input and output). Instead, these capabilities are provided
as part of the standard library. Because these functions are separate from
the language itself, C is especially suited for producing code that is
portable across a wide number of platforms.

Note: History of Keil C51


In 1986, a rather young Reinhard Keil met with an Intel application
engineer from America at a trade show in Germany. They spoke and
Reinhard offered that he was working on a C compiler for the 8051. In
fact, this was to become the worlds first C compiler for the 8051. The
Intel guy asked him why are you wasting your time? The 8051 will soon
be dead; we have much better products coming soon. Spend your time on
something worthwhile‖. At that time, Intel had plans to replace the 8051
with the new 16 bit 8096. You might know the 8096 as the 80C196.

How incredibly wrong the Intel fellow was. The 196 was a fairly
successful family – but is now gone and certainly never managed to
replace the 8051. Fortunately, Reinhard ignored his advice and continued
on with his work which eventually culminated with the famous Keil
C51™ compiler. Many others have predicted or even proclaimed the
demise of the 8051, but this legendary product line continues, even as it is
pushing 30 years old. Today, new devices are still being added to the
marketplace and Reinhard continues his work on the C51 and his IDE,
μVision®3.

7.2.1. Data Types in C51


The Cx51 Compiler provides several basic data types you may use in
your C programs. The compiler supports the standard C data types as well
210
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

as several data types that are unique to the Cx51 platform, as shown in
the following table. Note that the bit, sbit, sfr, and sfr16 data types are not
provided in ANSI C. They are unique to the Cx51 Compiler

Data Typrpes Bits Bytes Value Range


bit 1 0 to 1
signed char 8 1 -128 to +127
unsigned char 8 1 0 to 255
enum 8 / 16 1 or 2 -128 to +127 or -32768 to +32767
signed short 16 2 -32768 to +32767
unsigned short 16 2 0 to 65535
signed int 16 2 -32768 to +32767
unsigned int 16 2 0 to 65535
signed long 32 4 -2147483648 to +2147483647
unsigned long 32 4 0 to 4294967295
float 32 4 ±1.175494E-38 to ±3.402823E+38
sbit 1 0 or 1
sfr 8 1 0 to 255
sfr16 16 2 0 to 65535

7-2.2. Memory Models


The memory model determines the default memory type used for function
arguments, automatic variables, and variables declared with no explicit
memory type. You specify the memory model on the command line
using the SMALL, COMPACT, and LARGE control directives. By
explicitly declaring a variable with a memory type specifier, you may
override the default memory type.

Figure 7-2. The C-51 memory models.


211
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

SMALL In this model, all variables default to the internal data memory
of the 8051. This is the same as if they were declared explicitly using the
data memory type specifier. In this memory model, variable access is
very efficient. However, all data objects, as well as the stack must fit into
the internal RAM. Stack size is critical because the stack space used
depends upon the nesting depth of the various functions. Typically, if the
BL51 code banking linker/locator is configured to overlay variables in the
internal data memory, the small model is the best model to use.

COMPACT Using compact model, all variables default to one page of


external data memory. This is the same as if they were explicitly declared
using the pdata memory type specifier. This memory model can
accommodate a maximum of 256 bytes of variables. The limitation is due
to the addressing scheme used, which is indirect through registers R0 and
R1. This memory model is not as efficient as the small model, therefore,
variable access is not as fast. However, the compact model is faster than
the large model. The high byte of the address is usually set up via port 2.
The compiler does not set this port for you.

LARGE In large model, all variables default to external data memory.


This is the same as if they were explicitly declared using the xdata
memory type specifier. The data pointer (DPTR) is used for addressing.
Memory access through this data pointer is inefficient, especially for
variables with a length of two or more bytes. This type of data access
generates more code than the small or compact models.

7-2.3. Sequencing Instructions


For normal sequencing in a program, write the steps as short English text
as if you are describing the program.

i. IF-THEN-ELSE-ENDIF
Use IF, THEN, ELSE, and ENDIF statements to describe the ¯ow of
control in your programs. For example:
IF switch = 1 THEN
Turn on buzzer
ELSE
Turn on buzzer T
Turn on LED
ENDIF

ii. DO-ENDDO
Use DO and ENDDO control statements to show iteration in your PDL
code. For example:
212
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Turn on LED
DO 5 times
Set clock to 1
Set clock to 0
ENDDO
A variation of the DO-ENDDO construct is to use other keywords like
DO-FOREVER, DO-UNTIL etc. as shown in the following examples.
Turn on buzzer
IF switch = 1 THEN
DO UNTIL Port 1 = 2
Turn on LED
Read Port 1
ENDDO
ENDIF

iii. REPEAT-UNTIL
This is another useful control construct which can be used in PDL codes.
An example is shown below where the program waits until a switch value
is equal to1.
REPEAT
Turn on buzzer
Read switch value
UNTIL switch = 1

7.2.4. Pointers in C51


The Cx51 Compiler supports the declaration of pointers variable using
the asterisk * character. The Cx51 Compiler pointers may be used to
perform all operations available in standard C. However, because of the
unique architecture of the 8051 and its derivatives, the Cx51 Compiler
provides two different types of pointers:

 generic pointers (as standard C pointers)


 memory-specific pointers

Generic pointers are declared in the same way as standard C pointers.


They take 3 bytes. The first byte is for the memory type, the second is for
the high-order byte of the offset, and the third is for the low-order byte of
the offset. Generic pointers may be used to access any variable regardless
of its location in memory space. Many library routines use these pointer
types for this reason. By using these generic un-typed pointers, a function
can access data regardless of the memory in which it is stored. For
example:

213
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

char *s; /* string ptr */


int *numptr; /* int ptr */
long *state; /* long ptr */

Memory specific pointers always include a memory type specification in


their declaration and always refer to a specific memory area. Because the
memory type is specified at compile-time, the memory type byte required
by untyped pointers is not needed by typed pointers. Typed pointers can
be stored using only one byte (idata, data, bdata, and pdata pointers) or
two bytes (code and xdata pointers). For example:

char data *str; /* ptr to string in data */


int xdata *numtab; /* ptr to int(s) in xdata */
long code *powtab; / * ptr to long(s) in code */

The use of memory specific pointers, one can significantly accelerate the
C51 programs. The following table shows the differences in code & data
size and execution time for the different methods of pointer declaration.

Generic Pointer idata Pointer xdata Pointer


C51 Source char *p; char idata *ip; char xdata *xp;
char val; char val; char val;
val = *p; val = *ip; val = *xp;
Generated AS51 MOV R1,p + 2 MOV R0,ip MOV DPL,xp
Code MOV R2,p + 1 MOV +1
MOV R3,p val,@R0 MOV DPH,xp
CALL CLDPTR MOV
A,@DPTR
MOV val,A
Pointer Size 3 bytes 1 byte 2 bytes
Code Size 11 bytes+ lib call 4 bytes 9 bytes
Execution Time 13 cycles 4 cycles 7 cycles

7-2.5. Functions in C51


The C51 Compiler provides a number of extensions for standard C
function declarations. These extensions allow you to:
Declare a function as an interrupt procedure
Choose the register bank used
Select the memory model
Declare a reentrant function
Declare alien (PL/M-51) functions
214
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

You may include these extensions or in the function declaration. Use the
following standard format for your C51 Compiler function declarations.
« return_type » funcname (« args »)
« {small | compact | large} »
« reentrant »
« interrupt x »
« using y »
where
return_type is the type of the value returned from the function. If no type
is specified, int is assumed.
funcname the name of the function.
args the argument list for the function.
small the function uses the small memory model.
compact the function uses the compact memory model.
large explicitly defines the function uses the large memory model.
reentrant indicates that the function is recursive or reentrant.
interrupt indicates that the function is an interrupt function.
x the interrupt number.
using specifies which register bank the function uses.
y the register bank number.
Descriptions of these attributes in detail comes in the following sections

t. Parameters and Local Variables


Historically, function parameters were passed using fixed memory
locations. This is still true for routines written in PL/M-51. However, the
Cx51 Compiler can pass up to three function arguments in registers.
Other arguments are passed using the traditional fixed memory areas.
Memory space is reserved for all function arguments regardless of
whether or not some of these arguments may be passed in registers. The
parameter areas must be publicly known to any calling module. So, they
are publicly defined using the following names:

?function_name?BYTE is the name assigned to the contiguous


memory area reserved for non-bit parameters.
?function_name?BIT is the name assigned to the contiguous memory
area reserved for all bit parameters.
215
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

For example, if func1 is a function that accepts bit arguments as well as


arguments of other data types, the bit arguments are passed in the
memory area starting at ?FUNC1?BIT. All other parameters are passed
starting at ?FUNC1?BYTE.

Segments (which may be overlayed by the linker) are created for each
function's parameters, local variables, and bit variables. The segment
name is assigned based on the memory model of the function.

Small Model Segment Naming Conventions

Information Segment Type Segment Name


Program code code ?PR?function_name?module_name
Local variables data ?DT?function_name?module_name
Local bit variables bit ?BI?function_name?module_name

Compact Model Segment Naming Conventions


Information Segment Type Segment Name
Program code code ?PR?function_name?module_name
Local variables pdata ?PD?function_name?module_name
Local bit variables bit ?BI?function_name?module_name

Large Model Segment Naming Conventions


Information Segment Type Segment Name
Program code code ?PR?function_name?module_name
Local variables xdata ?XD?function_name?module_name
Local bit variables bit ?BI?function_name?module_name

ii. Parameters and the Stack


The stack pointer on the classic 8051 accesses internal data memory only.
The Cx51 Compiler locates the stack area immediately following all
variables in the internal data memory. The stack pointer accesses internal
memory indirectly and can use all of the internal data memory up to the
0xFF limit. The total stack space of the classic 8051 is limited to 256
bytes. Rather than consume stack space with function parameters or
arguments, the Cx51 Compiler assigns a fixed memory location for each
function parameter.
When a function is called, the caller must copy the arguments into the
assigned memory locations before transferring control to the desired
function. The function then extracts its parameters, as needed, from these
fixed memory locations. Only the return address is stored on the stack
216
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

during this process. Interrupt functions require more stack space because
they must switch register banks and save the values of a few registers on
the stack.

By default, the Cx51 Compiler passes up to three function arguments in


registers. This enhances speed performance. For more information, refer
to Parameters and Registers. Note that The Cx51 Compiler uses extended
stack areas that are available in some enhanced 8051 variants. In this way
the stack space can be increased to several Kilobytes. Some 8051
microcontrollers provide only 64 bytes of on-chip data memory but most
devices have 256 bytes. Take this into consideration when determining
which memory model to use, because the amount of on-chip data and
idata memory used directly affects the amount of stack space.

iii. Parameters and Registers


The Cx51 Compiler passes up to three function arguments in CPU
registers. This mechanism significantly improves system performance as
arguments are not written to and read from memory. Argument or
parameter passing can be controlled by the REGPARMS and
NOREGPARMS directives. The following table details the registers
used for different argument positions and data types.

Argument char int long generic ptr


Number 1-byte ptr 2-byte ptr float
1 R7 R6 & R7 R4-R7 R1-R3
2 R5 R4 & R5 R4-R7 R1-R3
3 R3 R2 & R3 R1-R3

Note that if the first parameter of a function is a bit type, then other
parameters are not passed in registers. This is because parameters that are
passed in registers are out of sequence with the numbering scheme shown
above. For this reason, bit parameters should be declared at the end of the
argument list. If no registers are available for argument passing, fixed
memory locations are used for function parameters.

iv. Return Values


CPU registers are always used for function return values. The following
table lists the return types and the registers used for each.

Return Type Registers Storage Format


bit Carry Flag
char, unsigned char, 1-byte ptr R7
217
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

int, unsigned int, 2-byte ptr R6 & R7 MSB in R6, LSB in R7


long, unsigned long R4-R7 MSB in R4, LSB in R7
float R4-R7 32-Bit IEEE format
generic ptr R1-R3 Memory type in R3, MSB
R2, LSB R1

v. Reentrant Functions
A reentrant function may be shared by several processes at the same time.
When a reentrant function is executing, another process can interrupt the
execution and then begin to execute that same reentrant function.
Normally, functions in Cx51 cannot be called recursively or in a fashion
which causes reentrancy. The reason for this limitation is that function
arguments and local variables are stored in fixed memory locations.
Recursive calls to the function use the same memory locations. And, in
this case, arguments and locals would get corrupted.
The reentrant function attribute allows you to declare functions that may
be reentrant and, therefore, may be called recursively. For example:

int calc (char i, int b) reentrant {


int x;
x = table [i];
return (x * b);
}

Reentrant functions can be called recursively and can be called


simultaneously by two or more processes. Reentrant functions are often
required in real-time applications or in situations where interrupt code
and non-interrupt code must share a function. Like the above example,
you may define (using the reentrant attribute) functions as being
reentrant. For each reentrant function, a reentrant stack area is simulated
in internal or external memory depending upon the memory model used,
as follows:
Small model reentrant functions simulate the reentrant stack in idata
memory.
Compact model reentrant functions simulate the reentrant stack in
pdata memory.
Large model reentrant functions simulate the reentrant stack in xdata
memory.
Reentrant functions use the default memory model to determine which
memory space to use for the reentrant stack. You may specify (with the
small, compact, and large function attributes) which memory model to
218
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

use for a function. Refer to Specifying the Memory Model for a Function
for more information about memory models and function declarations.
The following rules apply to functions declared with the reentrant
attribute.
bit type function arguments may not be used. Local bit scalars are
also not available. The reentrant capability does not support bit
variables.
Reentrant functions must not be called from alien functions.
Reentrant function cannot use the alien attribute specifier to enable
PL/M-51 argument passing conventions.
A reentrant function may simultaneously have other attributes like
using and interrupt and may include an explicit memory model
attribute (small, compact, large).
Return addresses are stored in the 8051 hardware stack. Any other
required PUSH and POP operations also affect the 8051 hardware
stack.
Reentrant functions using different memory models may be
intermixed. However, each reentrant function must be prototyped and
must include its memory model attribute in the prototype. This is
necessary for calling routines to place the function arguments in the
proper reentrant stack.

Each of the three possible reentrant models contains its own reentrant
stack area and stack pointer. For example, if small and large reentrant
functions are declared in a module, both small and large reentrant stacks
are created along with two associated stack pointers (one for small and
one for large).

The reentrant stack simulation architecture is inefficient, but necessary


due to a lack of suitable addressing methods available on the 8051. For
this reason, use reentrant functions cautiously.

The simulated stack used by reentrant functions has its own stack pointer
which is independent of the 8051 stack and stack pointer. The stack and
stack pointer are defined and initialized in the STARTUP.A51 file. The
following table details the stack pointer assembler variable name, data
area, and size for each of the three memory models.

219
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Model Pointer
Stack Information
SMALL The stack is located in indirectly accessible
?C_IBP
(1 Byte)
internal memory (idata). The maximum
reentrant stack size is 256 bytes. To access the
small reentrant stack, R0 or R1 is loaded with
the value of ?C_IBP and the reentrant stack is
accessed indirectly using the
MOV A, @R0/@R1 and MOV @R0/@R1, A
instructions.
COMPACT ?C_PBP The stack is located in Page-addressable
(1 Byte) external memory (pdata). The maximum
reentrant stack size is 256 bytes. To access the
compact reentrant stack, R0 or R1 is loaded
with the value of ?C_PBP and the reentrant
stack is accessed indirectly using the
MOVX A, @R0/@R1 and
MOVX @R0/@R1, A instructions.
LARGE ?C_XBP The stack is located in external memory
(2 Bytes) (xdata). The maximum reentrant stack size is
64 KB. To access the large reentrant stack,
DPTR is loaded with the value of ?C_XBP and
the reentrant stack is accessed indirectly by the
MOVX A, @DPTR and MOVX @DPTR, A
instructions.

The simulated stack area for reentrant functions is organized from top to
bottom—it stacks down. The 8051 hardware stack is just the opposite and
is organized bottom to top—it stacks up. When using the SMALL
memory model, both the simulated stack and the 8051 hardware stack
share the same memory area but grow towards each other. The simulated
stack and stack pointers are declared and initialized in the Cx51 Compiler
startup code in STARTUP.A51 which can be found in the LIB directory.
You must modify the startup code to specify which simulated stack(s) to
initialize in order to use reentrant functions. You can also modify the
starting address for the top of the simulated stack in the startup code.
When calling a function with a reentrant stack, the compiler MUST know
that the function has a reentrant stack. The compiler figures this out from
the function prototype which should include the reentrant keyword (like
the function definition). The compiler must also know the memory model
used by the function to determine which reentrant stack to stuff
arguments on. This is determined either from the specified memory
model of the function, or the specified memory model of the compiler, or
the default memory model (small).
220
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

In order to pass arguments, the compiler decrements the stack pointer and
then "pushes" arguments onto the stack by storing the argument indirectly
through R0/R1 or DPTR. When a reentrant function is called, it decreases
the stack pointer (for local variables) and accesses arguments using the
stack pointer plus an offset (number of bytes of local variables). When a
reentrant function returns, it adjusts the stack pointer to the value before
arguments were pushed. So the caller does not need to perform any stack
adjustment after calling a reentrant function.

vi. Interrupt Functions


The 8051 and its derivatives provide a number of hardware interrupts that
may be used for counting, timing, detecting external events, and sending
and receiving data using the serial interface. The standard interrupts
found on an 8051 are listed in the following table:

Interrupt Number Description Address


0 EXTERNAL INT 0 0003h
1 TIMER/COUNTER 0 000Bh
2 EXTERNAL INT 1 0013h
3 TIMER/COUNTER 1 001Bh
4 SERIAL PORT 0023h

As 8051 vendors create new parts, more interrupts are added. The Cx51
Compiler supports interrupt functions for 32 interrupts (0-31). The
interrupt vector address are shown in the following table.

Interrupt Address Interrupt Address


Number Number
0 0003h 16 0083h
1 000Bh 17 008Bh
2 0013h 18 0093h
3 001Bh 19 009Bh
4 0023h 20 00A3h
5 002Bh 21 00ABh
6 0033h 22 00B3h
7 003Bh 23 00BBh
8 0043h 24 00C3h
9 004Bh 25 00CBh
10 0053h 26 00D3h
11 005Bh 27 00DBh
12 0063h 28 00E3h
13 006Bh 29 00EBh
14 0073h 30 00F3h
15 007Bh 31 00FBh

221
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

The interrupt function attribute specifies that the associated function is


an interrupt service routine. For example:

unsigned int interruptcnt;


unsigned char second;
void timer0 (void) interrupt 1 using 2 {
if (++interruptcnt == 4000) { /* count to 4000 */
second++; /* second counter */
interruptcnt = 0; /* clear int counter */
}
}

The interrupt attribute takes as an argument an integer constant in the 0


to 31 value range. Expressions with operators and the interrupt attribute
are not allowed in function prototypes. The interrupt attribute affects the
object code of the function as follows:

When required, the contents of ACC, B, DPH, DPL, and PSW are
saved on the stack at function invocation time.
All working registers used in the interrupt function are stored on the
stack if a register bank is not specified with the using attribute.
The working registers and special registers that were saved on the
stack are restored before exiting the function.
The function is terminated by the 8051 RETI instruction.
In addition, the Cx51 Compiler generates the interrupt vector
automatically.

7-2.6. Cx51 Library Routines


Since the Cx51 Compiler is a cross compiler, some aspects of the C
programming language and standard libraries are altered or enhanced to
address the peculiarities of an embedded target processor. Refer to
Language Extensions for more detailed information. The Cx51 Compiler
differs in only a few aspects from the ANSI C Standard. These
differences can be grouped into compiler-related differences and library-
related differences. The ANSI C Standard Library includes a vast number
of routines, most of which are included in the Cx51 Library. Many,
however, are not applicable to an embedded application and are excluded
from the Cx51 Library. The following ANSI Standard Library routines
are included in the Cx51 Compiler library:

222
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

abs iscntrl printf strncpy


acos isdigit putchar strpbrk
asin isgraph puts strrchr
atan islower rand strspn
atan2 isprint realloc strstr
atof ispunct scanf strtod
atoi isspace setjmp strtol
atol isupper sin strtok
calloc isxdigit sinh strtoul
ceil labs sprintf tan
cos log sqrt tanh
cosh log10 srand tolower
exp longjmp sscanf toupper
fabs malloc strcat va_arg
floor memchr strchr va_end
fmod memcmp strcmp va_start
free memcpy strcpy vprintf
getchar memmove strcspn vsprintf
gets memset strlen
isalnum modf strncat
isalpha pow strncmp

The following ANSI library routines are not included in the C51 library:

abort fgets ldexp setlocale


asctime fopen ldiv setvbuf
atexit fprintf localeconv signal
bsearch fputc localtime strcoll
clearerr fputs mblen strerror
clock fread mbstowcs strftime
ctime freopen mbtowc strxfrm
difftime frexp mktime system
div fscanf perror time
exit fseek putc tmpfile
fclose fsetpos qsort tmpnam
feof ftell raise ungetc
ferror fwrite remove vfprintf
fflush getc rename wcstombs
fgetc getenv rewind wctomb
fgetpos gmtime setbuf

223
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

The following routines are not found in the ANSI Standard Library but
are included in the C51 library:

acos517 _getkey _nop_ strrpos


asin517 init_mempool printf517 strtod517
atan517 _irol_ scanf517 tan517
atof517 _iror_ sin517 _testbit_
cabs log10517 sprintf517 toascii
cos517 log517 sqrt517 toint
_crol_ _lrol_ sscanf517 _tolower
_cror_ _lror_ strpos _toupper
exp517 memccpy strrpbrk ungetchar

The C51 compiler includes seven different ANSI compile-time libraries


which are optimized for various functional requirements.
Library File Description
C51S.LIB Small model library without floating-point arithmetic
C51FPS.LIB Small model floating-point arithmetic library
C51C.LIB Compact model library without floating-point arithmetic
C51FPC.LIB Compact model floating-point arithmetic library
C51L.LIB Large model library without floating-point arithmetic
C51FPL.LIB Large model floating-point arithmetic library
80C751.LIB Library for use with the Philips 8xC751 and derivatives

Source code is provided for library modules that perform hardware-


related I/O and is found in the \C51\LIB directory. You may use these
source files to help you quickly adapt the library to perform I/O using any
I/O device in your target.

i. Math Routines

Routine Attributes Description


acos Calculates the arc cosine of a specified number.
acos517 Calculates the arc cosine of a specified number.
asin Calculates the arc sine of a specified number.
asin517 Calculates the arc sine of a specified number.
atan Calculates the arc tangent of a specified
number.
atan517 Calculates the arc tangent of specified number.
atan2 Calculates the arc tangent of a fraction.
224
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Routine Attributes Description


ceil Finds the integer ceiling of a specified number.
cos Calculates the cosine of a specified number.
cos517 Calculates the cosine of a specified number.
cosh Calculates the hyperbolic cosine of a number.
exp Calculates the exponential function of number.
exp517 Calculates the exponential function of number.
fabs reentrant Finds the absolute value of a specified number.
floor Finds the largest int less than or equal number
fmod Calculates the floating-point remainder.
log Calculates the natural logarithm of a number.
log517 Calculates the natural logarithm of a number.
log10 Calculates the common logarithm of a number.
log10517 Calculates the common logarithm of a number.
modf Generates integer and fractional components of
a specified number.
pow Calculates a value raised to a power.
rand reentrant Generates a pseudo random number.
sin Calculates the sine of a specified number.
sin517 Calculates the sine of a specified number.
sinh Calculates the hyperbolic sine of a number.
srand Initializes the pseudorandom number generator.
sqrt Calculates the square root of a number.
sqrt517 Calculates the square root of a number.
tan Calculates the tangent of a specified number.
tan517 Calculates the tangent of a specified number.
tanh Calculates the hyperbolic tangent of a number.
_chkfloat_ intrinsic, Checks the status of a floating-point number.
reentrant
_crol_ intrinsic, Rotates an unsigned char left a number of bits.
reentrant
_cror_ intrinsic, Rotates an unsigned char right a number of bits.
reentrant
_irol_ intrinsic, Rotates an unsigned int left a number of bits.
reentrant
_iror_ intrinsic, Rotates an unsigned int right a number of bits.
reentrant
_lrol_ intrinsic, Rotates an unsigned long left a number of bits.
reentrant
_lror_ intrinsic, Rotates an unsigned long right a number of bits.
reentrant
225
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

The math routines perform common mathematical calculations. Most of


these routines work with floating-point values and include the floating-
point libraries and support routines. All of these routines are implemented
as functions. Most are prototyped in the math.h include file. Functions
which end in 517 (acos517, asin517, atan517, cos517, exp517, log517,
log10517, sin517, sqrt517, and tan517) are prototyped in the 80c517.h
include file. The rand and srand functions are prototyped in the stdlib.h
include file. The _chkfloat_, _crol_, _cror_, _irol_, _iror_, _lrol_, and
_lror_ functions are prototyped in the intrins.h include file.

ii. Character Routines

Routine Attributes Description


isalnum reentrant Tests for an alphanumeric character.
isalpha reentrant Tests for an alphabetic character.
iscntrl reentrant Tests for a Control character.
isdigit reentrant Tests for a decimal digit.
isgraph reentrant Tests for a printable character except for space.
islower reentrant Tests for a lowercase alphabetic character.
isprint reentrant Tests for a printable character.
ispunct reentrant Tests for a punctuation character.
isspace reentrant Tests for a whitespace character.
isupper reentrant Tests for an uppercase alphabetic character.
isxdigit reentrant Tests for a hexadecimal digit.
toascii reentrant Converts a character to an ASCII code.
toint reentrant Converts a hexadecimal digit to a decimal value.
tolower reentrant Tests a character and converts it to lowercase if it
is uppercase.
_tolower reentrant Unconditionally converts a character to
lowercase.
toupper reentrant Tests a character and converts it to uppercase if it
is lowercase.
_toupper reentrant Unconditionally converts a character to
uppercase.

The character routines allow you to test individual characters for a variety
of attributes and convert characters to different formats.
The _tolower, _toupper, and toascii routines are implemented as
macros. All other routines are implemented as functions. All macro
definitions and function prototypes are found in the ctype.h include file

226
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

iii. String Routines

Routine Attributes Description


strcat Concatenates two strings.
strchr reentrant Returns a pointer to the first occurrence of a
specified character in a string.
strcmp reentrant Compares two strings.
strcpy reentrant Copies one string to another.
strcspn Returns the index of the first character in a string
that matches any character in a second string.
strlen reentrant Returns the length of a string.
strncat Concatenates up to a specified number of
characters from one string to another.
strncmp Compares two strings up to a number of
characters.
strncpy Copies up to a specified number of characters
from one string to another.
strpbrk Returns a pointer to the first character in a string
that matches any character in a second string.
strpos reentrant Returns the index of the first occurrence of a
specified character in a string.
strrchr reentrant Returns a pointer to the last occurrence of a
specified character in a string.
strrpbrk Returns a pointer to the last character in a string
that matches any character in a second string.
strrpos reentrant Returns the index of the last occurrence of a
specified character in a string.
strspn Returns the index of the first character in a string
that doesnot match any character in a 2nd string.
strstr Returns a pointer in a string that is identical to a
second sub-string.

The string routines are implemented as functions and are prototyped in


the string.h include file. They perform the following operations:
Copying strings
Appending one string to the end of another
Comparing two strings
Locating one or more characters from a specified set in a string

All string functions operate on null-terminated character strings. Use the


buffer manipulation routines to work on non-terminated strings.
227
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

iv. Stream I/O Routines

Routine Attributes Description


getchar reentrant Reads and echoes a character using the _getkey
and putchar routines.
_getkey Reads a character using the 8051 serial interface.
gets Reads and echoes a character string using the
getchar routine.
printf Writes formatted data using the putchar routine.
printf517 Writes formatted data using the putchar routine.
putchar Writes a character using the 8051 serial
interface.
puts reentrant Writes a character string and newline ('\n')
character using the putchar routine.
scanf Reads formatted data using the getchar routine.
scanf517 Reads formatted data using the getchar routine.
sprintf Writes formatted data to a string.
sprintf517 Writes formatted data to a string.
sscanf Reads formatted data from a string.
sscanf517 Reads formatted data from a string.
ungetchar Places a character back into the getchar input
buffer.
vprintf Writes formatted data using the putchar
function.
vsprintf Writes formatted data to a string.

The stream I/O routines are implemented as functions and are prototyped
in the stdio.h include file. The stream input and output routines allow you
to read and write data to and from a user-defined I/O interface. Characters
are read using the _getkey routine and are written using the putchar
routine. The default _getkey and putchar functions in the C51 library
read and write characters using the 8051 serial interface.

The source code for _getkey and putchar is available in the


\KEIL\C51\LIB folder. You may modify these files and substitute them
for the default library routines. The stream functions then perform input
and output using your modified _getkey and putchar routines.
To use the existing _getkey and putchar routines, you must first
initialize the 8051 serial port. If the serial port is not properly initialized,
the default stream functions do not function. Initializing the serial port
requires manipulating several special function registers (SFRs) of the
8051.
228
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

v. Memory Allocation
The following files contain the source code for the memory allocation
routines.

C Source File
Description
CALLOC.C This file contains the source code for the calloc library
routine. This routine allocates memory for an array from
the memory pool.
FREE.C This file contains the source code for the free library
routine. This routine returns a previously allocated
memory block to the memory pool.
INIT_MEM.C This file contains the source code for the init_mempool
library routine. This routine allows you to specify the
location and size of a memory pool from which memory
may be allocated using the malloc, calloc, and realloc
routines.
MALLOC.C This file contains the source code for the malloc library
routine. This routine allocates memory from the
memory pool.
REALLOC.C This file contains the source code for the realloc library
routine. This routine resizes a previously allocated
memory block.

7-2.7. Basic I/O


The following files contain the source code for the low-level stream I/O
routines. When you use µVision IDE, you can simply add the modified
versions to the project.

C Source File Description


PUTCHAR.C Used by all stream routines that output characters. You
may adapt this routine to your individual hardware (for
example, LCD or LED displays). The default version
outputs characters via the serial interface. An
XON/XOFF protocol is used for flow control. Line feed
characters ('\n') are converted into carriage return/line
feed sequences ('\r\n').
GETKEY.C Used by all stream routines that input characters. You
may adapt this routine to your individual hardware (for
example, matrix keyboards). The default version reads a
character via the serial interface. No data conversions are
performed.

229
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-2.8. C51 Compiler Directives


The following table is an alphabetical list of the control directives
available in the Cx51 Compiler.

Directive Group Description


AREGS Object Enables absolute register (ARn)
addressing.
ASM Source Marks the beginning of an inline
assembly block.
BROWSE1 Object Enables source browser information.
CODE1 Listing Includes generated assembly in the
listing file.
COMPACT1 Object Selects the COMPACT memory
model.
COND1 Listing Includes (in the listing file)
conditional source lines skipped by the
preprocessor.
DEBUG1 Object Includes debugging information in the
object file.
DEFINE2 Source Defines preprocessor names on the
command line.
DISABLE Object Disables interrupts for the duration of
a single function.
EJECT Listing Inserts a form feed character into the
listing file.
ENDASM Source Marks the end of an inline assembly
block.
FLOATFUZZY Object Sets the number of bits rounded for
floating-point comparisons.
INCDIR1 Source Sets additional include file paths.
INTERVAL1 Object Specifies the interval to use for
interrupt vectors.
INTPROMOTE1 Object Enables ANSI integer promotion
rules.
INTVECTOR1 Object Specifies the base address for interrupt
vectors.
LARGE1 Object Selects the LARGE memory model.
LISTINCLUDE Listing Adds contents of include files into the
listing file.
MAXARGS1 Object Specifies the maximum size of
variable-length argument lists.

230
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Directive Group Description


MOD517 Object Enables support for additional
hardware features of the Infineon
80C517 and compatible devices.
MODA2 Object Enables dual data pointer support for
the Atmel 82x8252 and compatible
devices.
MODAB2 Object Enables dual data pointer support for
the Analog Devices Microconverters
(ADuC B2 devices).
MODDA Object Enables arithmetic accelerator support
for the Dallas 80C390, 80C400, and
5240.
MODDP2 Object Enables dual data pointer support for
the Dallas 320, 520, 530, 550, and
compatible devices.
MODP2 Object Disables dual data pointer support for
Philips and Atmel devices.
NOAMAKE Object Excludes build information from the
object file.
NOAREGS Object Disables absolute register (ARn)
addressing.
NOCOND Listing Excludes (from the listing file)
conditional source lines skipped by the
preprocessor.
NOEXTEND Source Disables Cx51 extensions to ANSI C.
NOINTPROMOTE Object Disables ANSI integer promotion
rules.
NOINTVECTOR Object Disables generation of interrupt
vectors.
NOMOD517 Object Disables support for additional
hardware features of the Infineon
80C517 and compatible devices.
NOMODA2 Object Disables dual data pointer support for
Atmel 82x8252 & compatible devices
NOMODAB2 Object Disables dual data pointer support for
the Analog Devices Microconverters
(ADuC B2 devices).
NOMODDA Object Disables arithmetic accelerator
support for the Dallas 80C390,
80C400, and 5240.

231
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Directive Group Description


NOMODDP2 Object Disables dual data pointer support for
the Dallas 320, 520, 530, 550, and
compatible devices.
MODP2 Object Enables dual data pointer support for
Philips and Atmel devices.
NOOBJECT Object Disables object file generation.
NOPRINT Listing Disables listing file generation.
NOREGPARMS Object Disables passing parameter in
registers
OBJECT Object Specifies the name for the object file.
OBJECTADVANCED Object Adds additional information to the
object file for program optimizations.
OBJECTEXTEND Object Adds additional debugging
information to the object file.
OMF2 Object Generates an OMF2 object module.
ONEREGBANK Object Generates code for programs that use
only one register bank.
OPTIMIZE Object Specifies the level of optimization
performed by the compiler.
ORDER Object Allocates storage for variables in the
order in which they are declared.
PAGELENGTH Listing Specifies the number of lines on a
page.
PAGEWIDTH Listing Specifies the number of characters on
a line in the listing file.
PREPRINT Listing Produces a preprocessor listing file.
PRINT Listing Specifies the name for the listing file.
REGFILE Object Specifies the register definition file for
global register optimization.
REGISTERBANK Object Specifies the register bank to use for
absolute register accesses.
REGPARMS Object Enables passing parameter in registers.
RESTORE Object Restores settings for aregs, reg-
parms, and OPTIMIZE directives
RET_PSTK Object Uses the COMPACT model reentrant
stack for return addresses.
RET_XSTK Object Uses the LARGE model reentrant
stack for return addresses.
ROM Object Specifies the ROM model (SMALL,
COMPACT or LARGE).
232
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Directive Group Description


SAVE Object Saves settings for aregs, regparms,
and OPTIMIZE directives.
SMALL Object Selects the SMALL memory model.
SRC1 Object Creates an assembler source file
instead of an object file.
STRING Object Locates implicit string constants to
xdata or far memory.
SYMBOLS Listing Includes a symbol list in the listing
file.
TABS1 Listing Specifies the tab character expansion
width for the listing file.
USERCLASS Object Renames memory classes which allow
more flexible variable location.
VARBANKING Object Enables far memory type variables.
WARNINGLEVEL Listing Selects the level of warning detection.
XCROM Object Assumes const xdata variables are
stored in ROM.

Note that the directives and arguments (except for DEFINE directive),
are not case sensitive. These directives apply to the entire source file and
may be specified only once on the command line or at the beginning of
the source file using the #pragma statement. They need not be used more
than once in a source file.

The MODA2 directive instructs the compiler to produce code for the
additional hardware components (specifically, the additional data
pointers) available in the Atmel 80x8252 and compatible derivatives.
Using additional data pointers improves the performance of the memcpy,
memmove, memcmp, strcpy, and strcmp library routines.

233
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-2.9. Interfacing C51 to AS51


By observing a few programming rules, you can call assembly routines
from C and vice versa. Public variables declared in the assembly module
are available for your C programs.

There are several reasons to call an assembly routine from your C


program:

You have assembly code already written that you wish to use.
You need to improve the speed of a particular function.
You want to manipulate SFRs or memory-mapped I/O devices directly
from assembly.

This section describes how to write assembly routines that can be directly
interfaced to C programs. For an assembly routine to be called from C, it
must be aware of the parameter passing and return value conventions
used in C functions. For all practical purposes, it must appear to be a C
function.

i. Calling C51 from within Assembly 51


You can easily access assembly routines from C and vice versa. Values
returned from functions are always passed in CPU registers. You can use
the SRC directive to direct the C51 compiler to generate an assembly file
instead of an object file. For example, the following C source file:

unsigned int asmfunc1 (unsigned int arg)


{
return (1 + arg);
}

generates the following assembly output file when compiled using the
SRC directive:
PUBLIC _asmfunc1
RSEG ?PR?_asmfunc1?ASM1
_asmfunc1:
; Variable ’arg?00’ assigned to Register ’R6/R7’
MOV A,R7 ; load LSB of the int
ADD A,#01H ; add 1
MOV R7,A ; put it back into R7
CLR A
ADDC A,R6 ; add carry & R6
MOV R6,A
?C0001:
RET ; return result in R6/R7

234
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

You may use the #pragma asm and #pragma endasm preprocessor
directives to insert assembly instructions into your C source code.

The following HELLO program prints the text ―Hello World‖ to the
serial port. The program is contained in a single source file, HELLO.C,
which is listed below. You can perform these operations from the DOS
command line, using batch files, or from µVision for Windows using a
project file.

#pragma DEBUG OBJECTEXTEND CODE


/* pragma lines can contain command line
directives*/
#include <reg51.h> /* special function register declarations */
/* for the intended 8051 derivative */
#include <stdio.h> /* prototype declarations for I/O functions */
void main (void)
{ /* execution starts here after stack init */
SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 0xf3; /* TH1: reload value for 2400 baud */
TR1 = 1; /* TR1: timer 1 run */
TI = 1; /* TI: set TI to send first char of UART */
printf ("Hello World\n"); /* the ’printf’ function call */
while (1) { ; } /* an endless loop */
/*Program does not stop and never returns */
}

ii. Interfacing C51 with Intel’s PL/M-51


We discuss here how to interface the C51 programs with the 8051
assembly programs. By observing a few programming rules, you can call
assembly routines from C and vice versa. In fact, the C51 Compiler easily
interfaces with the Intel PL/M-51 Compiler and allows us to:

Call PL/M-51 routines from C.


Call C routines from PL/M-51.

To invoke PL/M-51 routines from your C functions, you must first


declare them external with the alien function type specifier. For example:

extern alien char plm_func (int, char);

char c_func (void) {


int i;
char c;

235
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

for (i = 0; i < 100; i++) {


c = plm_func (i, c); /* call PL/M func */
}
return (c);
}

To create C functions that may be invoked from your PL/M-51 routines,


you must use the alien function type specifier in the C function
declaration. For example:

alien char c_func (char a, int b) {


return (a * b);
}

Parameters and return values of PL/M-51 functions may be bit, char,


unsigned char, int, and unsigned int. Other types, including long, float,
and all types of pointers, can be declared in C functions with the alien
type specifier. However, use these types with care because PL/M-51 does
not directly support 32-bit binary integers or floating-point numbers.
Public variables declared in the PL/M-51 module are available to your C
programs by declaring them external like you would for any C variable.

Intel's PL/M-51 is a popular programming language that is similar to C in


many ways. You can easily interface the Cx51 Compiler to routines
written in PL/M-51.

 You can access PL/M-51 functions from C by declaring them with


the alien function type specifier.
 Public variables declared in the PL/M-51 module are available to
your C programs.
 The PL/M-51 compiler generates object files in the OMF-51
format.

The Cx51 Compiler can generate code using the PL/M-51 parameter
passing conventions. The alien function type specifier is used to declare
public or external functions that are compatible with PL/M-51 in any
memory model. For example:

extern alien char plm_func (int, char);


alien unsigned int c_func (unsigned char x, unsigned char y) {
return (x * y);
}
236
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Parameters and return values of PL/M-51 functions may be any of the


following types: bit, char, unsigned char, int, and unsigned int. Other
types, including long, float, and all types of pointers, can be declared in
C functions with the alien type specifier. However, use these types with
care because PL/M-51 does not directly support 32-bit binary integers or
floating-point numbers.

Note: PL/M-51 does not support variable-length argument lists.


Therefore, functions declared using the alien type specifier must have a
fixed number of arguments. The ellipsis notation used for variable-length
argument lists is not allowed for alien functions and causes the Cx51
Compiler to generate an error message. For example:

xtern alien unsigned int ifun(char, int, ...);


** ERROR IN LINE 1 OF A.C: 'ifun': Var_parms on alien function

7-2.10. Interfacing C51 with Real-Time Operating Systems (RTOS)


The Cx51 Compiler supports the RTX51 Full and RTX51 Tiny real-time
multitasking operating systems with the _task_ and _priority_ keywords.

The _task_ keyword specifies a function is a real-time task.


The _priority_ keyword specifies the priority for the task.

For example:

void func (void) _task_ num _priority_ pri

where

num is a task ID number from 0-255 for RTX51 Full or 0-15 for RTX51
Tiny.
pri is the priority for the task. Refer to the RTX51 User's Guide or the
RTX51 Tiny User's Guide for more information.

RTX51 Tiny is a real-time operating system (RTOS) which allows you to


create applications that simultaneously perform multiple functions or
tasks. This is often required in an embedded application. While it is
certainly possible to create real-time programs without an RTOS (by
executing one or more functions or tasks in a loop), there are numerous
scheduling, maintenance, and timing issues that an RTOS like RTX51
Tiny can solve for you.
237
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

A real-time operating system (RTOS) allows flexible scheduling of


system resources, like the CPU and memory, and offers communication
between tasks. RTX51 Tiny is a powerful RTOS that is easy to use and
that works with all 8051 derivatives. RTX51 Tiny programs are written
using standard C constructs and compiled with the Keil C51 C Compiler.
Additions to the C language allow you to easily declare task functions
without the need for complex stack and variable frame configuration.
RTX51 Tiny programs require only that you include a special header file
and link the RTX51 Tiny library into your program.

238
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-3. Programming with SDCC


SDCC is an ANSI - C compiler suite that targets the Intel MCS51 based
microprocessors (8031, 8032, 8051, 8052, etc.), Maxim (formerly Dallas)
DS80C390 variants, Freescale (formerly Motorola) HC08, Zilog Z80
MCUs (z80, z180, gbz80, Rabbit 2000/3000, and STMicroelectronics
STM8. Work is in progress on supporting the Microchip PIC16 and
PIC18 targets. It can be retargeted for other microprocessors.

SDCC suite is a collection of several components derived from different


sources with different licenses. SDCC compiler suite include:

sdas and sdld, a retargettable assembler and linker, based on ASXXX,


(GPL).
sdcpp preprocessor, based on GCC cpp; (GPL).
ucsim simulators, (GPL).
sdcdb source level debugger, (GPL).
sdbinutils library archive utilities, including sdar, sdranlib and sdnm,
derived from GNU Binutils; (GPL)
SDCC run-time libraries; (GPL+LE). Pic device libraries and header
files are derived from Microchip header (.inc) and linker script (.lkr)
files. Microchip requires that "The header files should state that they
are only to be used with authentic Microchip devices" which makes
them incompatible with the GPL.
gcc-test regression tests, derived from gcc-testsuite; (part of GCC)
packihx; (public domain)
makebin; (zlib/libpng License)

SDCC C compiler was originally written by Sandeep Dutta. Some of


the features include:
o MCU specific language extensions, allowing effective use of the
underlying hardware.
o standard optimizations such as global sub expression elimination,
loop, constant folding and propagation, copy propagation, dead code
elimination and jump tables for 'switch' statements.
o MCU specific optimizations, including a global register allocator.
o adaptable MCU backend that is well suited for other 8 bit MCUs
o full range of data types: char (8 bits, 1 byte), short (2 bytes), int (2
bytes), long (4 bytes), float (4 byte) and_Bool; support for long (8
bytes) data types for the z80, z180, r2k, r3ka, gbz80, hc08 targets.
o ability to add inline assembler code anywhere in a function.
o ability to report on the complexity of a function to help decide what
should be re-written in assembler.
239
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

A new release of SDCC (launched in June 2015), the portable optimizing


compiler for 8051, DS390, Z80, Z180, Rabbit 2000, HC08, STM8 and
PIC microprocessors is now available at (http://sdcc.sourceforge.net/).
Sources, documentation and binaries compiled for x86 Linux, x86 and
x64 MS Windows and x86 and Mac OS X are available. SDCC is known
to compile from the source code also on the following platforms:

Linux - x86_64
Linux - Alpha
Linux - IBM Power5
NetBSD - i386
NetBSD - Sparc64
FreeBSD - i386
SUN Solaris - i386
SUN Solaris - Sparc
Rasbian (Debian for Raspberry Pi) - ARMv6
Debian - ARMv7-a

The latest development source code can be accessed using the following
link: http://svn.code.sf.net/p/sdcc/code/trunk/sdcc

240
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-4. PIC Programming with mikroC


The mikroC is a powerful development tool for PIC microcontrollers
(especially PICmicro). It is designed to provide the programmer with the
easiest possible solution for developing applications for embedded
systems. mikroC provides a successful match featuring highly advanced
IDE, ANSI compliant compiler, broad set of hardware libraries,
comprehensive documentation.

7-4. 1. Programming Procedure


Write your C source code using the built-in Code Editor (Code and
Parameter Assistants, Syntax Highlighting, Auto Correct, and more…)
Use the included mikroC libraries to speed up development: data
acquisition, memory, displays, communications… all P12, P16, and P18
chips are supported.
Monitor your program structure, variables, and functions in the Code
Explorer.
Generate commented, readable assembly and standard HEX for all
programmers.
Inspect program flow and debug executable with the integrated
Debugger.

For the matter of illustration, let’s look at the following simple C-source
program, which is written for PIC16 microcontrollers
/* *************************************************************
Program to output a binary count to Port B LEDs
************************************************************* */
#include <p18f458.h> /* Include port labels for this chip */
#include <delays.h>

int counter /* Label a 16-bit variable location */


void main(void) /* Start main program sequence */
{
counter = 0; /* Initialize variable value */
TRISB = 0; /* Confi gure Port B for output */
while (1) /* Start an endless loop */
{
PORTB = counter; /* Output value of the variable */
Counter++; /* Increment the variable value */
Delay10KTCY(100); /* Wait for 100 x 10,000 cycles */
}
} /* End of program */

The block comment enclosed between /* and */. The first line in the c-
code is a compiler directive which calls up a header file named
―p18F458.h‖. This contains predefined register labels for that particular
processor, such as TRISB and PORTB, and the corresponding addresses.
The following lines are the rest of c-program. Each complete statement is
241
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

terminated with a semicolon; For instance, the statement


int counter;
assigns a label variable (called counter) to a register location and declares
that it will store an integer, or whole number. The subsequent statement
void main(void)
indicates, as far as we are concerned here, the start of the main program
sequence. The following brace (curly bracket) encloses the main program
with a matching brace at the end. These are lined up in the same column
and the main program tabbed in between them, so that they can be
matched up correctly. The delay function is an example of a function call,
which is one of the advantages of C—the collection of standard routines.

7-4. 2. mikroC Language Specific Limitations


mikroC diverges from the ANSI C standard in few areas. Some of these
modifications are improvements intended to facilitate PIC programming,
while others are result of PICmicro hardware limitations:

Function recursion is supported with limitations because of no easily-


usable stack and limited memory.
Pointers to variables and pointers to constants are not compatible, i.e. no
assigning or comparison is possible between the two.
mikroC treats identifiers declared with const qualifier as ―true constants‖
(C++ style). If aiming at portability, use the traditional preprocessor
defined constants.
mikroC allows C++ style single–line comments using two adjacent
slashes (//).
A number of standard C libraries (ctype, math, stdlib, string) have been
implemented; check the individual functions for divergence.
Anonymous structures and unions are unsupported at present.

For the matter of demonstration, let us present the above specific features
and limitations of microC in details. For instance, certain sections of the
ANSI standard have been implemented with defined behavior.

i. Floating-point Types
Types float and double, together with the long double variant, are
considered floating-point types. mikroC’s implementation of ANSI
Standard considers all three to be the same type. Floating point in mikroC
is implemented using the Microchip AN575 32-bit format (IEEE 754
compliant). The following table shows the floating-point types:
242
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Type Size in bytes Range


±1.17549435082 * 10-38 ..
float 4
±6.80564774407 * 1038
±1.17549435082 * 10-38 ..
double 4
±6.80564774407 * 1038
±1.17549435082 * 10-38 ..
long double 4
±6.80564774407 * 1038

ii. Storage Classes


Associating identifiers with objects requires each identifier to have at
least two attributes: storage class and type. The mikroC compiler deduces
these attributes from implicit or explicit declarations in the source code.
Storage class dictates the location (data segment, register, heap, or stack)
of the object and its duration or lifetime (the entire running time of the
program, or during execution of some blocks of code). Storage class can
be established by the syntax of the declaration, by its placement in the
source code, or by both of these factors:
Auto
Use the auto modifer to define a local variable as having a local duration.
This is the default for local variables and is rarely used. You cannot use
auto with globals.
Register
By default, mikroC stores variables within internal microcontroller
memory. Thus, modifier register technically has no special meaning.
mikroC compiler simply ignores requests for register allocation.
Static
Global name declared with static specifier has internal linkage, meaning
that it is local for a given file. Local name declared with static specifier
has static duration. Use static with a local variable to preserve the last
value between successive calls to that function.
Extern
Name declared with extern has external linkage, unless it has been
previously declared with internal linkage. Declaration is not a definition if
it has extern specifier and is not initialized. The keyword extern is
optional for a function prototype. Use the extern modifier to indicate that
the actual storage and initial value of a variable, or body of a function, is
defined in a separate source code module. Functions declared with extern
are visible throughout all source files in a program, unless you redefine
the function as static.
243
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

iii. Bit Fields


Bit fields are specified numbers of bits that may or may not have an
associated identifier. Bit fields offer a way of subdividing structures into
named parts of user-defined sizes. Structures and unions can contain bit
fields. Bit fields can be up to 16 bits. You cannot take the address of a bit
field.

Note: If you need to handle specific bits of 8-bit variables (char and
unsigned short) or registers, you don’t need to declare bit fields. Much
more elegant solution is to use mikroC’s intrinsic ability for individual bit
access. Simply use the direct member selector (.) with a variable,
followed by one of identifiers F0, F1, … , F7, with F7 being the most
significant bit. For example:

// If RB0 is set, set RC0:


if (PORTB.F0) PORTC.F0 = 1;

There is no need for any special declarations


Bit Fields Declaration
Bit fields can be declared only in structures. Declare a structure normally,
and assign individual fields like this (fields need to be unsigned):

struct tag {
unsigned bitfield-declarator-list;
}

Here, tag is an optional name of the structure; bitfield-declarator-list is a


list of bit fields. Each component identifer requires a colon and its width
in bits to be explicitly specified. Total width of all components cannot
exceed two bytes (16 bits).
As an object, bit fields structure takes two bytes. Individual fields are
packed within two bytes from right to left. In bitfield-declarator-list, you
can omit identifier(s) to create artificial ―padding‖, thus skipping
irrelevant bits. For example, if we need to manipulate only bits 2–4 of a
register as one block, we could create a structure:

struct {
unsigned : 2, // Skip bits 0 and 1, no identifier here
mybits : 3; // Relevant bits 2, 3, and 4
// Bits 5, 6, and 7 are implicitly left out
} myreg;
244
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Here is an example:

typedef struct {
prescaler : 2;
timeronoff : 1;
postscaler : 4;} mybitfield;

which declares structured type mybitfield containing three components:


prescaler (bits 0 and 1), timeronoff (bit 2), and postscaler (bits 3, 4, 5, 6).

Bit Fields Access


Bit fields can be accessed in same way as the structure members. Use
direct and indirect member selector (. and ->). For example, we could
work with our previously declared mybitfield like this:

// Declare a pointer to mybitfield type:


mybitfield *TimerControl;
void main() {
TimerControl = (mybitfield *) (void *) &T2CON ; // explicit casting of
pointer to T2CON, so it can be assigned

// Declare a bit field TimerControl:


mybitfield TimerControl;

void main() {
TimerControl.prescaler = 0;
TimerControl.timeronoff = 1;
TimerControl.postscaler = 3;
T2CON = TimerControl;
}

iv. Interrupts
Interrupts can be easily handled by means of reserved word interrupt.
mikroC implictly declares function interrupt which cannot be redeclared.
Its prototype is:

void interrupt(void);

For P18 low priorty interrupts reserved word is interrupt_low:

void interrupt_low(void);

You are expected to write your own definition (function body) to handle
interrupts in your application. mikroC saves the following SFR on
245
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

stack when entering interrupt and pops them back upon return:
PIC12 family: W, STATUS, FSR, PCLATH
PIC16 family: W, STATUS, FSR, PCLATH
PIC18 family: FSR (fast context used to save WREG, STATUS, BSR)

Use the #pragma disablecontexsaving to instruct the compiler not to


automatically perform context-switching. This means that no regiser will
be saved/restored by the compiler on entrance/exit from interrupt service
routine. This enables the user to manually write code for saving registers
upon entrance and to restore them before exit from interrupt.
P18 priority interrupts
For the P18 family both low and high interrupts are supported.
function with name interrupt will be linked as ISR (interrupt service
routine) for high level interrupt
function with name interrupt_low will be linked as ISR for low level
interrupt_low
If interrupt priority feature is to be used then the user should set the
appropriate SFR bits to enable it. For more information refer to datasheet
for specific device.
Function Calls from Interrupt
Calling functions from within the interrupt() routine is now possible. The
compiler takes care about the registers being used, both in "interrupt" and
in "main" thread, and performs "smart" context-switching between the
two, saving only the registers that have been used in both threads.

Interrupt Examples
Here is a simple example of handling the interrupts from TMR0 (if no
other interrupts are allowed):

void interrupt() {
counter++;
TMR0 = 96;
INTCON = $20;
}

In case of multiple interrupts enabled, you need to test which of the


interrupts occurred and then proceed with the interrupt handling code:

void interrupt() {
if (INTCON.TMR0IF) {
counter++;
246
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

TMR0 = 96;
INTCON.TMR0F = 0;
}
else if (INTCON.RBIF) {
counter++;
TMR0 = 96;
INTCON.RBIF = 0;
}
}

v. Built-in Routines
mikroC compiler provides a set of useful built-in utility functions. Built-
in functions do not require any header files to be included; you can use
them in any part of your project. Built-in routines are implemented as
―inline‖; i.e. code is generated in the place of the call, so the call doesn’t
count against the nested call limit. The only exceptions are Vdelay_ms,
Delay_Cyc and Get_Fosc_kHz which are normal C routines.
Delay_us
Prototype void Delay_us(const time_in_us);
Returns Nothing.
Description Creates a software delay in duration of time_in_us
microseconds (a constant). Range of constants depends on
the oscillator frequency. This is an ―inline‖ routine; code is
generated in the place of the call, no limit for nested call.
Example Delay_us(10); /* Ten microseconds pause */

Delay_ms
Prototype void Delay_ms(const time_in_ms);
Returns Nothing.
Description Creates a software delay in duration of time_in_ms
milliseconds (a constant). Range of constants depends on
the oscillator frequency. This is an ―inline‖ routine; code is
generated in the place of the call.
Example Delay_ms(1000); /* One second pause */

Vdelay_ms
Prototype void Vdelay_ms(unsigned time_in_ms);
Returns Nothing.
247
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Description Creates a software delay in duration of time_in_ms


milliseconds (a variable). Generated delay is not as precise
as the delay created by Delay_ms. Note that Vdelay_ms is
library function rather than a built-in routine; it is presented
in this topic for the sake of convenience.
Example pause = 1000;
// ...
Vdelay_ms(pause); // ~ one second pause

Delay_Cyc
Prototype void Delay_Cyc(char Cycles_div_by_10);
Returns Nothing.
Description Creates a delay based on MCU clock. Delay lasts for 10
times the input parameter in MCU cycles. Note that
Delay_Cyc is library function rather than a built-in routine;
There are limitations for Cycles_div_by_10 value. Value
Cycles_div_by_10 must be between 3 and 255
Example Delay_Cyc(10); /* Hundred MCU cycles pause */

Clock_Khz
Prototype unsigned Clock_Khz(void);
Returns Device clock in KHz, rounded to the nearest integer.
Description Function returns device clock in KHz, rounded to the
nearest integer.
Example clk = Clock_Khz();

Clock_Mhz
Prototype unsigned short Clock_Mhz(void);
Returns Device clock in MHz, rounded to the nearest integer.
Description Function returns device clock in MHz, rounded to the
nearest integer. This is an ―inline‖ routine;
Example clk = Clock_Mhz();

Get_Fosc_kHz
Prototype unsigned long Get_Fosc_kHz(void);
Returns Device clock in KHz, rounded to the nearest integer.

248
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Description Function returns device clock in KHz, rounded to the


nearest integer. Note that Get_Fosc_kHz is library function
rather than a built-in routine;
Example clk = Clock_Khz();

vi. Creating User's Libraries with mikroC


mikroC allows you to create your own libraries. In order to create a
library in mikroC follow the steps bellow:

Create a new C file, Save the file in compiler's Uses folder(s):

DriveName:\Program Files\Mikroelektronika\mikroC\Uses\P16\
DriveName:\Program Files\Mikroelektronika\mikroC\Uses\P18\

If you are creating library for PIC16 MCU family the file should be saved
in P16 folder.

If you are creating library for PIC18 MCU family the file should be saved
in P18 folder.

If you are creating library for PIC16 and PIC18 MCU families the file
should be saved in both folders.

Write a code for your library and save it.

Open the "mlk" file for the MCU that you want to use. This file is placed
in the compiler's Defs folder:

DriveName:\Program Files\Mikroelektronika\mikroC\Defs\

and it is named PMCU_NAME.mlk, for example P16F877A.mlk

Add the following line in the definition file for the MCU:

#pragma SetLib(Your_Lib_ Name)

Restart the compiler

249
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-5. ARM Programming with C/C++


Since their introduction, the ARM Cortex processors have been adopted
by an increasing number of embedded developers.

MDK Core includes all the components to write, build, and debug an
embedded application for Cortex-M microcontroller devices. The Pack
Installer manages Software Packs that can be added any time to MDK
Core. This makes new device support and middleware updates. Software
Packs contain device support, CMSIS libraries, middleware, board
support, code templates, and example projects. The Cortex
Microcontroller Software Interface Standard (CMSIS) provides a
software framework for embedded applications that run on Cortex-M
based microcontrollers.

Figure 7-10. The MDK core components and software packs.

MDK provides the tools and the environment to create and debug
applications using C/C++ or assembly language and is available in
various editions. Each edition includes the μVision IDE, debugger,
compiler, assembler, linker, libraries, and CMSIS-RTOS RTX. Keil
MDK Version 5 is the latest release of software development
environment for a wide range of ARM, Cortex-M, and Cortex-R based
microcontroller devices. The Keil Microcontroller Development Kit
(MDK) includes the µVision IDE/Debugger, ARM C/C++ Compiler, and
middleware components.
You can download MDK-ARM v5 from www.keil.com/download
With the exception of MDK-Lite version, which is dedicated for
evaluation and student projects, the MDK editions require activation
using a license code.
250
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-5.1. ARM C-Compilers


The ARM Compiler is specifically designed to optimize software running
on ARM processors. It is the result of 20 years of development alongside
the ARM Architecture. The ARM Compiler toolchain incorporates a
highly optimizing C/C++ compiler, assembler, linker and libraries for
embedded software development.

The ARM C Compiler (ARMCC) features full support for C90, C99 and
C++2003 with optimized routines for ARM and Thumb-2 which can
greatly improve the performance of your code

When using the Keil tools, the project development cycle is similar to any
other software development project.

1. Create a project, select the target device from Device Data base, and
configure the tool settings
2. Create your source files in C/C++ or Assembly
3. Build your application with the Project Manager
4. Debug and correct errors in source files, verify and optimize your
application
5. Download your code to Flash ROM or SRAM and test application.

Figure 7-11. The project development cycle.

251
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-5.2. C-Coding Hints for ARM Cortex-M3


The Cortex-M3 processor provides a number of special instructions to
increase the performance in data processing, for example, bit field insert,
saturation and endian conversion for data. Some of these instructions can
be generated by the C compiler using idiom recognitions. A few
examples of Idiom recognitions on C source code are shown in the
following table:

Instruction C language
BFI /* recognised BFI r0,r1,#8,#9 */
int bfi(int a, int b)
{
return (a & ~0x1FF00) | ((b & 0x1FF) << 8);
}
USAT /* recognized USAT r0,#8,r0 */
int usat(int x) {
return (x < 0) ? 0 : (x > 255 ? 255 : x);
}
SSAT /* recognized SSAT r0,#9,r0 */
int ssat(int x) {
return (x < -256) ? -256 : (x > 255 ? 255 : x);
}

The intrinsic functions provided by the compiler can also be used to


generate other special instructions that cannot be generated by a compiler
in normal C code.

Instruction Examples of C intrinsic function


WFI void __wfi(void); // Wait for interrupt
WFE void __wfe(void); // Wait for event
RBIT unsigned int __rbit(unaigned int val); // Reverse bit
REV unsigned int __rev(unaigned int val); // Reverse byte order

When programming a microcontroller, in C-language, the following notes


are very important, for all microcontroller architectures.
*Apply the volatile attribute on variables that are modified by an
interrupt, hardware peripherals, or other RTOS tasks. The volatile
attribute prevents the C/C++ compiler from optimizing variable access.
By default, a C/C++ Compiler may assume that a variable value will
remain unchanged between several memory-read operations. This may
yield incorrect application behavior in real-time applications.
252
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

*When possible, use automatic variables for loops and other temporary
calculations. When possible, use automatic variables for loops and other
temporary calculations.
*Keep interrupt functions short. Well-structured interrupt functions only
perform data collection and/or time-keeping. Data processing is done in
the main function or by RTOS task functions. This reduces overhead
involved with context save/restore of interrupt functions

When possible, make use of the following notes, when using the ARM-C
compiler, with ARM Cortex-M3 microcontrollers.

*Use 32-bit data types for automatic and parameter variables.


Parameter passing is performed in 32-bit CPU registers. All ARM
instructions operate on 32-bit values. In Thumb mode, all stack
instructions operate only on 32-bit values. By using 32-bit data types
(signed/unsigned int/long), additional data type cast operations are
eliminated.

*Use the Thumb instruction set.. Thumb mode is about 65% of the code
size and 160% faster than ARM mode when executing from a 16-bit
memory system. The MDK-ARM Compiler automatically inserts
required ARM / Thumb interworking instructions.

*Enhance struct pointer access by placing scalars at the beginning and


arrays as subsequent struct members. Thumb and ARM instructions
encode a limited displacement for memory access. When a struct is
accessed via a pointer, scalar variables at the beginning of a struct can be
accessed directly. Arrays always require address calculation.
Consequently, it is more efficient to place scalar variables at the
beginning of a struct.

*Assign high speed interrupt code to RAM. Code executed from Flash
ROM typically requires wait states or CPU stalls. Code execution from
RAM does not. Consequently, time critical functions (like high-speed
interrupt code) can be located in RAM directly using the Memory
Assignment feature in Options for File – Properties available via the
Context Menu of that file.

*Use MicroLIB. The compiler offers a MicroLIB to be used for further


reducing the code size of an application. MicroLIB is tailored for deeply
embedded systems, but is not fully ANSI compliant. Do not use
MicroLIB when execution speed is your primary goal.
253
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

*Optimize for Speed and size. To optimize an application for maximum


execution speed, under Options for Target select the following
toolchain: In the dialog page C/C++ select Optimization

254
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-6. C-Code Comparisons (x51, PIC, ARM)


There exist some differences in C-language syntax for different micro-
controllers. For instance, let us look at the I/O Port Access methods and
interrupt handling in x51, PIC and ARM microcontrollers.

7-6.1. I/O Ports


8051 devices provide bit-addressable I/O Ports and instructions to access
fixed memory locations directly. C166, XE166, XC2000 devices provide
bit-addressable I/O Ports and instructions to access fixed memory
locations directly. On the other hand, ARM7 and ARM9 devices provide
indirect memory access instructions only. However, there are no bit
operations. Alternatively, Cortex-Mx devices provide indirect memory
access instructions only, but allow atomic bit operations. The following
table shows a comparison about an I/O instruction, which increments a
value (i) when an I/O pin is set.
Source Code Description
if (IO_PIN == 1) {
i++;
}

7-6.2. Pointer Access Comparison


8051 devices provide byte arithmetic requiring several microcontroller
instructions for address calculation. C166, XE166, XC2000 devices
provide efficient address arithmetic with direct support of a large 16
MByte address space. ARM devices are extremely efficient with regard
to pointer addressing and always use the 32-bit addressing mode.

255
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

In Cortex-Mx devices, any register can be used as a pointer to data


structures and arrays. The following table shows a comparison about a
pointer instruction, which return a value that is part of a struct and
indirectly accessed via pointer.

typedef struct { int x; int arr[10]; } sx;


int f(sx xdata *sp, int i) {
return sp->arr[i];
}

7-6.3. Interrupt Handling Comparison


One significant difference between the various microcontroller
architectures is the balance between hardware and software in interrupt
handling.
PIC18 devices (with the priority scheme enabled) have two interrupt
vectors. All high-priority interrupts are assigned to one vector; all low-
priority interrupts to the other. Each interrupt handler is responsible for
determining which of the possible sources has raised an interrupt
(Interrupt Flag bits must be checked to work this out). Once the source is
identified, a specific handler can be involved to handle the event.
The nested vector interrupt controller (NVIC) on Cortex-M3 devices
handles all this interrupt issues automatically. All interrupt sources have
separate vectors defined in a vector table. In parallel with saving context
on the stack, the NVIC reads the relevant vector address from the table
and directs program execution directly to the start of the correct handler.
256
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Interrupt handler routines for PIC devices must be identified in C source


code using a

#pragma directive.

When writing interrupt handlers in PIC assembler, there are constraints


(e.g. cannot access arrays using calculated index, call other functions and
access ROM variables etc). These must be followed for correct operation.
If the interrupt priority scheme is not used only one handler is required;
two are required if the priority scheme is used. The interrupt handlers
must be installed by putting a GOTO instruction at the vector location.
Typically this is done with a short section of inline assembler within the
C application. If the priority scheme is used, two vectors are required.

Cortex-M3 interrupt handlers are standard C functions and there are no


special C coding rules for them. The vector table is typically defined by
an array of C function pointers. This is then located at the correct address
by the linker.
The examples below show definition of vector tables and placeholders for
exception handlers when writing in C- code. Note that it is possible to
avoid C startup for Cortex-M3 systems completely.

PIC
#include <p18cxxx.h>
void low_isr(void);
void high_isr(void);
/* ****** This will be located at the low-priority interrupt vector at 0x0018*** */
#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
{
_asm
GOTO low_isr
_endasm
}
/* **** return to the default code section and declare interrupt handler ********/
#pragma code
#pragma interruptlow low_isr
void low_isr (void)
{
/* write interrupt handler here */
}
/* ** This will be located at the hi-priority interrupt vector at 0x0018.*********/
#pragma code high_vector=0x08
257
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

void interrupt_at_high_vector(void)
{
_asm
GOTO high_isr
_endasm
}
/* **** return to the default code section and declare interrupt handler *****/
#pragma interrupt high_isr
void high_isr (void)
{
/* write the interrupt handler here */
}

Cortex-M3
/* Filename: exceptions.c */
typedef void(* const ExecFuncPtr)(void);
/* *********** Place table in separate section *********** */
#pragma arm section rodata="vectortable"
ExecFuncPtr exception_table[] =
{
(ExecFuncPtr)&Image$$ARM_LIB_STACKHEAP$$ZI$
$Limit, /* Initial SP */
(ExecFuncPtr)__main, /* Initial PC */
NMIException,
HardFaultException,
MemManageException,
BusFaultException,
UsageFaultException,
0, 0, 0, 0, /* Reserved */
SVCHandler,
DebugMonitor,
0, /* Reserved */
PendSVC,
SysTickHandler,
/* ************ Configurable interrupts from here ************* */
InterruptHandler0,
InterruptHandler1,
InterruptHandler2
:
};
/* *********** One example exception handler **************** */
#pragma arm section
void SysTickHandler(void)
{
printf("---- SysTick Interrupt ----");
}
258
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

In Scatter Control File:


LOAD_REGION 0x00000000 0x00200000
{
;; 256 exceptions (256*4 bytes == 0x400)
VECTORS 0x0 0x400
{
exceptions.o (vectortable, +FIRST)
}
}

Note that all Thumb instructions can execute on the Cortex-M3


processor. However, the legacy SWI (Software Interrupt) instruction has
been renamed to SVC (Supervisor Call), and its associated handler will
require modification (See SWI and SVC section).

259
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-7. Summary

The C compiler converts the program into machine code of the target
microcontroller. Most of the C statements translate into more than one
machine code instruction.
Usually, the main elements of a microcontroller C- program are as
follows.
#include<xxxxxx.h>
void main(void) /* Start main program sequence */
{
while (1) /* Start an endless loop */
{
: /* write instructions to be executed */
}
:
}/* End of program */

Mote that comments in C source code are enclosed between /* and */, and
can be run over several lines.

The Keil Cx51 is a complete implementation of the ANSI standard of C


language for MC51 and compatible microcontrollers. The Cx51compiler
is adapted for the 8051 target. It is a ground-up implementation, dedicated
to generating extremely fast and compact code for the 8051
microprocessor. The Cx51 Compiler provides you with the flexibility of
programming in C and the code efficiency and speed of assembly
language. The C language on its own is not capable of performing
operations (such as input and output) that would normally require
intervention from the operating system. Instead, these capabilities are
provided as part of the standard library. Because these functions are
separate from the language itself, C is especially suited for producing
code that is portable across a wide number of platforms.

The following coding hints are very important, for all microcontroller
architectures.

Keep interrupt functions short. Well-structured interrupt functions only


perform data collection and/or time-keeping. Data processing is done in
the main function or by RTOS task functions. This reduces overhead
involved with context save/restore of interrupt functions.

260
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

Apply the volatile attribute on variables that are modified by an interrupt,


hardware peripherals, or other RTOS tasks. The volatile attribute
prevents the C/C++ compiler from optimizing variable access. By default,
a C/C++ Compiler may assume that a variable value will remain
unchanged between several memory-read operations. This may yield
incorrect application behavior in real-time applications.

When possible, use automatic variables for loops and other temporary
calculations. When possible, use automatic variables for loops and other
temporary calculations.

MDK-ARM offers a website that helps you to learn more about the
programming of ARM Cortex-based microcontrollers. It contains
tutorials, videos, further documentation, as well as useful links to other
websites and is available at www.keil.com/learn.

261
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

7-12. Problems:

7-1) Write a C program to interface the 8255 parallel I/o (PIO) chop to
the ARM microcontrollers

7-2) You want to define an array "myarray" with 20 unsigned bytes. How
could you do that?
a) uint8_t myarray[20];
b) #define myarray[20] uint8_t;
c) uint8_t *myarray[20];
d) uint8_t *myarray;

7-3) Which phrase is accurate?


(a) 8051 has interrupt vector table between 0x0003 and 0x002B
(b) 8051 does not have an interrupt vector table but the vector addresses
for the hardware interrupt ISRs between 0x0003 and 0x002B
(c) ARM processor software interrupts vector table starts from
0x00000008.
(d) 68HC11x hardware interrupts vector table starts from 0xFFFF to
higher memory addresses.

262
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7

263
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Chapter 8: Developing a Microcontroller-Based System

8-1. Developing a Microcontroller System


The first step in developing a microcontroller system, for a specific
application, is to define the system as completely as possible. You will
always think of things as you go along that you left out. After thinking
out the problem, you start by making a flow chart for the sequence of
operations you‟d like to implement. Then, type up the source files that
interpreter these operations and compile them.

As we mentioned so far, the simulator is a way to test your programs


without downloading them to the microcontroller. This means, for our
purposes, you don't have to have an 8051 to learn how to use 8051. The
way you would use it in real life is to write a program, compile it, and
then load it into the simulator. After all the different pieces, of the whole
program, have been tested, you would combine them into one file,
possibly test it again, and then download it to the real microcontroller.
We concentrate our attention here on 8051microcontroller-based systems.
You can go to look at some examples from the last chapter and watch
them in action in an 8051 simulator (like SIM51EM or JSIM or any other
one). However, some routines are dedicated for PIC, Atmel AVR and
ARM microcontrollers.

8-2. Writing the System Software


The prime concern in programming a microcontroller is how many bytes
the program will actually take up inside the microcontroller code
memory, after it's been assembled. So, we'll concentrate our attention, to
learn how to write small but efficient code for the problem you are
solving or the project you're implementing using a microcontroller. Here
we will look at the techniques of writing the code of a complete
microcontroller system. The first phase in developing a new system is to:
i- Define the System and what you want to accomplish with it. You may
divide the whole program into small modules (files) or subroutines, and
define the input/output interface for each routine.
ii- Write all the Subroutines and Functions that will be repeated
throughout the system. When writing software, a common practice is to
decide what functions or routines will be needed to complete the project.
This may include conversion routines, routines to scan different pieces of
the system, or any routine that can be written and then called by either the
operating loop or the interrupt routines.
263
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Typical examples could be a routine to convert binary to decimal, convert


decimal to binary, convert binary to ASCII, and convert decimal to
ASCII. Others might be to get current time, scan an analog point and
convert it to binary, output a character on the serial port, write a character
to an LCD display, read a character from a keyboard, and many others.
By writing each of these routines, and debugging them separately, the
development time is generally reduced. Also, the task of debugging the
final software is simpler, because each of these routines has been
debugged previously and is known to work. In a PC, these routines are
called the BIOS and DOS. BIOS stands for Basic Input/Output System
and DOS stands for Disk Operating System. In the devices we will build
there won't be a disk but there will be an Operating System and BIOS. In
this section we will look at these more closely and start writing them.
The first routine we will write converts binary to decimal. In the
microcontroller, all numbers used are binary, but we usually want to be
able to display them in decimal for easy reading. The following program
(bin2dec.asm) is a binary to decimal conversion routine.
bin2dec: mov b,#100 ;set to divide by 100
div ab ;divide acc by 100
mov R3,a ;move the hundreds digit into R3
mov a,b ;move remainder into acc
mov b,#10 ;set to divide by 10
div ab ;divide acc by 10
mov R4,a ;move the tens digit into R4
mov R5,b ;move the ones digit into R5
ret ;done, exit the routine

It takes a binary number in the accumulator and returns with the decimal
number in R3, R4, and R5. R3 will hold the hundreds digit, R4 the tens
digit, and R5 the units or ones digit. In an 8 bit location, the largest
number is FFH or 255. In order to call this routine, you can add up front
The following program:

.org h'0000 ;start assembly at 0000H


start: mov a,#h'ff ;load a FFH(255) into acc
ACALL bin2dec ;convert to decimal
mov a,#h'64 ;load a 64h(100) into acc
ACALL bin2dec ;convert to decimal
SJMP start ;jump to start

By adding this you can see how a function or subroutine is called by the
operating system. After editing this file and compiling it, start the
simulator and load (read) bin2dec.hex. As before, all the registers are 0's
264
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

to start with. Print out the listing file bin2dec.lst for reference.
Using the listing file is even more crucial here because we are calling a
subroutine. To follow the code window's contents, while single stepping
the program, the listing file is a must.

Notice that there are two labels in this listing. One is the start of the
operating loop and the other is the start of the binary to decimal
subroutine. Also notice that the subroutine ends with a RET instruction.
This instruction is similar to a SJMP except that it returns to the
instruction after the one that called it (ACALL bin2dec). In this way we
can do several binary to decimal conversions with the same routine. Note
that when a subroutine call is performed the stack pointer (SP) register
comes into play to keep track of branching locations. Next we will write a
routine to convert decimal to ASCII. ASCII is used by most display
systems and by the LCD display that we will eventually use. Since as
before, all the numbers used by the microcontroller are binary. We have
written a routine to convert the binary to decimal and now we will
convert that to ASCII so that we can display it on an LCD. The routine
we are going to write will take the 3 digit decimal in R3, R4, and R5 and
return with 3 digit ASCII in R3, R4 and R5. To convert a decimal number
to ASCII, all you have to do is add 30H to it. In other words a decimal 0
is ASCII 30H and a decimal 9 is ASCII 39H.
We will now add this to the previous routine. You can compile it, print
the listing file, start the simulator. You can see that we have added a call
to do the conversion from decimal to ASCII and the decimal to ASCII
routine. Also we changed the two numbers to be converted to FEH (254)
and 7BH (123). We did so to see better the results since each digit is
different. Single step through the instructions and take note of the internal
RAM window at the far right. As the numbers are converted to ASCII,
the area where there are normally a bunch of periods will now show the
ASCII numbers 254 or 123. Following is the dec2asc.asm routine.

dec2asc: mov a,R3 ;get the hundreds digit


add a,#h'30 ;add 30h to it
mov R3,a ;move it back into R3
mov a,R4 ;get the tens digit
add a,#h'30 ;add 30h to it
mov R4,a ;move it back into R4
mov a,R5 ;get the ones digit
add a,#h'30 ;add 30h to it
mov R5,a ;move it back into R5
ret ;done, return
265
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

There are many more routines to write, but the time is getting near where
we need some hardware to experiment with. In this section you've seen
how an operating system operates and how we write subroutines to be
used by the operating loop. The loop in our example began at start and
looped at the end back to start. In the finished operating loop there will be
a lot more code and many more subroutines, but the concept is identical
to our examples.

8-3. Building a Prototype


In a typical system there are various parts, the choice of which depends
on what the design goal of the system is. There must be a power supply
for the system, and a connector to take all the pins of the microcontroller
off of the basic board so that they can be connected to a breadboard to
allow us to connect up whatever we want to the microcontroller. There
will also be a serial interface to allow the downloading of the program
into the microcontroller. There also must be an oscillator to supply the
microcontroller with a clock source. To permit troubleshooting problems,
we need a way to break out of any program that is currently executing,
and examine various locations in the microcontroller to help in the
debugging process. To view the states of various pins on the
microcontroller we need a logic probe. It's recommended that you start
building your system, using a breadboard to allow connecting any
additional parts. As shown in figure 8-1(a), a breadboard is just a matrix
of holes, with connectors, on 0.1" centers that any component or a chip,
can be plugged into. Wire jumpers can be used to interconnect that chip
to the appropriate microcontroller pins. Such breadboards come in a
variety of sizes and shapes.

Fig. 8-1(a). The breadboard

Breadboards work very well for prototyping of circuits. They allow us to


add things as we go along in our project. The breadboards have a peel off
sticker on the back. You may peel off the covers and stick down these
strips, side by side (not end to end).
266
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Running down each side of the strips are two lines of connections that are
normally used for power buses. We normally use the outside bus on
either side as the positive (VCC) and the inside on either side as the
negative (GND) bus. This means that down each side of each breadboard
you will have both a VCC and a GND bus, side by side. The following
figure depicts the breadboard back connections. The chips are plugged in
straddling the divider running down the middle. This means that half of
the pins will be plugged into one side of the divider and the other half
will be plugged into the other side of the divider. Where the letter "J" is,
this is where the power busses are jumpered so that they become two
single busses that run the length of the breadboard.

----- ----- ----- ----- ----- J ----- ----- ----- ----- ----- VCC
BUS
----- ----- ----- ----- ----- J ----- ----- ----- ----- ----- GND
BUS
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DIVIDER
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
----- ----- ----- ----- ----- J ----- ----- ----- ----- ----- GND
BUS
----- ----- ----- ----- ----- J ----- ----- ----- ----- ----- VCC
BUS

Fig. 8-1(b). The Backside of the breadboard.

Now let's start explaining all the above stuff in further detail. First, all
microcontrollers need a system clock to drive them. Clock is a square
wave oscillator that produces pulses with a very stable frequency. These
pulses are either generated inside the microcontroller or applied on its
clock-input pin.

Next we need a serial interface that allows us to download a program to


the microcontroller. This is implemented with a serial driver chip, like the
Maxim MAX232 chip or the Dallas DS275. You may also need analog to
digital converter (ADC), like ADC0808 or ADC0804, to control analog
inputs. An example of an analog input is a temperature, or a pressure. In
order to collect such analog signals you need a sensor. Another example
of analog input could be the voltage of a battery or the light intensity to
determine when it's night or day. A microphone signal is also an example
of analog input. Another device we usually use in microcontroller
applications is the liquid crystal display (LCD). The LCD takes an

267
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

ASCII1 number and displays it. This is why we wrote a binary to ASCII
routine in a previous section. This display can be used to display the time
or temperature or anything you want displayed. The last thing you may
use called X10 protocol, that allow anyone to control different devices
plugged into the 220V house power.

There are also fire alarm sensors, smoking sensors, door sensors,
keypads, infrared motion sensors and many other accessories that you
may need to implement your project. The rest of the parts is a few
resistors, capacitors, transistors, switches, and connectors. Here is a list of
possible projects you can implement, using a microcontroller and a few
number of components:

1. Home security system, with burglar alarm, fire alarm, glass-break


alarm, smoke detectors, etc.

1. Full-featured thermostat to control your heater or air-conditioning, to


save you money in power costs

3. Control of your home appliances and lights, with X-10 devices.

4. Clock/calendar that can be used by all the other functions to add


time/date control functions. For instance the thermostat can adjust the
temperature in your house after you leave for work. Or turn on security
lights at night and turn them off in the morning.

5. Automatic Door access control,

Y ou'll probably think of other uses that are combinations of these or new
ones. All these applications can be purchased off of the shelf at stores, but
the cost is more and you don't get the satisfaction of building and
customizing them to suit your needs. In the next section, we'll recapitulate
the parts list, schematic. We are just about ready to start building a real
hardware project.

1
ASCII (American standard code for information interchange) is a 8-bit code of characters.
268
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-4. Serial Interface Driver Chips.


The serial interface allows us to download a program to the
microcontroller. This is implemented with a serial driver chip, like the
Maxim MAX232 or the Dallas DS275 chips. The MAX232 chip has 2
transmitters and 2 receivers inside it, while DS275 has 1 transmitter and 1
receiver. In logic circuits, we ideally consider a logic 0 as 0V and logic 1
as +5V. However, in real circuits a zero is close to 0 volts and a 1 is close
to the power supply voltage, which is usually +5V in digital circuits. In
the microcontroller specs, a 0 is any voltage less than about 0.8 volts and
typically about 0.1 volts or less and a 1 is any voltage greater than about 2
volts and typically about 4.8V. Levels between 0.8V and 2V are
indeterminate and usually indicate a bad chip or an open circuit.
However, a serial port uses a different set of voltage levels to transmit
and receive data. They conform to the levels set out in the specs for RS-
232C serial interface, where a 0 is close to -5 volts (or lower) and a 1 is
close to +5V (or above).

Fig. 8-2. Serial driver chips, the Maxim Max232 and the Dallas DS275.
269
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

To connect the serial port from a PC to the microcontroller we should


convert these levels from one spec to the other. This is the job of the
serial driver chip MAX232 (or DS275).

As shown in figure 8-2, these chips can take the RS-232 levels from the
PC, through one of its receivers, and convert them to logic levels suitable
to the microcontroller. The serial driver chip can also take logic levels of
the microcontroller, through one of its transmitters, and convert them to
RS-232 levels to the PCAs shown in figure, Serial connection requires 3
wires: a transmit (TX), a receive (RX), and a common ground (GND). To
transmit data out of the microcontroller, the serial port goes to a
transmitting chip (MAX232 or DS275) through a connecting cable and
into the receiver chip of the PC' serial port. To transmit out of a PC, the
serial port goes through a connecting cable to the receiving chip
(MAX232) into the receive terminal of the micro-controller serial port.
The ground or common on the PC serial port is connected to the ground
of the microcontroller. This completes the serial port connections. As
shown, there are 4 external (charge pump) capacitors connected to the
MAX232 chip.

8-5. Connecting Keypad & Keyboards to the Microcontroller


A keypad is a data entry device, which is composed of a set of keys, like
the numbers 0 through 9 and sometimes other control, as shown in Fig. 8-
3. The simplest keypad connection is that of the lead-per-key, as shown in
figure 8-4. If you are using a 16-key keypad, you are looking at around a
16 I/O lines. As soon as number of key is greater than 4, a coded matrix
keypad is more economical in term of I/O used.

Fig. 8-3. Keypad modules.


270
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

To minimize the number of pins required, the keys are arranged in a square matrix as
shown in figure 8-4. For example a 8–key pad arranged as a 4x2 matrix can be
implemented with only 6 port pins (4 columns and 2 rows). We usually connect
column lines to microcontroller inputs whereas row lines are AND‟ed and connected
to one of the microcontroller interrupts (INT), as shown in figure 8-6.

Fig. 8-4. Standard matrix keypad.

VCC

0 Px.0
1 Px.1
:
:
:
: :
: :
9 Px.9
Lead-per-key
MC
Keypad
int

Fig. 8-5. Connecting a lead-per-key keypad to the microcontroller.

271
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Fig. 8-6. Connecting a matrix (coded) keypad to a microcontroller.

8.5.1. Keyboard Algorithm


To detect and decode a key, only 4 interrupt routines are executed: the
keyboard interrupt and the debounce timer routines both when the key is
pressed down and released. A sensible issue when writing routines for
keypad management is the mechanical key bounce. We need a certain
"trick" to smooth digital inputs from switches, or contacts. The process is
called "de-bouncing". It is to remove the bounce from a contact. If you
drop a ball to the floor, it bounces back up and then down again and then
up, each time getting closer to sticking to the floor. After several bounces,
the ball comes to rest on the floor. So, the algorithm must use a debounce
timer to avoid multiple key press detection, as shown in figure below.
The debounce delay depends on the keypad technology (silicon rubber,
mechanical...) and how the keypad is used.

8.5.2. Key press detection


To detect a key, all row inputs are programmed in low level interrupt.
Column outputs are set to a low level. When a key is pressed down, a
keyboard interrupt is generated. Then interrupt is disabled and debounce
timer is launched.

8.5.3. Key release detection


To detect a key release, active row input (the one on which key is
pressed) is programmed in high level interrupt. When the key is released,
272
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

a keyboard interrupt is generated. Then interrupt is disabled and debounce


timer is launched.

8.5.4. Key debounce


As soon as a key press has been detected (via keyboard interrupt), a timer
is started for the debounce delay. When the timer expires, an interrupt is
generated and pressed key decoding is done. Debounce delay can be
easily modified by changing the debounce delay definition in the keypad
header file (keypad.h). In the demonstration software, timer 1 is used to
manage the debounce delay. If the application needs to use the UART,
you can use any other timer than timer 1 for the debounce delay, for
instance timer 0 or an external PCA timer. The following program (in C
language) depicts software driver for the above keypad with Atmel 2051
microcontroller. The program is composed of a main routine (KEY.C) and
4 modules, namely: PUTCHAR.C, KEYPAD.H, SYSTEM.H and
REG251G1.H.

Fig. 8-7. Key ON/OFF behavior and debouncing technique.

The PUTCHAR.C file contains the putchar routine. To avoid character


output on serial port (standart output port) putchar routine is modified to
do nothing. User has to modify this routine depending on its final
application. You can redirect output to an LCD display.

The KEYPAD.H file is the keypad header file and contains constants that
can be adjusted by the user depending on application and keypad type
(e.g. port column, ASCII key table, debounce period, etc.). The
SYSTEM.H file is the system header file and contains constants that can
be adjusted by user depending on application (e.g. oscillator frequency,
interrupt priority, etc.). The REG251G1.H file is the register header file
and contains SFR and BIT addresses for the TSC80251G1 micro-
controller.

273
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

/* *****************************************************************
* 1- KEY.C
* demonstration software for keypad routines
** *****************************************************************/

#include <reg251G1.h> /* special function registers 251G1 */


#include <stdio.h> /* prototype for I/O functions */
#pragma REGISTERBANK (0) /* use Register Bank 0 for coding */
#define SECRET_PIN 3710

extern void kbd_install (void);


extern void t1_install (void);
extern void sys_stop (void);

/** ***************************************************************
main user routine
* *****************************************************************/
void main (void) /* main entry for program */
{
int Pin;
kbd_install();
t1_install();
EA = 1; /* global interrupt enable */
sys_stop(); /* put system in power down */
while (1)
{ /* loop forever */
while (scanf(”%4d”, &Pin) != 1) /* read pin value */
getchar(); /* flush of getchar buffer if number of input != 1 */
if ((getchar() == ‟\n‟) && (Pin == SECRET_PIN))
sys_stop(); /* stop system if pin matches */
}
}/*********************End Main()***********************************/

/* ******************************************************************
2- KEYPAD.C
********************************************************************/
#include <reg251G1.h> /* special function register reg251G1 */
#include <keypad.h> /* define keypad constants */
#include <system.h> /* define system constants */
#pragma iv(0) /* generates interrupt vectors */

bit bdata Key_Hit= 0; /* set to 1 if key pressed */


unsigned char data Last_Key = 0; /* last key pressed value */
char code Key_Table[NB_COL*NB_ROW]=
{K04, K08, K12, K16,
K03, K07, K11, K15,
K02, K06, K10, K14,
K01, K05, K09, K13}; /* keypad is in code area, keys are
define in keypad.h */
274
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

void kbd_install (void);


void t1_install (void);
void sys_stop (void);
char _getkey (void)
void dec_key (char, char);

/*––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
kbd_install – Keyboard install function
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
void kbd_install (void) {
Key_Hit = 0; /* no key pressed */
P_COL |= ~MSK_COL; /* all columns active */
P_ROW |= MSK_ROW; /* no active row */
P1LS = ~MSK_ROW; /* low level int on rows */
P1IE = MSK_ROW; /* enable row int */
P1F = 0; /* no interrupt pending */
IPH1 |= KB_PRIO_H << 0; /* set priority */
IPL1 |= KB_PRIO_L << 0; /* defined in system.h */
KBIE = 1; /* enable Keyboard interrupt */
}
/* –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
t1_install – timer 1 install function
Comments: prepares the debounce timer
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
void t1_install (void) {
TMOD |= 0x10; /* timer 1 in delay mode */
TR1 = 0; /* timer 1 stopped */
IPH0 |= T1_PRIO_H << 3; /* set priority */
IPL0 |= T1_PRIO_L << 3; /* defined in system.h */
ET1 = 1; /* enable timer interrupt */
}
/* ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
** sys_stop – System stop function
** Comments : prepares wake up by ON key and puts
** the microcontroller in power down mode
** ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
void sys_stop (void)
{
KBIE = 0; /* disable interrupt */
P1IE = MSK_KEY_PD; /* enable ON key int */
P1LS = ~MSK_ROW; /* low level int on rows */
P_COL |= MSK_COL; /* only column 0 active*/
P1F = 0; /* no interrupt pending */
KBIE = 1; /* enable interrupt */
PD = 1; /* enter power down mode */
}
/* –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
_getkey – wait a key press and return ASCII key value
–––––––––––––––––––––––––––––––––––– –––––––––––––––––––––––––
275
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

I/O: key pressed value


Comments: _getkey is the low level character input routine for the stream
I/O routines. Default routine reads character from the serial
interface, new routine hereafter reads character from keypad
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
char _getkey (void)
{
while (!Key_Hit);
Key_Hit = 0;
return Last_Key; /* return key pressed */
}
/* –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
** t1_int – Timer 1 interrupt function
** –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
** Comments: test if a key is pressed and decode it
** test is done by shifting a 0 on columns and reading rows
** column 0 is always set to GND and is the first tested
** ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
void t1_int (void) interrupt 3 using 1 {
char row;
TR1 = 0; /* stop timer */
/* here is the key decoding */
P_COL |= MSK_COL; /* only colum 0 activated (always) */
row = P_ROW;
if ((row & MSK_ROW) != MSK_ROW) {
dec_key(row, 0*NB_COL);
}
else
{
COL1 = 0; /* activate column 1 */
row = P_ROW;
if ((row & MSK_ROW) != MSK_ROW) {
dec_key(row, 1*NB_COL);
}
else
{
COL1 = 1;
COL2 = 0; /* activate column 2 */
row = P_ROW;
if ((row & MSK_ROW) != MSK_ROW) {
dec_key(row, 2*NB_COL);
}
else {
COL2 = 1;
COL3 = 0; /* activate column 3 */
row = P_ROW;
if ((row & MSK_ROW) != MSK_ROW) {
dec_key(row,3*NB_COL);
}
276
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

else
{ /* here there is no key pressed */
COL3 = 1;
P_COL &= ~MSK_COL; /* activate all colums */
Key_Hit = 0; /* no key pressed */
P1LS = ~MSK_ROW; /* low level int on all rows */
P1IE = MSK_ROW; /* enable all rows interrupt */
}
}
}
}
KBIE = 1; /* enable Keyboard interrupt */
}
/** –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
** kbd_int – Keyboard interrupt function
** Comments: launches the debounce timer
** –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
*/
void kbd_int (void) interrupt 8 using 1
{
KBIE = 0; /* disable Keyboard interrupt */
P1IE = 0; /* disable row interrupts */
P1F = 0; /* no interrupt pending */
TL1 = KB_TEMPO;
TH1 = KB_TEMPO >> 8; /* prepare debounce delay */
TR1 = 1; /* launches timer */
}
/*–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
* dec_key – Key decoding function
** Inputs: row: a value from 1, 2, 4, 8
** col: a value from 0 to 3*NBCOL
** Outputs: Last_Key: set to decoded key
** ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
** Comments: decodes the key pressed with its row and column
** prepares interface to detect key release: interrupt on high level
** –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
*/
void dec_key (char row, char col)
{
row = ~row & MSK_ROW;
P1LS = row; /* high level int on key row */
P1IE = row; /* enable only key row interrupt */
while ((row >>= 1) != 0) col++;
Last_Key = Key_Table[col]; /* read key value */
Key_Hit = 1;
}

277
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

/********************************************************************
3- PUTCHAR.C
** ––––––––––––––––––––––––––––––––––––––––––––––––––––
** Comments: This file contains the low level character
output routine for the stream I/O routines
** –––––––––––––––––––––––––––––––––––––––––––––––––––
** ––––––––––––––––––––––––––––––––––––––––––––––––––––
** putchar – send a character to the standard output
** ––––––––––––––––––––––––––––––––––––––––––––––––––––
** Inputs: char to output
** Outputs: char output
** ––––––––––––––––––––––––––––––––––––––––––––––––––––
** Comments: putchar is the low level character output
routine for the stream I/O routines. Default routine
sends character to the serial interface, new routine
hereafter does nothing
** ––––––––––––––––––––––––––––––––––––––––––––––––––––
*/

char putchar (char c)


{
return (c);

}/*****************************************************/

/********************************************************************
4- KEYPAD.H
––––––––––––––––––––––––––––––––––––––––––––––––––––––
This file contains the keypad definitions
––––––––––––––––––––––––––––––––––––––––––––––––––––––
*/
#ifndef _KEYPAD_H_
#define _KEYPAD_H_
#include <system.h> /* define system constants */
/* Keypad arrangement

K01–––K02–––K03–––K04 ––– Row0


: : : :
K05–––K06–––K07–––K08 ––– Row1
: : : :
K09–––K10–––K11–––K12 ––– Row2
: : : :
K13–––K14–––K15–––K16 ––– Row3
: : : :
: : : –––––––– Col 0
: : –––––––––––--– Col 1
: –––––––––––––––––––– Col 2
–––––––––––––––––––––––––– Col 3
*/

278
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

#define P_ROW P1 /* row port always P1 */


#define MSK_ROW 0x0F /* mask for rows: 00001111 */
#define NB_ROW 4 /* number of rows */
#define P_COL P1 /* columns port */
sbit COL1 = P1 ^ 4; /* col 0 set to 0 */
sbit COL2 = P1 ^ 5;
sbit COL3 = P1 ^ 6;
#define MSK_COL 0x70 // mask columns: 01110000
#define NB_COL 4 // number of columns */
#define DEBOUNCE_PER 10 // debounce period(ms) max65
#define KB_TEMPO (65535–(DEBOUNCE_PER*(FOSC/12)))
#define MSK_KEY_PD 0x01 // mask ON key row:00000001
#define K01 0x31
#define K02 0x32
#define K03 0x33
#define K04 0x4F
#define K05 0x34
#define K06 0x35
#define K07 0x36
#define K08 0x4D
#define K09 0x37
#define K10 0x38
#define K11 0x39
#define K12 0x43
#define K13 0x2A
#define K14 0x30
#define K15 0x23
#define K16 0x0A
#endif // _KEYPAD_H_
// pca (External programmable Counter array)
sfr CCON = 0xD8;
sfr CMOD = 0xD9;
sfr CL = 0xE9;
sfr CH = 0xF9;
sfr CCAPM0 = 0xDA;
sfr CCAPM1 = 0xDB;
sfr CCAPM2 = 0xDC;
sfr CCAPM3 = 0xDD;
sfr CCAPM4 = 0xDE;
sfr CCAP0L = 0xEA;
sfr CCAP1L = 0xEB;
sfr CCAP2L = 0xEC;
sfr CCAP3L = 0xED;
sfr CCAP4L = 0xEE;
sfr CCAP0H = 0xFA;
sfr CCAP1H = 0xFB;
sfr CCAP2H = 0xFC;
sfr CCAP3H = 0xFD;
sfr CCAP4H = 0xFE;

279
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

/* power management */
sfr PCON = 0x87;
sfr PFILT = 0x86;
sfr CKRL = 0x8E;
sfr POWM = 0x8F;

/* sslc */
sfr SSCON = 0x93;
sfr SSCS = 0x94;
sfr SDAT = 0x95;
sfr SSADR = 0x96;
sfr SSBR = 0x92;

/* keyboard */
sfr P1LS = 0x9C;
sfr P1IE = 0x9D;
sfr P1F = 0x9E;

/* watchdog */
sfr WDTRST = 0xA6;

/* BIT REGISTERS––––––––––––– */

/* PSW */
sbit CY = 0xD7;
sbit AC = 0xD6;
sbit F0 = 0xD5;
sbit RS1 = 0xD4;
sbit RS0 = 0xD3;
sbit OV = 0xD2;
sbit UD = 0xD1;
sbit P = 0xD0;

/* TCON */
sbit TF1 = 0x8F;
sbit TR1 = 0x8E;
sbit TF0 = 0x8D;
sbit TR0 = 0x8C;
sbit IE1_ = 0x8B;
sbit IT1 = 0x8A;
sbit IE0_ = 0x89;
sbit IT0 = 0x88;

/* T2CON */
sbit TF2 = 0xCF;
sbit EXF2 = 0xCE;
sbit RCLK = 0xCD;
sbit TCLK = 0xCC;
sbit EXEN2 = 0xCB;

280
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

/*******************************************************************
7.5. SYSTEM.H
**––––––––––––––––––––––––––––––––––––––––––––––––––––––
** Comments: This file contains the system definitions
**––––––––––-––––––––––––––––––––––––––––––––––––––––––-
*********************************************************
/

#ifndef _SYSTEM_H_
#define _SYSTEM_H_

#define FOSC 12000 /* oscillator frequency (KHz) */


#define KB_PRIO_H 0
#define KB_PRIO_L 0 /* keyboard priority= 0 */
#define T1_PRIO_H 0
#define T1_PRIO_L 0 /* timer 1 priority= 0 */
#endif /* _SYSTEM_H_ */

/*******************************************************************
7.6. REG251G1.H
Comments: This file contains the registers definition
for the Atmel TSC8x251G1 microcontroller
********************************************************/
#ifndef _REG251G1_H_
#define _REG251G1_H_
sfr P0 = 0x80; sfr P1 =0x90;
sfr P2 =0xA0; sfr P3 =0xB0;
sfr ACC = 0xE0; sfr B = 0xF0;
sfr PSW = 0xD0; sfr PSW1 = 0xD1;
sfr SP = 0x81; sfr SPH = 0xBE;
sfr DPL = 0x82; sfr DPH = 0x83;
sfr DPXL = 0x84;
sfr IE0 = 0xA8;
sfr IPL0 = 0xB8; sfr IPH0 = 0xB7;
sfr IE1 = 0xB1; sfr IPL1 = 0xB2;
sfr IPH1 = 0xB3; sfr WCON = 0xA7;
sfr TCON = 0x88; sfr TMOD = 0x89;
sfr TL0 = 0x8A; sfr TL1 = 0x8B;
sfr TH0 = 0x8C; sfr TH1 = 0x8D;
sfr T2CON = 0xC8; sfr T2MOD = 0xC9;
sfr RCAP2L = 0xCA; sfr RCAP2H = 0xCB;
sfr TL2 = 0xCC; sfr TH2 = 0xCD;
sfr SCON = 0x98; sfr SBUF = 0x99;
sfr SADDR = 0xA9; sfr SADEN = 0xB9;
sfr BRL = 0x9A; sfr BRDCON = 0x9B;
sbit PD = PCON^1; sbit IDL = PCON^0;
sbit SSIE = IE1^5; sbit KBIE = IE1^0;
sbit IPHC =IPH0^6; sbit IPHT2= IPH0^5;
sbit IPHS = IPH0 ^ 4;
281
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

sbit IPHT1 = IPH0 ^ 3;


sbit IPHX1 = IPH0 ^ 2;
sbit IPHT0 = IPH0 ^ 1;
sbit IPHX0 = IPH0 ^ 0;
sbit IPHSS = IPH1 ^ 5;
sbit IPHKB = IPH1 ^ 0;
sbit IPLSS = IPL1 ^ 5;
sbit IPLKB = IPL1 ^ 0;
#endif /* _REG251G1_H_ */

282
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-6. Connecting a Display to the Microcontroller


The display unit plays the role of output device in the microcontroller
system. There exist so many types of compact display devices that are
usually connected to microcontrollers, namely:

 Simple light emitting diodes (LED)


 7-Segment displays
 Bar-Graphs
 Alphanumeric Liquid-crystal Displays (LCD)

8-6.1. Adding a 7-Segment Display to the Microcontroller


The 7-segment display is found in many household appliances and
electronic apparatus, such as microwave ovens, toasters, VCRs and
occasionally in cassette recorders. The 7-segment module is just 7 LEDs
that have been combined into one case to make a convenient device for
displaying numbers and some letters. The display, with its pin-out
diagram, is shown below, in figure 8-8.

Fig. 8-8. The 7-segment display and its pin-out diagram.

The above version is called "common anode 7-segment display". That


means that the positive leg of each LED is connected to a common point
which is pin 3 in this case. Each LED has a negative leg that is connected
to one of the pins of the device. To make it work you need to connect pin
3 to 5 volts. Then to make each segment light up, connect the ground pin
for that led to ground.
283
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

A resistor is required to limit the current. Rather than using a resistor


from each LED to ground, you can just use one resistor from VCC to pin
3 to limit the current.

The following table shows how to form the numbers 0 to 9 and the letters
A, b, C, d, E, and F on a 7-segment display. '0' means that pin is
connected to ground (GND). '1' means that pin is connected to Vcc.

Table 8-1. The 7-segment code.

a (Pin 1) b (Pin 10) c (Pin 8) d (Pin 6) e (Pin 5) f (Pin 2) g (Pin 9)


0 0 0 0 0 0 0 1
1 1 0 0 1 1 1 1
2 0 0 1 0 0 1 0
3 0 0 0 0 1 1 0
4 1 0 0 1 1 0 0
5 0 1 0 0 1 0 0
6 0 1 0 0 0 0 0
7 0 0 0 1 1 1 1
8 0 0 0 0 0 0 0
9 0 0 0 1 1 0 0
A 0 0 0 1 0 0 0
b 1 1 0 0 0 0 0
C 0 1 1 0 0 0 1
d 1 0 0 0 0 1 0
E 0 1 1 0 0 0 0
F 0 1 1 1 0 0 0

The following circuit shows you how to add two 7-segment display
modules and a 2-keys keypad to your microcontroller project. The
circuit demonstrates simple counting down clock. S1 is used for setting
time to 99, S2 for start count down.

284
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Fig. 8-9. Controlling two 7-sgment modules with two-keys keypad.

The following program (in assembly language) depicts software driver


for the above 7-segment display with Atmel 2051 microcontroller.
;********************************************************************
; 7seg.asm
; Seven Segment Display Driver
;********************************************************************
#INCLUDE "8051EQU.INC" ;include predefined constants
;********************************************************************
.ORG 0H ;locate routine at 00H
AJMP START ;jump to START
;**************** *************************************
.ORG 25H ;locate beginning of rest of program
;******************** **********************************
INITIALIZE: ;set up control registers
MOV TCON,#00H
MOV TMOD,#00H
MOV PSW,#00H
MOV IE,#00H ;disable interrupts
RET
;*************************** ** *********************************
; SUBROUTINES
;********************************* **********************************
DELAYMS: ;1 millisecond delay routine
MOV R7,#00H ;put value of 0 in register R7
LOOPA:
INC R7 ;increase R7 by one (R7 = R7 +1)
MOV A,R7 ;move value in R7 to Accumlator (A)

CJNE A,#0FFH,LOOPA ;compare A to FF (256) If not equal go LOOPA


RET ;return to point where this routine was called
;********************************************************************
DELAYHS: ;half second delay above millisecond delay
MOV R6,#00H ;put 0 in register R6 (R6 = 0)
MOV R5,#002H ;put 2 in register R5 (R5 = 2)
LOOPB:
INC R6 ;increase R6 by one (R6 = R6 +1)
285
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

ACALL DELAYMS ;call routine above. It'll run and return here.
MOV A,R6 ;move value in R6 to A
JNZ LOOPB ;if A is not 0, go to LOOPB
DEC R5 ;decrease R5 by one. (R5 = R5 -1)
MOV A,R5 ;move value in R5 to A
JNZ LOOPB ;if A is not 0 then go to LOOPB.
RET
;****************************** *********************************
DISPLAY_0: ; Display 0 on the Seven Segment Display
MOV P1, #00000001B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;**************************** ********************************
DISPLAY_1: ; Display 1 on the Seven Segment Display
MOV P1, #01001111B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;********************************** ***************************
DISPLAY_2: ; Display 2 on the Seven Segment Display
MOV P1, #00010010B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;******************************************* ********************
DISPLAY_3: ; Display 3 on the Seven Segment Display
MOV P1, #00000110B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;***************************** **********************************
DISPLAY_4: ; Display 4 on the Seven Segment Display
MOV P1, #01001100B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;**************************** ********************************
DISPLAY_5: ; Display 5 on the Seven Segment Display
MOV P1, #00100100B ; P1.7 is on the left and P1.0 on the right
RET ; The B at the end means it is a binary number
;************************************** **********************
DISPLAY_6: ; Display 6 on the Seven Segment Display
MOV P1, #00100000B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;**************************************** *********************
DISPLAY_7: ; Display 7 on the Seven Segment Display
MOV P1, #00001111B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;*************************************** **********************
DISPLAY_8: ; Display 8 on the Seven Segment Display
MOV P1, #00000000B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;********************************************************************
DISPLAY_9: ; Display 9 on the Seven Segment Display
MOV P1, #00001100B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;*****************************************************************
DISPLAY_A: ; Display A on the Seven Segment Display
MOV P1, #00001000B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;*******************************************************************
DISPLAY_b: ; Display b on the Seven Segment Display
MOV P1, #01100000B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;***************************************************************
DISPLAY_C: ; Display C on the Seven Segment Display
MOV P1, #00110001B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary numbe
;*******************************************************************
DISPLAY_d: ; Display d on the Seven Segment Display
286
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

MOV P1, #01000010B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;*******************************************************************
DISPLAY_E: ; Display E on the Seven Segment Display
MOV P1, #00110000B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;********************************************************************
DISPLAY_F: ; Display F on the Seven Segment Display
MOV P1, #00111000B ; P1.7 is on the left and P1.0 on the right.
RET ; The B at the end means it is a binary number
;*******************************************************************
, Main Program
;*******************************************************************
;
START: ;main program (on power up, program starts here)
ACALL INITIALIZE ;set up control registers
LOOP:
ACALL DISPLAY_0 ;Display 0 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_1 ;Display 1 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_2 ;Display 2 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_3 ;Display 3 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_4 ;Display 4 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_5 ;Display 5 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_6 ;Display 6 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_7 ;Display 7 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_8 ;Display 8 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_9 ;Display 9 on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_A ;Display A on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_b ;Display b on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_C ;Display C on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_d ;Display d on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_E ;Display E on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
ACALL DISPLAY_F ;Display F on the seven segment display
ACALL DELAYHS ;go to above routine that causes a delay
AJMP LOOP ;goto LOOP(always jump back to point LOOP)
.END ;end program

The following program (in C- language) depicts the same driver for the
above 7-segment display with Atmel 2051 microcontroller.

/* *****************************************************************
7seg.c * Driving 2-digit 7-segment
287
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Common Anode LED & keypad


******************************************************************* */
#include c:\mc\8051io.h // include i/o header file
#include c:\mc\8051reg.h

#define SetValue 99

extern register char cputick; // cputick was incremented every 10ms


register unsigned char flag1;
unsigned register char sec,digit,buffer[2];
register char key;
char convert[10] = {0x3F, 0x0c,0x76, 0x5e, 0x4d,0x5b, 0x7b,0x0e, 0x7f, 0x5f};

/* ***************************************************************
main()
{
flag1 = 0;
sec = setValue;
timeToBuffer();
serinit(9600); // set timer0 to be 16 bit counter
while(1){
while(cputick < 10)
scanLED();
// execute the following functions every 100ms
cputick = 0;
timeToBuffer();
keyexe();
countdown();
}
} //******************************************************************
scanLED()
{ // Scan 2-digit LED and 2-key switch, if key pressed key=0-1 else key=-1
int i;
digit = 0x02; // scan code 00000010
key = -1;
for( i = 0; i < 2; i++) /* 2-DIGIT scanning */
{
P3 = ~digit; /* send complement[digit] */
P1 = ~buffer[i]; /* send complement[segment] */
delay(1); /* delay 1ms */
P1 = 0xff; /* off LED */
if ((P3 & 0x10) == 0) /* if key pressed P3.4 became low */
key = i; /* save key position to key variable */
digit>>=1; /* next digit */
}
}//***************************************************************

timeToBuffer() // converts binary data in sec to 7-segment pattern


{ buffer[0] = convert[sec%10];
288
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

buffer[1] = convert[sec/10];
} //*****************************************************************

countdown()
{
if ((flag1 & 0x02) != 0)
sec--;
if (sec == 0 )
flag1 &= ~0x02; // clear run bit
} //******************************************************************

keyexe()
{
if (key != -1)
{
switch(key){
case (0): /* key position 0 */
reset(); /* service key 0 */
break;
case (1): /* key position 1 */
run(); /* service key 1 */
}

}
} //******************************************************************

reset()
{
sec = setValue; // reload set value
timeToBuffer();
flag1 &= ~0x02; // stop counting down
} //*****************************************************************

run()
{
if (sec != 0)
flag1 |= 0x02; // start counting down
} //***************************************************************

8-6.2. Connecting LCD.


Another device we frequently use in microcontroller projects is the liquid
crystal display (LCD). Liquid crystal displays do not emit light, but they
reflect it or manipulate it. So, they can display images using very little
power, as compared to LED-based devices. The LCD can display the
entire alphabet and numbers plus some special characters. It takes an
ASCII2 number and displays its equivalent character as a matrix array
(usually 5-by-7 matrix). This is why we need a binary to ASCII routine to
2
289 interchange) is a 8-bit code of characters.
ASCII (American standard code for information

Prof. Dr. Muhammad El-SABA


Introduction to Microcontrollers CHAPTER 8

get ready to use LCD displays. This display can be used to display the
time or temperature or anything you want to display. LCD can display
characters in different fonts such as: 7-segment, 16-segment, and dot
matrix. The simplest LCD has 1 line of 16 characters, each character in a
5x7 matrix.

LCD devices reflect ambient light or reflect a light source placed behind
the LCD (called backlighting). The optical switching action of LCD's can
be observed in three selectable viewing modes: reflective, transflective,
and transmissive.

Reflective LCD: This LCD includes a reflector. The reflector reflects the
polarized ambient light back through the LCD cell. That kind of LCD
exhibits high brightness, excellent contrast, and provides wide viewing
angles. They are suitable for use in battery-operated equipment.
Reflective LCD's can not be backlit. They can be front lighted.

Transflective LCD: This LCD includes a translucent material that


reflects part of the ambient light and transmits backlighting. It is not as
bright as the reflective type and has lower contrast but can be backlit.
Their applications include medical instruments.

Transmissive LCD: This type of LCD's does not incorporate a reflector


but can be backlit.

i. Types of LCD Host Drives:


There are at least 2 types: segment drivers (controllers) and graphic
drivers. The segment controller includes direct and multiplex drivers
which are applied to 7-segment and 16-segment (alphanumeric) displays
while the graphic controller is applied to dot-matrix displays.
1-Segment Controller Direct Drive: In this technique, there is a separate
driver for each segment. Each driver is commonly built into a LCD driver
chip and consists of the CMOS EX-OR gate and a clock source. Direct
drive displays tend to employ several driver chips that take a large space
and are not practical.
2- Multiplex Drive: This is very popular driver. The backplane (BP)
segments of the LCD can be daisy-chained together into a few horizontal
rows. The front-plane (FP) segments are connected to form vertical
columns. Therefore the leads required for connections to the driver are
few. If we say that a certain driver employs ¼ multiplexing, it means that
4 drivers connected to BP1, BP2, BP3, and BP4 drive the backplane of
290
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

the entire display. The number of front-plane drivers is equal to N/4


where N is the number of segments in the entire display. For example, if
we have an LCD with 4 digits, each digit includes 8 segments (7 for a
character and 1 for the decimal point). Then N = 4 x 8 = 32 segments.

ii. Graphic Controller


The controller IC includes a character generator ROM that allows it to
display any of the160 different alphanumeric characters and symbols. The
character is represented by 7-bit character code. ASCII characters are
represented by their ASCII codes. The controller also includes a RAM
generator to allow you to create 8 of your own characters.

Fig. 8-10. A 2-lines 16-character liquid crystal display (2x16 LCD).

8-6.3. Serial and Parallel LCD Drivers


The conventional parallel LCD's has a parallel interface, which is usually
composed of 7-bit data lines and some control wires, as shown in figure.

291
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

10k

Fig. 8-11. A 2-lines 16-character parallel LCD. As shown, there exist 8 data lines,
labeled (D0-D8). The contrast control is provided by connecting Vc to a 10k pot.

Some LCD interfaces can be connected to a microcontroller with a few


pin count and admit reception of data to be displayed. Figure 8-12 depicts
a temperature sensor with LCD display, which is connected via 4 data
bits (D4, D5, D6, D7) and 2 control lines (Enable E, Register Status RS).

Fig. 8-12. Parallel connection of LCD, to a microcontroller, via 4 pins

Serial LCDs are preferable than conventional parallel LCDs, because they
can be connected to the microcontroller, serially, via a few number of
pins. So, you can save the microcontroller I/O pins for other devices, or
you can use a cheap microcontroller with less pin count. However, serial
LCD's are usually so much expensive than parallel LCDs.
292
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Fortunately, one can sometimes turn around this problem by connecting


the LCD to the microcontroller via a serial-to-parallel shift register (like
74LS164), as shown in figures 8-13.

Fig. 8-13.. Serial connection of a liquid crystal display (LCD), to a microcontroller


via a shift register.

Fig. 8-14. 2-wire connection of a liquid crystal display (LCD), to a microcontroller


via a 74LS164 shift register.

8-6.4. Programming the HD44780 LCD Driver


Now we‟ll go into an explanation of a well-known LCD, namely the
Hitachi HD44780, and its host interface. As shown in the figure below,
there exist 11 connections to the LCD, 8 of which are for 7-bit data.
However, only 4 data lines have to be connected for nibble operation. The
other 3 lines are the ones that need explanation. One is the E (enable)
line. This is an active high control line.
293
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Active high means that when this line is low, it is inactive, it is serving no
function. It could have been more accurately named STROBE. This line,
on it's rising edge, strobes data either to or from the data bus. The second
line is the R/W (read/write) line. If this line is high, data is transferred
from the display. If this line is low, data is transferred to the display. The
last line is the RS (register status) line. If this line is high, the display is in
the data mode and if this line is low the display is in the command/status
mode.

Fig. 8-15. Pin-out diagram of the Hitachi HD44780 LCD.

Function pin pin Function

GND 1 16 Not Connected


VCC 2 15 Not Connected
Contrast 3 14 Data Line 7
RS 4 13 Data Line 6
LCD
Read/Writ 5 12 Data Line 5
Enable 6 11 Data Line 4
Data Line 0 7 10 Data Line 3
Data Line 1 8 9 Data Line 2

Fig. 8-16. Pin-out description of the HD44780 LCD

A typical display routine will first read the status of the display to see if it
is busy, and then make a transfer with the display. Data can be written or
READ from the display. I don't normally read data from the display, but
that option is available. Each interaction with the display is prefaced by
reading the display status and waiting until the display isn't busy.

294
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

The concept of waiting until something is ready is due to the fact that the
display is really a dedicated microcontroller that's running its own
program, being a display. When you write a byte to the display, you've
really just handed it off to the microprocessor in the display and now it
goes through its program doing what displays do and eventually showing
us a visual feedback, through looking at the display. This all takes time
for the display to do, so if you start him doing something, in all
likelihood, it will be many microseconds before he will be ready to do
something else. So we wait for the display to get through with anything it
may already be doing, and then tell him something else to do. This holds
true for many of the peripheral chips, like A/D converters, who are
micros themselves with execution times. Notice that this type of interface
is a polling interface, not an interrupt driven interface.

We can't know anything about the status of the display without reading
the status register. There is no way for the display to signal its state to the
microcontroller, except by polling status from the display. To read status
from the display and wait until the display is ready; the following steps
would be taken. Normally the E line will be low, the RS and R/W lines
can be anything, and must be assumed to be wrong, so they are set each
time an operation is required:
1. Set the RS line to a low (status),
2. Set the RW line to high (read),
3. over1: Set the E line high,
4. Read the display,
5. Clear the E line,
6. Test Bit 7 (BF) in the acc and loop to over1
if a one busy,
7. If bit 7 is a zero, the display is ready

Step 1: Sets the display bus for a read operation


Step 2: Sets the display bus for a command/status operation.
Step 3: Enables the display bus.
Step 4: Reads in the status from the display bus into the accumulator
Step 5: Disables the display bus.
Step 6: Tests the READY bit to see if it is 1 and if not, loops back to 3
Step 7: The end of routine.

Here are the actual commands that we will use


setb lcrw
clr lcrs
over1: setb lcde
mov a,p0
clr lcde
jbz acc.7,over1
295
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

The label will be different, but these are the commands that will be used.
There are some mechanical software procedures that must be used with
the HD44780 every time you apply power or reboot (RESET) the system.
First, a sequence of bytes must be written to the display, in a timing
order, to reset the display and set it to the proper system parameters. It
follows a sequence that is described in the Hitachi data sheet for the
HD44780. Following is the actual segment from our software that deals
with the display. There are several subroutines that this initialization uses.
Their description and code follows the initialization routine.

Subroutine: INLCD – This routine initializes the display after power up


or a system reboot. First we initialize the 3 control lines to the display.
inlcd: clr lcrs ;clear rs to set data bus to command
;(write) status mode (read)
clr lcrw ;clear rw to set data bus to write mode
clr lcde ;clear E to disable display bus

The first thing to do is to initialize the display after power up. This is
done by first waiting at least 15 ms after power up. We used 16 (10H) just
to make sure.
mov a,#h'10 ;wait
lcall waitp ;16 milliseconds

The next thing is to write a 38H to the display and wait 5 milliseconds.
The 38H says that we want an 8 bit data bus, a 5X7 font, and a 4 line
display (it is only a 2 line display, but we'll explain that later).

mov p0,#h'38 ;write


lcall strob ;38 to lcd
mov a,#h'05 ;wait
lcall waitp ;5 milliseconds

The next thing is to write a 38H to the display and wait 1 millisecond
lcall strob ; 38 to lcd
mov a,#h'01 ; wait
lcall waitp ; 1 millisecond

The next thing is to write a 38H to the display, actually checking the busy
bit (reading display status). The previous writes to the display were using
instruction timings to wait different amounts of time. This is a
requirement of the display to guarantee that it is initialized. Normally all
transactions with the display are prefaced by reading display status and
waiting until not busy, before actually doing the deed. These are the only
examples where this rule isn't strictly followed.
296
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

mov a,#h'38 ; write 38h to


lcall wclcd ;display

Next output a 0ch to the display. This turns on the display, turns off the
cursor, and sets the cursor to increment (move to the right).
mov a,#h'0c ;write
lcall wclcd ;0c to display

Next output a 01h to the display. This clears the display and places the
cursor at the home position.
mov a,#h'01 ;write
lcall wclcd ;01 to lcd

Next output a 06h to the display. This sets the cursor to increment (move
to the right), and no display shift (characters would move off the left side
of display when too many characters had been displayed).
mov a,#h'06 ;write
lcall wclcd ;06 to lcd

Next output a 10h to the display. This sets the cursor to move, the display
not to shift, but if it did shift, shift to the left.
mov a,#h'10 ;write
lcall wclcd ;10h to lcd
ret

This ends the startup initialization needed for the HD44780. Following
are the subroutines used by the display initialization routine.
Subroutine: WCLCD - This routine writes a command to the display.
This function is used whenever a command is written to the display. The
routine enters with the command in the acc. R7 is used for temporary
storage of the command by the subroutine. When the routine exits, the
data has been transferred.
wclcd: mov r7,a ;save the command in r7
clr lcrs ;set lcd to command
setb lcrw ;set lcd to read
wc001: setb lcde ;set E
mov a,p0 ;read display status
clr lcde ;
clr E
jb acc.7,wc001 ;if busy then doit again
mov a,r7
clr lcrw ;set lcd to write
mov p0,a ;write data to lcd
setb lcde ;set E
clr lcde ;clr E
mov p0,#h'ff ;tristate p0
ret

297
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Subroutine:WAITP - This routine waits for an amount of milliseconds


in acc. Using a clock frequency of 11.0592 Mhz, the loop count value
needs to be an e6h for both 8 bit timers. The following routine enters with
the ACC holding the count in milliseconds that the routine has to wait.
Use R7 for temporary storage of count. The following routine is 2 simple
7-bit counters cascaded together so that each time r6 is decremented to
zero, R5 is decremented once. R6 is the low byte and R5 is the high byte.

waitp: mov r7,a ;save # milliseconds


wtx02: mov r6,#h'e6 ;initialize
mov r5,#h'e6 ;counters
wtx01: djnz r6,wtx01 ;decrement r6 and jump not zero
wtx03: djnz r5,wtx03 ;decrement r5 and jump not zero
djnz r7,wtx02 ;decrement count and jump not zero
ret ;done, return

Subroutine: WDLCD – This routine writes a byte of data to the display.


The following routineis always used to transfer a byte of data to the
display. The routine enters with the acc holding the byte of data. R7 is
used by the subroutine to temporarily store the byte of data. When the
routine exits, the byte of data has been transferred.

wdlcd: mov r7,a ;save the data temporarily in r7

First we initialize the control lines to the display

clr lcrs ;set lcd to command


setb lcrw ;set lcd to read

Next we wait until the display is ready


.
wd001: setb lcde ;set E
mov a,p0 ;read lcd busy
clr lcde ;clr E
jb acc.7,wd001 ;if busy then doit again

We get the data, initialize the control lines

mov a,r7
setb lcrs ;set lcd to data
clr lcrw ;set lcd to write

Write the data to the display

mov p0,a ;write data to port


setb lcde ;set E
clr lcde ;clr E

298
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Any time we write any data out on the data bus (P0) we must always
return them to all 1's when we are done. This keeps the tri-state bus
working properly for the other speakers on the bus.
mov p0,#h'ff ;tri-state p0
ret

Subroutine: STROB - The following routine strobes the E line to the


display.
strob: setb lcde ;set E
clr lcde ;clr E
ret ;

Display Commands
The display is ASCII character based. There are commands to clear the
display, home the cursor, define the cursor, set the cursor to a character
position, and read and write display data.
Command HEX Description
Clear display 01 Clears the display and homes the cursor.
Return home 02 Homes the cursor
Function set 38 Set the data bus to 8bit,4line
display, and 5 X 7 font
Entry mode set 06 Sets the cursor direction to
right with no display shift
Display ON/OFF 0C turns on the display, turns
off the cusor,
no blinking cursor
Cursor / Display 10 Cusor move, no display shift
Set cursor position 80 This is the start of the top
display line
(20 characters)
C0 This is the start of the
second display line "
94 This is the start of the third
display line "
D4 This is the start of the
bottom display line "

Here is how we could send the word "Hi" to the first two character
positions on display line 1 (far left side)
Oneln: mov a,#h'80 ;set cursor to
lcall wclcd ;start of line 1
mov a,#'H' ;mov a ASCII 'H'
lcall wdlcd ;to the display
mov a,#'i' ;mov a ASCII 'i'
lcall wdlcd ;to the display

299
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

The display should now have the letters "Hi" in the first two character
positions of the top line on the display. See the table that describes the
HD44780 instructions in Appendix H.

We give you here an initial test program that will test your display and
output a message to it if it is working. This program is called LCD1.ASM.
If it works, your display should have the message "Hi " in it.

The rest of the display may look weird, but don't worry about that. If the
program doesn‟t work, check your connections. The following LCD1.asm
program is listed below. So, you‟ll be able to modify and write any
characters you wish to any place on the display.

;********************************* **************************** * *
LCD1.ASM
;*******************************************************************
.ORG H'0000 ; START IN RAM FOR DEVELOPMENT (RESET)
RESET: LJMP CONT1 ; JUMP AROUND INTERRUPT VECTORS (RESET)
;*******************************************************************
;INTERRUPTS ;PLACE INTERRUPT ROUTINES
. ORG 03H ;EXTERNAL INTERRUPT 0
RETI
. ORG 0BH ;TIMER 0 INTERRUPT
RETI
. ORG 13H ;EXTERNAL INTERRUPT 1
RETI
. ORG 1BH ;TIMER 1 INTERRUPT
RETI
. ORG 23H ;SERIAL PORT INTERRUPT
RETI
. ORG 2BH ;LOCATE BEGINNING OF REST OF PROGRAM
;*****************************************************************
; HERE BEGIN THE SYSTEM VARIABLES
;*****************************************************************
.ORG H'00
;THIS ALLOWS ACCESS TO REGISTERS W/O SWITCHING PSW TO A BANK
; REGISTER BANK 0
R00: .RS 1 ; BANK 0 REG 0
R01: .RS 1 ; 1
R02: .RS 1 ; 2
R03: .RS 1 ; 3
R04: .RS 1 ; 4
R05: .RS 1 ; 5
R06: .RS 1 ; 6
R07: .RS 1 ; 7
;REGISTER BANK 1

300
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

R10: .RS 1 ; BANK 1 REG 0


R11: .RS 1 ; 1
R12: .RS 1 ; 2
R13: .RS 1 ; 3
R14: .RS 1 ; 4
R15: .RS 1 ; 5
R16: .RS 1 ; 6
R17: .RS 1 ; 7
;REGISTER BANK 2
R20: .RS 1 ; BANK 2 REG 0
R21: .RS 1 ; 1
R22: .RS 1 ; 2
R23: .RS 1 ; 3
R24: .RS 1 ; 4
R25: .RS 1 ; 5
R26: .RS 1 ; 6
R27: .RS 1 ; 7
;REGISTER BANK 3
R30: .RS 1 ; BANK 3 REG 0
R31: .RS 1 ; 1
R32: .RS 1 ; 2
R33: .RS 1 ; 3
R34: .RS 1 ; 4
R35: .RS 1 ; 5
R36: .RS 1 ; 6
R37: .RS 1 ; 7
;*****************************************************************
.ORG H'20
FLAG1: .RS 1
CURLN: .RS 1 ;CURRENT DISPLAY LINE UPDATE POINTER
STACK: ; START OF STACK
;******************************************************************
; EQUATES
;******************************************************************
.EQU LCRS,H'A0 ;LCD RS
.EQU LCRW,H'A5 ;LCD R/W
.EQU LCDE,H'A6 ;LCD E
.CODE ;SWITCH BACK TO CODE SEGMENT
.ORG H'0030 ;START CODE AT HEX 0030
;******************************************************************
START-UP HOUSE KEEPING
;******************************************************************
CONT1: MOV P0,#H'FF ;INITIALIZE
MOV P2,#H'10 ;PORT LINES
MOV R0,#H'02 ;CLEAR
MOV R1,#H'FE;
MOV A,#H'00 ;INTERNAL
CLRM2: MOV @R0,A ;
INC R0 ;RAM
DJNZ R1,CLRM2;
301
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

MOV SP,#STACK-1 ;SET STACK POINTER


MOV MONTH,#D'04 ;
MOV DAYMO,#D'30 ;
MOV YEARS,#D'97 ;
MOV MINUT,#D'59 ;
MOV HOURS,#D'23 ;
MOV DPTR,#H'4100 ;CLEAR
MOV R2,#H'80;
MOV A,#H'20 ;OUT
XFER3: MOVX @DPTR,A;
INC DPTR;DISPLAY
DJNZ R2,XFER3 ;BUFFER
MOV DPTR,#H'410A ;AND
MOV A,#H'2C ;INITIALIZE
MOVX @DPTR,A ;CERTAIN
MOV DPTR,#H'4122 ;CHARACTERS
MOV A,#H'3A ;IN
MOVX @DPTR,A ;BUFFER
MOV DPTR,#H'4125 ;
MOVX @DPTR,A;
MOV DPTR,#H'4180 ;
MOV A,#H'00 ;CLEAR
MOV R2,#H'08 ;OUT
;******************************************************************
; OPERATING LOOP
;******************************************************************
MOV A,#H'80 ;SET TO START OF
LCALL WCLCD ;DISPLAY LINE 1
MOV A,#'H' ;WRITE AN ASCII H
LCALL WDLCD ;TO THE DISPLAY
MOV A,#'I' ;WRITE AN ASCII I
LCALL WDLCD ;TO THE DISPLAY
BEGIN: SJMP BEGIN ;LOOP HERE FOREVER
;*****************************************************************
SUBROUTINES
;*****************************************************************
; THE FOLLOWING ROUTINE INITIALIZES THE DISPLAY
;*****************************************************************

INLCD: CLR LCRS ; SET TO COMMAND/STATUS MODE


CLR LCRW ; SET WRITE TO DISPLAY MODE
CLR LCDE ; TURN OFF DISPLAY DATA BUS
MOV A,#H'10 ; WAIT
LCALL WAITP ; 16 MILLISECONDS
MOV P0,#H'38 ; WRITE
LCALL STROB ; 30 TO LCD
MOV A,#H'05 ; WAIT
LCALL WAITP ; 5 MILLISECONDS
LCALL STROB ; 30 TO LCD
302
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

MOV A,#H'01 ; WAIT


LCALL WAITP ; 1 MILLISECOND
LCALL STROB ; 30 TO LCD
MOV A,#H'38 ; WRITE
LCALL WCLCD ; 38 TO LCD
MOV A,#H'0C ; WRITE
LCALL WCLCD ;0C TO LCD
MOV A,#H'01 ; WRITE
LCALL WCLCD ; 01 TO LCD
MOV A,#H'06 ;WRITE
LCALL WCLCD ; 06 TO LCD
MOV A,#H'10 ; WRITE
LCALL WCLCD ; 10 TO LCD
RET
;*************************************&**************************
; THE FOLLOWING ROUTINE WRITES A COMMAND TO THE DISPLAY
;*****************************************************************
WCLCD:
MOV R7,A
CLR LCRS ;SET LCD TO COMMAND
SETB LCRW ;SET LCD TO READ
WC001:
SETB LCDE ;SET E
MOV A,P0 ;READ LCD BUSY
CLR LCDE;CLR E
JB ACC.7,WC001 ;IF BUSY THEN DOIT AGAIN
MOV A,R7
CLR LCRW ;SET LCD TO WRITE
MOV P0,A ;WRITE DATA TO LCD
SETB LCDE ;SET E
CLR LCDE ; CLR E
MOV P0,#H'FF ;TRISTATE P0
RET
;*****************************************************************
;THE FOLLOWING ROUTINE WAITS FOR A MILLISECONDS IN REG A
;*****************************************************************
WAITP: MOV R7,A ; SAVE # MILLISECONDS
WTX02: MOV R6,#H'E6 ;
MOV R5,#H'E6 ;
WTX01: DJNZ R6,WTX01 ;
WTX03: DJNZ R5,WTX03 ;
DJNZ R7,WTX02 ;
RET
;******************************************************************;
;THE FOLLOWING ROUTINE WRITES A BYTE OF DATA TO THE DISPLAY
;*******************************************************************
WDLCD: MOV R7,A
CLR LCRS ;SET LCD TO COMMAND
SETB LCRW ;SET LCD TO READ
WD001: SETB LCDE ;SET E
303
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

MOV A,P0 ;READ LCD BUSY


CLR LCDE ;CLR E
JB ACC.7,WD001 ;IF BUSY THEN DOIT AGAIN
MOV A,R7
SETB LCRS ;SET LCD TO DATA
CLR LCRW ;SET LCD TO WRITE
MOV P0,A ;WRITE DATA TO PORT
SETB LCDE ;SET E
CLR LCDE ;CLR E
MOV P0,#H'FF ;TRISTATE P0
RET
;*****************************************************************
;THE FOLLOWING ROUTINE STROBES THE E LINE TO THE DISPLAY
;******************************************************************
STROB: SETB LCDE ;SET E
CLR LCD ;CLR E
RET

The following program (LCD2.ASM) is a simple LCD routine that makes


use of only 16 buffer locations to displays one line. It displays “Ain
Shams”. So, you‟ll also be able to modify the program and write any
other characters you wish to any place on the LCD

;**********************************************************
LCD2.ASM Program
;********************************************************************
#INCLUDE "8051EQU.INC" ;include predefined constants
;********************************************************************
; VARIABLES AND CONSTANTS
;The LCD Buffer is 16 memory locations (enough for one LCD line(. To write a line.
; the characters are put in the buffer and then the whole line is written to the LCD.
;********************************************************************
B0 .EQU 070H ; BUFFER POSITION 1
B1 .EQU 071H;
B2 .EQU 072H;
B3 .EQU 073H;
B4 .EQU 074H;
B5 .EQU 075H;
B6 .EQU 076H;
B7 .EQU 077H;
B8 .EQU 078H;
B9 .EQU 079H;
B10 .EQU 07AH;
B11 .EQU 07BH;
B12 .EQU 07CH;
B13 .EQU 07DH;
B14 .EQU 07EH;
B15 .EQU 07FH ; BUFFER POSITION 16
304
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

******************************************************************;
;RESET ;reset routine
. ORG 0H ;locate next command at 00H
AJMP START ;jump to START (first command of program(
*****************************************************************;
;INTERRUPTS ;place interrupt routines at appropriate memory locations
. ORG 03H ;external interrupt 0
RETI
. ORG 0BH ;timer 0 interrupt
RETI
. ORG 13H ;external interrupt 1
RETI
. ORG 1BH ;timer 1 interrupt
RETI
. ORG 23H ;serial port interrupt
RETI
. ORG 2BH ;locate beginning of rest of program
;***************************************************************
Main Program
;***************************************************************
START: ;beginning of main program
MOV SP,#02FH ;initialize stack pointer to 2FH
ACALL INITIALIZE ;initialize registers
ACALL DELAYHS
CLR P3.2 ;make LCD R/W low (Stays low, we just write to LCD)
ACALL LCDSETUP ;initialize LCD
LCDLOOP:
ACALL CLEARDISPLAY ; erase LCD screen
ACALL DELAYHS
ACALL BEGLINEONE ; move cursor to beginning of top line
ACALL WRITEmyMessage
ACALL DELAYHS
AJMP LCDLOOP ; go to LCDLOOP: (repeat)
.END ; end program

;*************************************************************
; Subroutines
;*************************************************************
INITIALIZE: ; set up control registers
MOV TCON,#00H
MOV TMOD,#00H
MOV PSW,#00H
MOV IE,#00H ; disable interrupts
RET
;***************************************************************
DELAYMS: ;millisecond delay routine; uses R7
MOV R7,#00H ;put 00H in register R7
LOOPA :
INC R7 ;increment R7
305
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

MOV A,R7 ;move R7 to Accumlator


CJNE A,#0FFH,LOOPA ;jump to LOOPA if R7 not equal to #FFH
RET ;return
;***************************************************************
DELAYHS: ; half sec delay using milli sec delay uses R5 R6 (R7(
MOV R6,#00H
MOV R5,#002H
LOOPB:
INC R6
ACALL DELAYMS
MOV A,R6
JNZ LOOPB
DEC R5
MOV A,R5
JNZ LOOPB
RET
;***************************************************************
DELAYS: ; delay for a second or two ;uses (R5 R6 R7(
ACALL DELAYHS
ACALL DELAYHS
ACALL DELAYHS
ACALL DELAYHS
RET
;***************************************************************
WRITELCD:
SETB P3.4 ;enable LCD
ACALL DELAYMS ;wait for write completion
CLR P3.4 ;disable LCD
RET
;***************************************************************
EXECUTELCD:
CLR P3.3 ; ditto
SETB P3.4 ; enable LCD
ACALL DELAYMS
CLR P3.4
SETB P3.3 ;Make rs=1
RET
;***************************************************************
LCDSETUP:
MOV P1,#03CH ; set up LCD 8 bits and 1 line x 16 characters
ACALL EXECUTELCD
MOV P1,#00DH ; turn on display and cursor off
ACALL EXECUTELCD
MOV P1,#006H ; set increment one and shift
ACALL EXECUTELCD
MOV P1, #02H ; Home Display
ACALL EXECUTELCD
RET
;***************************************************************
306
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

CLEARBUFFER: ; uses R0
MOV R0,#070H
CBONE:
MOV @R0,#' ' ; put a blank in the memory address specified in R0
INC R0 ; go to next memory address
CJNE R0,#080H,CBONE ; stop when address is 80H
RET
;***************************************************************
WRITEBUFFER: ; uses R0
MOV R0,#070H
WBONE:
MOV P1,@R0 ; get character stored in memory address specified in R0
ACALL WRITELCD
INC R0 ; go to next memory address
CJNE R0,#080H,WBONE ; stop when address is 80H
RET
;***************************************************************
BEGLINEONE:
MOV P1,#080H ; go to beginning of line one
ACALL EXECUTELCD
RET
; ************************************************************
CLEARDISPLAY:
MOV P1,#001H ; clear display
ACALL EXECUTELCD
ACALL BEGLINEONE ; go to beginning of line one
RET
;*************************************************************
WRITEmyMessage: ; Write Ain Shams Univ. to LCD
ACALL CLEARBUFFER
MOV B0,#'A' ;write A
MOV B1,#'i' ;write i
MOV B2,#'n' ;write n
MOV B3' '#, ; Write „ „
MOV B4,#'S' ;write S
MOV B5,#'h' ;write h
MOV B6,#'a' ;write a
MOV B7,#'m' ;write m
MOV B8,#'s' ;write s
MOV B9' '#, ; Write „ „
MOV B10,#'U' ;write U
MOV B11,#'n' ;write n
MOV B12,#'i' ;write i
MOV B13,#'v' ;write v
MOV B14,#'.' ;write .
ACALL WRITEBUFFER
RET
;***************************************************************

307
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-7. Tri-State Buffers & Tri-State Bus


When you tie two things together, there can be a conflict between the two
things, if they both try to signal at the same time. There are a couple of
ways around this problem. One is to put each thing on a separate
connection. This solution requires a lot of wires and hardware to work.
The 8051 only has about 24 pins that you can connect something to.
While this may seem like a lot of connection points, if you wanted to
connect the display to its own lines, and the ADC to its own lines, you
would need 11 for the display and 11 for the ADC. That's already 22 and
you haven't connected a single sensor yet.
The other approach is to use a tri-state data bus. In normal logic, you
have two possible states, a '0' and a '1'. Tri-state devices add a third level,
called high-impedance or off-state. When the device is enabled (Enable =
1), it is in the high impedance state, or turned off, for all practical
purposes, disconnected. While you still have the original limitation, you
cannot be reading from both at the same time, you can share the bus
between the microcontroller and peripheral devices like LCD and ADC
by reading each at a different time, one after another.
Sometimes, you need to connect the I/O data pins of the 8051 with other
data pins of the peripheral devices, in a seemingly impossible situation.
Fortunately, there exist a set of electronic switches (tri-state buffers) that
connect the pins of each of these chip, with the logic inside. If these
switches are disabled, the chip is, in effect, disconnected. Figure (7-10)
depicts a tri-state bus driver, and the truth table of its constituent gates.

Enable

In Out

Enable In Out
1 0 High Impedance
1 1 High Impedance
0 0 1
0 1 0

Fig. 8-17. A tristate bus driver, with the truth table of its gates (NOT gates).
308
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-8. Analog-to-Digital Converter (ADC) Chips.


There is another device commonly used in microcontrollers called ADC
(analog to digital converter). An ADC converts a varying (analog) voltage
level into a corresponding digital number. We'll use either the National
Semiconductor ADC0808 or ADC0804. The ADC0808 has 7-analog
inputs (7-channels) and gives a 7-bit value out as a result of the
conversion. The ADC0804 has 4-analog inputs (4-channels) and also
gives a 7-bit value out as a result of the conversion. Both of these analog-
to-digital converters accept a voltage in the range of 0V to +5V. If the
voltage is 0 the digital value will be 00H. If the voltage is +5V, the digital
value will be FFH. This means that there can be 256 quantization levels,
including 0, that can be measured by the microcontroller. This means that
each one bit change in the digital value is equal to a 0.02V or 20 mV
change in the analog voltage. So as an example, if there is a 0.02V level
into a 7-bit ADC, there will be a count of 01H as a result. If there is a 2V
input, there would be a count of 64H (100).

ADC0804 (4-channels 7-bit) ADC0808 (7-channels 7-bit)

Fig. 8-18. The National Semiconductors 7-bit analog-to-digital converters.

Another example of analog input could be the light intensity to determine


when it's night or day. A microphone signal is also an example of analog
input. A sound signal may also indicate if the place is occupied, or not.

309
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

So, it can be used to turn lights on automatically when you enter a room.
In addition to the data lines, the ADC chip has other lines, the 3 MUX
select lines that could have required 3 more lines with the
microcontroller. These are inputs, not outputs, so the problem of conflict
doesn't appear. Adding these lines to the data bus has no practical effect
on the data bus operation. Since the ADC chips and other smart
peripherals have their bus drivers normally turned off.

8-8.1. Programming ADC0808 Analog to Digital Converter


We describe here the National Semiconductor analog-to-digital converter
ADC0808 and how to operate it in a microcontroller-based project. As
indicated above, this converter is 7-bits and has a microprocessor bus
interface and single +5V power. It also has a 7-input analog multiplexer
(MUX). The interface requires 6 lines in addition to the data bus. These
are the 3 MUX input select address lines and 3 control lines. The 3 MUX
address lines are connected to data bus bits 0 through 2. So that a nibble
(0-7) written to the ADC will select one of the eight inputs. There is a bus
output enable line for reading the ADC and an End of Convert line that
signals the host that the conversion is complete. Lastly there are 2 more
lines that are tied together and connected as 1 to the host. This is the
Start/ALE line. By placing a nibble (0-7) on the data bus and setting the
Start/ALE line to a one, the input MUX selection is written to the ADC.
When this line is taken back low, the conversion process starts. The EOC
line is driven low. Within a few milliseconds, the conversion is complete
and the EOC line is driven high. The OE line is set high and the result is
read from the ADC data bus. The OE line is set low, disabling the ADC
output data bus. This completes one cycle of the ADC conversion
process.
There are 2 other lines that are tied, to the Vcc and GND pins. These are
the +Vref and -Vref pins. The ADC conversion is done based on the ratio
of the input to the Vref pins. In other words, if +Vref is +5V, then each
bit is worth 5/256 or 19.53 mV. The more accurate voltage for +Vref (in
terms of measuring voltage) would be 5.12 which would yield a 20mV/bit
resolution. We could then just multiply the value of the conversion by
20mV and have the actual voltage on the input, accurate to + or - 20 mV.
This would result in a 5.1V full scale reading if the binary value is FFH
(255d). So, the full scale is 1-bit less than +Vref. Also +Vref cannot be
more positive than Vcc and -Vref cannot be more negative than ground.
So to have a 5.12V +Vref, you would have to have a +5.12V Vcc.
We can just tie the Vref to Vcc and the -Vref to GND and take the loss
of accuracy in favor of simplicity. We can use 20 mV for the value of
310
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

each bit which results in an error of about 2.35%. If you are measuring
the position of a potentiometer, with either ends tied to Vcc and GND
and the wiper as an input, then it doesn't matter what the +Vref value
actually is, since you are now looking for a ratio, not an actual value. You
want to know the POSITION of the wiper, relative to either end, not its
actual resistance or voltage. This is what the ADC0808 was designed to
work best with and it's called ratiometric.

Fig. 8-19. Block diagram of the National Semiconductors ADC0808 converter.

Here are the steps in order and what each does. Initially the EOC line is
high, the OE line is low and the Start/ALE line is low:

1. A MUX selection (00H ) is placed on the ADC bus


2. The Start/ALE line is set high.
3. The Start/ALE line is set low
4. The EOC line is monitored until high
5. The OE line is set high
6. The converted results are read from the ADC
7. The OE line is set low.

Line 1- Bits 0 thru 2 are the MUX select lines. So to select, say input 0, a
00H is placed on the bus. To select input 7, a 07H is placed on the bus.
Line 2- Set Start/ALE line high, strobes in the MUX select to the ADC.
Any voltage applied to input 0 is connected to the ADC converter input.
311
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Line 3- Resetting this line starts the converter converting. After this, the
EOC line goes low, indicating busy.
Line 4- The EOC line is monitored until it goes high, indicating
conversion complete.
Line 5- The OE line enables the ADC output data bus when it is high
and disables it when it is low. So setting the line high here enables the
ADC output bus.
Line 6- The converted value is read into the host (8051) microcontroller.
Line 7- The ADC output bus is disabled (tri stated, or turned off), and the
conversion process is complete.
At the time we are placing the 00H on the bus to select input 0 on the
ADC, the Start/ALE line makes use of the bus. It strobes the 00H into the
ADC chip. The display chip is being a display and could care less that the
ADC is using the bus. A more elemental way of looking at the problem is
that on a bus, the problem of conflict arises when more than one device is
trying to TALK on the bus at the same time. The problem of conflict
never comes from how many "listeners" there are on the bus.
So far, we've saved ourselves 11 connections that would normally have to
be made with separate lines, the 3 MUX select lines and the 8 data bus
lines from the ADC. We may also use additional 14 lines to connections
between the 8051 and the LCD. We may also add a keyboard to the
system that will add 1 new control line, and use all the data bus lines.
Buses are terrific things, but they do have their drawbacks. Any time one
of the chips that have bus drivers fails in a way to leave drivers stuck on,
through some hardware failure, or software glitch, none of the other
devices on the bus can communicate over the bus. In essence, there is a
loudmouth, screaming at the top of his lungs, in a small, crowded room,
so that no other communications can take place in the room. It's a
sacrifice made with all due diligence and forethought.
Now, let's think a little about P0 on the microcontroller (8051). We are
using P0 as the peripheral data bus for the display, ADC, and eventually a
keyboard. Any time we (the 8051) write to P0, we must follow the
operation with an instruction to write all 1's to P0. This leaves P0 in its tri
state condition. The outputs of the 8051 are high enough resistance that
other outputs can override the 8051 outputs. But this only works if all the
outputs are high (hence the pull up resistor), and someone wants to bring
one low. It won't work if the line is low and someone wants to bring it
high. It will stay low (or worse, burn up a chip!). If both switches are
closed, and you open one, the output is still closed by the other switch, so
no change occurred on the output. Both switches have to be open for any
one switch to communicate. 312
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

P0 is also unique among the 8051 ports because it is an open collector


output (floating), as opposed to totem pole. In our projects, we usually
use a display with enough of pull-up resistors on its inputs. They pull up
P0 pins so that no external pull-ups are required. If you don't use a
display, to be safe in any case, you should pull up all 8 lines with a 10K
resistor to Vcc. The other 8051 ports are totem pole outputs, that don't
require any pull-up resistors.

Here is the program, which makes use of the ADC0808 to collect data
and sends it to the microcontroller, which in turn sends it to the display.
The bit adec is the EOC (end of convert) pin of the ADC0808. The bit
adst is the Start/ALE input pins of the ADC0808. Bit adoe is the ADC
output enable pin.

adcnv:
wait2: jnb adec,wait2 ;wait until EOC is a one
setb adoe ;enable ADC output bus
mov a,P0 ;get converted value
clr adoe ;disable ADC output bus
mov a,#h'00 ;set MUX select to input 0
mov P0,a ;put MUX select on the bus
setb adst ;set Start/ALE to a one
;(this strobes in the address)
clr adst ;clear Start/ALE to a zero
;(this starts the conversion)
mov P0,#h'ff ;set P0 to tri-state bus

This example is only converting input 0 and never converts the other 7
inputs. Otherwise it is exactly as it will be in the final software. This
pretty well covers the display and the ADC converter.
Now for something on how our system is going to operate. As we've
mentioned so far, there are two basic ways to have events signaled to the
microcontroller.

1- By polling all the devices, getting their status.


2- By emitting an interrupt signal, like EOC on the ADC chip.

However, the 8051 has only 2 external interrupt inputs (INT0, and INT1).
We dedicate one of these (say INT1) to a "Break" switch, for trouble
shooting purposes. So without adding any additional hardware to expand
these, we only have one external interrupt (INT0) to use for all our
interfacing needs. For our needs, this is quite sufficient. In other cases,
we will exercise the third option, and that is to have a combination of
interrupt driven polled response.
313
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

For, instance, if we've an X-10 computer interface module (like TW325),


with 50 Hz square wave, synchronous with the 220 VAC power. We will
double this to 100 Hz, for reasons we'll explain when we get into X-10
interfacing in the next section. With this arrangement, we will get an
INT0 interrupt 100 times a second. This is exactly the rate needed to
accommodate the X-10 interface, with the least hardware. During each
iteration of this interrupt, several things are going to happen. First the
ADC is serviced, then the display is serviced, and eventually a keyboard
will be serviced. Also the X-10 has to be serviced.

The other interrupt that could be happening regularly is communication


via the RS-232 serial port driver. When a character is received on the
serial port, an interrupt is generated (RI) that says that the receive buffer
is full. It is the responsibility of the program to get to the serial buffer and
read the contents before the next character comes in. If you don't, chaos
will most surely erupt.

As we mentioned before, the 8051 takes 12 clock cycles to make an


instruction cycle. This makes the 11.0592 MHz clock turn into 921,6
instruction per second (0.9216 MIPS). With 9600 as the baud rate, there
are 960 instruction cycles between characters, if characters were coming
at the maximum rate, or worst case. There are 9600 instructions between
each 100 Hz interrupt. Since we never disable any interrupts after startup,
and an interrupt can occur and be serviced, while inside another service
routine, there shouldn't be any problems.

The things to consider when doing much of the software inside an


interrupt routine, is how much of the total supply of instruction times will
be used up by the interrupt, and will this be too many to allow the
operating loop to have some crunch time. The thing to remember, there
are a finite number of instructions in each second of time. In our case,
there are 921,600 instructions in each second. We are going to have two
different pieces of software running all the time, one the Operating Loop,
another the 100 Hz interrupt routine, along with any characters sent or
received on the RS-232 link. One thing that we like to do is to calculate
shortest and longest execution times for all the different routines, and
keep a list of them, to reference when trouble shooting. This takes a while
to compile, but it is priceless if it is needed. Now, let's go back to our
system. All the polling of devices on the tri-state peripheral data bus will
be done during the 100 Hz interrupt routine. The operating loop will not
directly communicate with these devices. This communication will take
place through the interrupt routine, using flags and buffers.
314
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

The external data ram is used for the buffers needed to make all this
work. The 8051 has only 128 internal RAM locations, which run out fast
with large buffer sizes. But we have "more ram than we can shake a stick
at", in external data memory. The display has a buffer here that is 128
bytes long. If the operating system wants to display something, it is
written to this buffer.

During the 100 Hz interrupt routine, one line of the display is refreshed.
So in 4 iterations of the 100 Hz routine, the display is completely
updated. Or another way of saying it, the display is updated at a rate of 25
Hz. You may try first to update the entire display each 100 Hz cycle, but
the next interrupt would occur before you finish servicing the previous
interrupt, in other words, you ran out of time. It took longer than 1/100th
of a second to update the entire display. You may choose to display 1 line
per cycle, for a fast real time display rate and less overhead on the host.

During each iteration of the 100 Hz interrupt, one point is converted by


the ADC converter. In 8 iterations of the 100 Hz routine, all the inputs
will have been converted. Another way of saying this is that the ADC
points are scanned at a rate of 12.5 Hz, or 12.5 times a second. The 8
readings are stored in a buffer that is read by anyone wanting to know a
reading. The reason we chose this approach is that the ADC is in the
process of converting a point, almost all the time. You hardly have to say
anything to him, he just works. By doing it this way, there is very little
overhead to scanning the ADC points into the system memory. The ADC
is left mostly waiting around for that poky old 8051 to get around to
giving him his next job. Of course that inconsiderate ADC doesn't realize
that the trusty 8051 is taking care of a lot more than just ADC. While all
this ADC and Display work is going on, there may be X-10 in your
system. In this case, you have to consider the instructions to send and
receive PC commands to be honored. You may have, in addition, a
security system that can turn on an X-10 device (horn for instance) to
wake people when needed. A real time clock keeps up with scheduled X-
10 events and watches for scheduled tasks to do, like start the coffee pot,
or lower the thermostat, turn off the kids TV maybe.

With a couple of other chips, we can add voice control, a 900 MHz RF
communications transceiver, and 56.6K Modem interface. Other cool
interfaces would be a sonic range finder, synthesized voice playback, IDE
hard drive interface or even unmanned plane. As we pointed out in our
discussion about keypads, we need a certain "tricks" to smooth digital
inputs from switches, contacts, etc., to remove the bounce from a contact.
315
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

To debounce a contact, the input is sampled several times, and only then
is it recognized as having changed. We normally write a routine that
scans all the inputs at once. Usually we arrange the hardware so that all
the inputs are in one port. Then we read from that port, masking out any
bits that aren't inputs, and then comparing the current status with the
previous status, when you scanned it last.

You are looking for a change between the previous, or old status, and the
current status. As the microcontroller is powering up, the inputs are read
and stored as old status, to be used for all the succeeding scans of the
inputs. We always have a non-stop operating loop that continuously scans
the inputs, and then jumping out to a routine associated with a particular
input, when it is sensed and denounced. After the routine is finished, we
return to the loop, to stay there, until another input has changed. Here is a
generic input scan routine that will read and denounce the 8 inputs in port
3 of the 8051. This code uses a location for old status (ostat), a location
for current status (cstat), a location for denounced changes (dbchg),
and 8 locations starting at the label dbctr that are the 8 denounce
counters, one for each input. All this code is shown in the proper
sequence, even though there is descriptive text in between each part. This
code reads input and stores it as old status.

mov a,p3 ;read current status


mov ostat,p3 ;and store it as old status

This is the start of the operating loop. This code reads the inputs and
compares them to the old status, generating any changes as a 1's. If there
isn't a change on an input, that bit will be a 0.

begin: mov a,p3 ;read current status


mov cstat,a ;and store as current status
xrl a,ostat ;generate changes

This code goes thru all 8 inputs and increments the associated debounce
counter if there is a change, or clears the counter if there is no change.
mov r0,#dbctr ; start of debounce counters
mov r3,#h'08 ;set for 8 debounce counters
n0002: rrc a ;rotate bit of change into carry
jnc inc00 ;if bit is 0 then goto inc00
inc @r0 ;increment debounce counter

n0003: inc r0 ;step counter pointer


djnz r3,n0002 ;if not last then n0002
sjmp c0002 ;goto c0002
inc00: mov @r0,#h'00 ;zero debounce counter
sjmp n0003 ;goto n0003

316
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

This code goes thru all 8 denounce counters to see if any have reached a
count of 16. If one has reached 16, that bit is set in the denounced
changes byte (dbchg) and the denounce counter is cleared. Otherwise
the bit in the denounced changes byte will be zero and the counter left
untouched.
c0002: mov r0,#dbctr ;get start of debounce counters
mov r3,#h'08 ;set to check 8 status inputs
n0004: mov a,@r0 ;get debounce counter
cjne a,#h'10,onexx ;if count not=16 then go onexx
setb c ;set carry flag
mov @r0,#h'00 ;zero debounce counter
twoxx: mov a,dbchg ;get debounced changes
rrc a ;and shift in
mov dbchg,a ;into storage
inc r0 ;step debounce counter pointer
djnz r3,n0004 ;if not last then n0004
sjmp e0000 ;goto e0000
onexx: clr c ;clear carry
sjmp twoxx ;goto twoxx

What you have now is a byte (dbchg) representing any changes that
have been debounced. There is more that one way to proceed from here,
but here's one way. We only show the code for the first 3 bits (bit 0 thru
bit 2) but it's the same for the rest.
e0000: mov a,dbchg ;get debounced changes
jnb acc.0,e0001 ;if bit 0=0, goto next input
ljmp rout0 ;otherwise goto routine 0
e0001: mov a,dbchg ;get debounced changes
jnb acc.1,e0002 ;if bit 1=0, goto next input
ljmp rout1 ;otherwise goto routine 1
e0002: mov a,dbchg ;get debounced changes
jnb acc.2,endlp ;if bit 2=0, goto next input
ljmp rout2 ;otherwise goto routine 2
endlp: ljmp begin ;end of operating loop

This code represents the routine that will be executed as a result of an


input change on input 0. The NOP is the code you have to service input 0.
rout0: nop ;this represents the routine

This code complements the old status bit 0. This makes the old status
equal to the current status, so that when we return to the scan loop, no
changes will be detected until bit 0 changes states again.
mov a,ostat ;get old status and complement
xrl a,#h'01 ;old status bit 0
mov ostat,a ;and store it
ljmp e0001 ;done, goto next input

317
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

This code is identical to rout0 except for this being for bit 1
.
rout1: nop ;your code
mov a,ostat ;complement old status
xrl a,#h'02 ;bit 1
mov ostat,a ;and store it
ljmp e0002 ;done, goto next input

This code is identical to rout0 except for this being for bit 2.
rout2: nop ;your code
mov a,ostat ;complement old status
xrl a,#h'04 ;bit 2
mov ostat,a ;and store it
ljmp endlp ;done, goto end of loop

So what all this has done is to denounce an input and execute some
routine to service it. A change on an input has to be there for 16
consecutive scans before it is recognized as valid. If an input doesn't have
a change, it's denounce counter is always cleared. When a counter has
reached 16, it is cleared and a bit is set in the denounced changes byte to
reflect that that bit has changed and is valid.

Next, the routine for that bit is executed and at the end of this routine, the
old status for this bit is complemented, making it the same as the current
status. Then the next input is checked. Now when this bit is scanned and
checked against the old status on the next scan, there won't be a change
generated for this bit until it changes states again for 16 consecutive
scans. This not only debounces a contact, but increases the noise
immunity on input as well. You can use a count of 16 or any count value
up to 255 or down to 1. What we normally do to get the average value of
a signal, is to have a memory location for each analog input, containing
the current value used by the operating system. As each input is scanned
and converted, the new value is added to the old value and divided by
two, and then stored back in the memory location. This has the effect of
filtering and smoothing the input, at a minimal software impact. This isn't
the most complicated way of filtering, or the most accurate and
responsive, but it is very simple and takes very few clock cycles to
execute. Here is an example of this. This uses port 3 as the ADC value
and temp as the current reading.

filter: mov a,P0 ;get the conversion value


add a,temp ;add it to the current value
rra ;divide it by two
mov temp,a ;store as current

318
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

This code reads port 0 for the value. That value is then added to the
current value in memory. This result is divided by two, by shifting right
one bit position. This is stored in memory as the current value. Depending
on the impedance of the input, we sometimes also hang a 0.1uf capacitor
to ground at the chip input, to add some extra filtering.

8-8.2. Digital-to-Analog Converter (DAC) Chips.


The digital-to-analog converters (DAC), like DAC808 or MC1408, are
used to transform digital output from a microcontroller port to an analog
proportional value. For instance, the digital output P.0-P.7 of a given
output port is fed to the DAC IC and transformed to an analog output
value Vo according to the relation:

 P.0 P.1 P.2 P.3 P.4 P.5 P.6 P.7  (7-1)


Vo  Vref        
 256 128 64 32 16 8 4 2 

where Vref is a constant, such that Vo ranges between 0 and Vref.

319
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-9. X-10 Control Interface & X-10 Protocol3


X10 is a communications "language" that allows compatible electronic
appliances to talk to each other using the existing electrical wiring in the
home. Most X10 compatible products are very affordable and the fact that
they talk over existing wires in your home means that no costly rewiring
is necessary. Installation is simple; a transmitter plugs-in at one location
in the home and sends its control signal (on, off, dim, bright, etc.) to a
receiver which plugs into another location in the home. In this section we
will talk about X-10 and home control over existing power lines. The
TW523 X-10 is a Power Line Computer (PLC) interface that implements
the X-10 protocol. The TW523 X-10 provides an isolated connection to
the power line, but eliminates any transients from getting into the
microcontroller. All inputs and outputs of the TW523 are isolated, using
4N35 optocouplers, and therefore safe to connect to the microcontroller.
The opto-isolators provide isolation between the power line and the
microcontroller.

Fig. 8-20. Some X10 devices.

X-10 communication protocol has been around for many years. The X-
10 hardware modules are originally assumed for 60 Hz power frequency
(USA). However, X-10 has modules for 50 Hz power mains, which is the
standard mains frequency in our countries (Middle East & Europe).

X-10 allows for up to 256 devices, divided into 16 house codes, each with
16 unit codes. Most X-10 devices has the ability to select, with switches,

3
The X-10 protocol is patented but gives anyone that purchases a PL513 or TW523 express permission
to transmit X-10 commands. It is in direct violation of the patent to create your own hardware interface
to the power line and transmit X-10.
320
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

the house and unit code address. The TW523 is one of the few devices
that doesn't have these selector switches. That is because the TW523 can
communicate with any one of the 256 possible devices. Originally,
lighting was a big part, and still is, for the use of X-10. There are also
horn modules, thermostat modules, pet feeders, infrared motion sensors,
and many more. Each recognizes and may respond to some or all of the
commands available. It depends on the module.

The X-10 Commands: There are many different X-10 modules available.
One is the lighting module. This module recognizes the ON, OFF, ALL
UNITS OFF, ALL UNITS ON, ALL LIGHTS ON, ALL LIGHTS OFF,
DIM, and BRIGHT commands. Some of the newer models may also
recognize and respond to STATUS REQUEST with STATUS=ON or
STATUS=OFF and recognize the PRE-SET DIM command.
The ON and OFF commands are straight forward and either turn off or
turn on a device. The ALL UNITS ON and OFF also do the same thing,
except that it is done for all devices on a particular HOUSE code. The
ALL LIGHTS ON and OFF act on all lighting control modules on a
particular HOUSE code.
The DIM dims a particular lighting module and the BRIGHT brightens a
lighting module. The PRE-SET DIM sets a particular lighting module to a
DIM level somewhere between OFF and ON, without having to send
repeated DIM's or BRIGHTs to get it to that level.
The HAIL REQUEST is used to determine if there is another "talker" or
transmitter within "listening range" of the TW523. This could be another
TW523. If there is another talker, it will respond with the HAIL
ACKNOWLEDGE response.
The X-10 Protocol: To control an X-10 device, the HOUSE code, the
UNIT code and the FUNCTION code must be sent for a complete
command. The UNIT code and the FUNCTION code vary in the most
significant bit, called D16 in the X-10 protocol documentation. For a
UNIT code this bit is a zero and for a FUNCTION code this bit is a one.
Following is a table listing all the codes used by X-10.
The X-10 protocol defines transmissions in 11 cycle message segments.
Each message segment contains a START code, a HOUSE code, and a
KEY code. The KEY code can be a UNIT or a FUNCTION, depending
on the state of bit D16. The X-10 protocol states that, except for the
START code, all bits are sent in their "True" state, immediately followed
by the "inverted" state. In other words if a HOUSE code 'A' is sent (0110)
this would look like 01 10 10 01. Each of these pairs of bits
321
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

would take one complete cycle of power to be sent. The true state is sent
on the first half cycle and the inverted state on the second half cycle.

House Codes Key Codes


H1 H2 H3 H4 D1 D2 D4 D8 D16

'A' 0 1 1 0 '1' 0 1 1 0 0 UNITS


'B' 1 1 1 0 '2' 1 1 1 0 0
'C' 0 0 1 0 '3' 0 0 1 0 0
'D' 1 0 1 0 '4' 1 0 1 0 0
'E' 0 0 0 1 '5' 0 0 0 1 0
'F' 1 0 0 1 '6' 1 0 0 1 0
'G' 0 1 0 1 '7' 0 1 0 1 0
'H' 1 1 0 1 '8' 1 1 0 1 0
'I' 0 1 1 1 '9' 0 1 1 1 0
'J' 1 1 1 1 '10' 1 1 1 1 0
'K' 0 0 1 1 '11' 0 0 1 1 0
'L' 1 0 1 1 '12' 1 0 1 1 0
'M' 0 0 0 0 '13' 0 0 0 0 0
'N' 1 0 0 0 '14' 1 0 0 0 0
'O' 0 1 0 0 '15' 0 1 0 0 0
'P' 1 1 0 0 '16' 1 1 0 0 0

'ALL LIGHTS OFF' 0 0 0 0 1 FUNCTIONS


'ALL LIGHTS ON' 0 0 0 1 1
'ON' 0 0 1 0 1
'OFF' 0 0 1 1 1
'DIM' 0 1 0 1 1
'BRIGHT' 0 1 0 1 1
'ALL LIGHTS OFF' 0 1 1 0 1
'EXTENDED CODE' 0 1 1 1 1
'HAIL REQUEST' 1 0 0 0 1
'HAIL ACKNOWLEDGE' 1 0 0 1 1

'PRE-SET DIM' 1 0 1 X 1
'EXTENDED DATA (ANALOG)' 1 1 0 0 1
'STATUS=ON' 1 1 0 1 1
'STATUS=OFF' 1 1 1 0 1
'STATUS REQUEST' 1 1 1 1 1

The exception is the START code, which is always sent out as 1110.
Looking at the above example of HOUSE code 'A', that data is 01101001.
Notice that in that data there is never 3 one's in a row, and never the
pattern 1110. This makes the START code unique in the data stream, and
what signals the start of an X-10 message segment. A complete message
segment will take 11 cycles of power to send. In other words the data is
sent out just as it is listed in the above table, from left to right starting
with the START followed by H1, H2, H4, H8, D1, D2, D4, D8, and D16
along with the inverted bits. Here's an example of what the data stream
would look like for HOUSE code 'A' and UNIT code '1'.
322
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

1110011010010110100101

Dividing it up in it's functional groups it would look like this.

1110 01101001 0110100101

The first four bits are the START code, the next 8 are the HOUSE code
and the last 10 are the KEY code. Dividing this up in pairs of bits,
representing complete cycles of power, it would look like this.

START HOUSE CODE KEY CODE


11 10 01 10 10 01 01 10 10 01 01

As you see here, the START code takes 2 cycles, the HOUSE code 4
cycles, and the KEY code 5 cycles. This is the 11 cycle message segment.
One complete command consists of the message segment sent twice,
taking 22 cycles of power to send. If the TW523 was receiving this 22
cycle transmission, data will only be sent out to the microcontroller
during the second message segment. The proprietary chip inside the
TW523 is comparing the first message segment with the second segment
as it is received and presents data to the microcontroller during this
second segment. This comparison is made to validate the X-10 command,
and that it wasn't garbled with noise during transmission.
To actually turn 'ON' HOUSE code 'A', UNIT '1', two commands are
sent. The first command selects the UNIT to be controlled and the second
command is the action to be taken, in this case to turn 'ON'. This
complete transmission would take 22 cycles for the first command,
followed by 3 cycles of silence, followed by 22 cycles for the second
command, for a total of 47 cycles. There would also have to be at least 3
cycles of silence following the second command, which would bring the
total to 50 complete cycles of power for one complete transmission,
before another could be sent. The exception to the rule of 3 cycles of
silence between commands is in the case of DIM, BRIGHT, EXTENDED
CODE, and EXTENDED DATA. These commands are sent with no gaps
or silence between commands. The TW523 can only receive commands
separated by 3 cycles of silence.
The format of the X-10 message follows a strict order. Following is a
complete X-10 message. Although we've shown it on two lines, they
should be considered as one long line.
START HOUSE UNIT START HOUSE UNIT SPACE
START HOUSE FUNCTION START HOUSE FUNCTION SPACE

323
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Our approach to X-10 transmission is to build the complete message (all


47 cycles worth) in a buffer in data memory, and then send it out, one bit
each 100 Hz interrupt iteration. This is one of the reasons we pick 100 Hz
for the interval of the interrupt. In this way, a minimum of CPU time is
spent sending the X-10 transmission. The TW523 outputs a square wave,
in sync with the power line frequency and 50us zero crossing. This is a 50
Hz square wave. In your design you may trigger two monostables, one on
the rising edge of this square wave and one on the falling edge. You can
OR the outputs of these two single shots together to form the 100 Hz
frequency needed, for software simplicity, to generate and receive the X-
10 transmission. We also use another monostable to generate the 1 ms
modulation envelope for transmitting X-10. This relieves the software
from generating this interval leaving more crunch time for everything
else.
One last thing, when a '1' is present in the X-10 data stream, this results in
a 100 KHz carrier being applied to the power line. If a zero, no carrier is
present. In other words if a 100 KHz carrier is present, that is interpreted
as a 1, otherwise it is a zero. Note that the transmit and receive signal
points on the TW523 are INVERTED. In other words to send a „1‟ you
really send a zero and if you are receiving a zero, that's really a one.
Sounds very confusing, but in reality you handle this by simply inverting
everything you send or receive with the TW523, in software.
One can use software for this inversion instead of external inverter gates.
This is one example of software being as good as or better than hardware
for a particular job. If you don't have any spare inverter gates left, do it in
software and the impact on software is very minimal to perform this
inversion. On the other hand you can add a single shot gate to time the
1ms envelope requirement for X-10 transmission, which would have used
a lot of CPU time to generate this interval in software. When designing a
system, there is a continuous effort to use the minimum amount of
hardware. But, we try at the same time to have enough hardware to
simplify the software, where it matters. In closing, there are devices on
the market that will interfere with X-10 communications. This includes
light controllers, that all operate over the power lines. The interference
comes from the fact that these devices are transmitting and scrambling the
X-10 signals (100 kHz carrier, in case of 50Hz power line frequency).

324
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-10. Building a Demo-Board.


Now, we begin the description of a basic microcontroller development
board, which contains many devices (UART, ADC, LCD,). Figure 8-21
depicts the circuit diagram of such a demo board.

Fig. 8-21. Circuit diagram of the microcontroller demo-board


325
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

The necessary components are as follows:

Qty Part# Description Price


($)

2 74HCT123E (U1,U7) DUA RETRIG MONO MULTIVIBRATOR 1.60


1 4N35QT (U2) TRANSISTOR OPTOISOLATOR .43
1 MAX232CPE (U3) DUAL RS232 X/R 16- DIP 5 VOLT 2.94
1 74HC04 (U4) HEX INVERTER 0.39
1 SE1232 (U5) CRYSTAL OSC 11.0592MHZ CMOS 8 D 3.45
1 892051 (U6) ATMEL MCU 2.88
1 74HCT393E (U8) DUAL 4 BIT COUNTER .83
1 ADC0808CCN (U9) 8 BIT A/D CONV 8 CH MUX 28-DIP 6.60
1 73-1098 (U10) LCD MODULE 20 X 4 CHARACTER 31.92
1 7805FA (U11) 5V POSITIVE REGULATOR TO220 .88
2 LM34DZ (U12) 32 TO 212F TEMPERATURE SENSOR 5.70
1 P276 SOLAR CELL 1.3V 55.0 X 11.0 MM 1.16
3 HLMP-1700QT T-1 DIFFUSED RED LED .90
1 W005G 1.5 AMP 50 V BRIDGE RECTIFIER GP .42
1 T702 WALL TRANSFORMER 9VAC 600 MA 6.70
1 HS121 PLUG-IN HEAT SINK FOR TO-220 .44
1 P5234 NHE RADIAL ELECT CAP 16V 470UF .66
2 P2040 22UFD 16VDC TANTALUM CAP 1.72
2 CKN1059 TOGGLE SWITCH SPDT VERTICAL RT 8.88
10 P4551 0.001UF 50VDC POLYESTER B CAP 1.08
3 2N3904 NPN SML SIG G.P. AMP&SWITCH TO-92 .87
1 2N3906 PNP SML SIG G.P. AMP&SWITC TO-92 .29
5 100EBK 100 OHM 1/8W 5% CARBON FILM RESISTOR .28
5 330EBK 330 OHM 1/8W 5% CARBON FILM RESISTOR .28
5 470EBK 470 OHM 1/8W 5% CARBON FILM RESISTOR .28
5 4.7KEBK 4.7K OHM 1/8W 5% CARBON FILM RESISTOR .28
18 10KEBK 10K OHM 1/8W 5% CARBON FILM RESISTOR .56
5 27KEBK 27K OHM 1/8W 5% CARBON FILM RESISTOR .28
2 923252 SUPER STRIP ALLOY CONTACTS 38.50
1 MC14M-X 5 FT 14 CONDUCTOR RIBBON CABLE 4.80
2 P4888 .1UF CAP .64
10 BAV21DICT .2 AMP 250 VOLT DIODE 1.00
1 P2105 1UF 16VDC TANTALUM CAP .28

We've included a description so that you can get some of these parts from
any components supplier.

74123
Fig. 8-22. Pin-out diagram of the some chips in the demo-board.
326
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-10.1. The power-supply section


Let‟s begin with the system power supply. In fact, batteries are
expensive way to power your projects and kits. Here we present a basic
power supply in a box, or integrated with your demo-board. It consists of
a transformer, a bridge rectifier, a filter capacitor, a +5V regulator chip
and a heat sink for the regulator. The transformer should have at least a
7.5V RMS output and at least a 0.5A capacity. The 7805 power regulator
IC takes in a DC voltage at the INPUT leg (around 12V). It's OUTPUTS
leg is DC +5V which powers the system. "COMMON" is connected to
Ground.

Fig. 8-23 The voltage regulator circuit diagram.

You need a heat sink (HS121-ND) onto the 7805 voltage regulator chip.
The thinnest end is where the metal tab of the 7805 slips into and the
thicker end is where the body of the 7805 ends up. Bend out the fins of
the heat sink just enough to slip in the 7805, metal tab first, into the
thickest end. Slide in the 7805 until the metal tab ends up at the other end
of the heat sink. One end of the heat sink will now be pressed against the
metal tab and the other end will be pressed against the body of the 7805.
327
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

This should be as tight fit as you can get, the tighter it is the better the
heat will be conducted and radiated away from the 7805. Solder the +
lead of the rectifier bridge to the IN lead of the 7805 and the - lead of the
bridge to the GND lead of the 7805. Then solder a wire to the OUT lead
of the 7805 and another to the „–„ lead of the rectifier bridge, somewhere
between where the capacitor is connected and where the 7805 is
connected. Now connect two more wires to the ~ leads of the bridge,
somewhere in the middle between where the transformer is connected and
the body of the bridge.

You may use red for the „OUT‟ lead of the 7805, black for the „-‟ from
the bridge, and two other colors for the „~ „ leads of the bridge. Now,
take a "hot glue gun" and stick the transformer leads just before they
connect to the bridge down to a 18" piece of 1" by 6" wooden board, near
one end. Put enough glue to secure the transformer leads so they won't
pull loose by tugging on the transformer lead. This type glue sets very
fast so after you squeeze out a puddle of glue, a half inch in diameter or
so, stick the transformer leads into the puddle with the leads going to the
transformer pointing out away from the board, and do it while the glue is
still molten.

If you don't want to use hot glue, you can fasten the power supply down
however, or even mount it on a perforated board (a board with holes
and copper pads on the back side). You insert the parts on the bare side
and solder them on the back side. Then make the interconnections,
usually using the leads of the parts by bending them over.

8-10.2. The Serial Port Connectors


You will need a cable and DB-9 or DB-25 female serial connector to
connect to your PC serial port. The number of pins depends on the
number of pins on your PC. Some PC's have both, with the 8-pin being
COM1 and the 25-pin COM2. But things are further complicated if you
have an internal modem. Many times the 25-pin port, or COM2 will be
disabled and the installed modem will be set for COM2. The cable
between the PC and the microcontroller only needs 3 wires. We can use
standard flat telephone cable for this cable. The schematic circuit below,
show you what pins to tie together on the female serial connector to avoid
having to use more than 3 wires. The female connector will end up
plugging into the serial port on the PC. There are two possible connectors
that you will be using, either a 9 pin or a 25 pin female "D" connector
(DB9 or DB25).

328
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

The DB9 comes from the fact that the shape of the connector resembles
the letter D. Which one you use depends on the available connectors on
your PC. Some have a 9 pin, some have the 25 pin, and some have both.
Your mouse may be plugged into the 8-pin one. If this is your case, you
can use the DB25 connector or unplug the mouse and reboot your system.

Fig. 8-24. The serial port connectors: DB-9 and DB-25.

You need something to hold the DB9 connector with while you both
bring the tinned wire into contact with the "cup" (the back side of the
connector) while at the same time pressing the tip against the previously
tinned cup, all at the same time. Now take a second pair of pliers, and put
several wraps of rubber band on those handles and then open up the jaws
and clamp onto the handle of the first pair, at a right angle. This will
create a stable combination that will free stand on the table and hold the
connector in place, with enough weight to keep it steady while you solder
to it. Following is the pin-out of both varieties of serial connectors. The
pins number from left to right (viewed from the back) with the numbers
starting on the row with the most pins, continuing on with the next row,
left to right.

9 Pin Female 25 Pin Female

1 5 1 13
o o o o o o o o o o o o o o o o o o
o o o o o o o o o o o o o o o o
6 9 14 25
Fig. 8-25. View of the DB9 and DB29 (Viewed from the solder side)

329
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

After you finish wiring of all the power busses, then it is time to plug in
parts. Notice that while the power strips run in the direction of the length
of the breadboard, the holes in the center of the breadboard seem to be all
together, side by side with a dividing strip down the middle, running the
full length of the breadboard, separating them into two large areas.

Figure 8-26. The demo-board (on a breadboard)

With power turned off, plug in the dual mono-stable multi-vibrator single
shot chip 74HC123 (U1), with the indent to the left. Always plug in the
chips with the indent to the left. Looking at the drawing above, that
would place pin 1 of the chip plugged into the first strip of five points in
the lower area, first row on the far left. Since this is an 16 pin dip, the first
8 rows on either side of the divider are used up. When you plug in a chip,
one of the narrow variety, you use up 1 of the five tie points in each strip,
leaving only 4 that can be connected to with jumpers or parts. On the
other hand, when you plug in a wide chip like the microcontroller, you
use up 2 on one side and 3 on the other side, because the chip is much
wider than the divider and it covers up 3 points that can't be used later.
Also as you plug in the chips, end to end, you should skip a row to allow
for the overhang of the chip package past the end pins.

Don't try to force two chips next to each other trying to use up the rows
completely. This skipped row will be used later for something else, it
won't be wasted. The next chip to plug in is the Opto-isolator chip 4N35
(U2). Next plug in the RS-232 driver chip MAX232 (U3).

330
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Next the hex inverter chip 74HC04 (U4). Lastly, for now, the oscillator
chip SE1232 (U5). This should still leave enough rows left for the
microcontroller (U6). But don't plug it in yet (if you've already got it).
You should now have 5 chips plugged in, starting at the far left of the
breadboard, end to end, with the indent or dot on each to the left. The
next thing is to connect GND to all the chips. Then, you just "plug" in the
ends to the appropriate places. Don't apply any strong force to do this, the
pins should go in without much effort. Don't use large diameter wires for
jumpers, as this will loosen the tie points, and possibly cause bad
connections if you ever use a smaller wire in that hole later on.

Now connect VCC to all the chips, following the same procedure. We
have renumbered the chips on the schematics, to reflect the order that we
placed the chips on the breadboard. This should make locating the chips
physically verses the schematic, much easier. On the new ones, the chip
in the upper far left corner is U5 not U1. The references to these
schematics in the previous lesson will also get the new versions.

Now double check all your VCC and GND power connections to each
chip again before we turn on the power. These have to be right before you
power up the breadboard. This is the one mistake that can destroy more
chips than you can afford. If you get these backwards, GOD Forbid, you
will certainly destroy some chips. If you're satisfied with the power
connections, we can add some parts now. First, we need to place one of
the 22UF caps at the point that the wires from the power supply plug into
the breadboard. Hopefully you plugged the wires into one side of the
breadboard, one into each bus, the red into the VCC bus and the black
into the GND bus. The next holes were probably used to jumper the
busses on each side of the breadboard together. These caps have a stripe
down one side, that lines up, more or less, with one of the leads. This is
the + lead of the cap. Plug this cap into the next available holes on the
bus, with the + lead plugged into VCC and the other lead into GND.

Now we are going to make a logic probe out of one of the 6 gates in the
hex inverter chip. You will need a 330 ohm resistor and one of the LED's.
Put one lead of the resistor into the tie strip connected to pin 10 of the
74HCT04 (U4) chip. Plug the other end into an unused strip near the
chip, like one of the rows we skipped as we plugged in the chips. Now
plug the shorter end of the LED into this same strip, with the longer end
plugged into VCC. Make a jumper, a foot long, one that will reach to any
place on either breadboard, and plug one end into pin 11 of U4. The free
end of this jumper is now the working end of our logic probe.

331
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

The way this probe will work is that if there is a '1' on the input, the LED
will be lit. If there is a '0', the LED will not be lit. Also, an open appears
to the probe the same as a '1'. So if you are confident of your connections,
turn on the power. The LED should light up immediately, indicating a '1'.
If it doesn't, turn off power and check your connections again. Now plug
the probe into GND and notice that the LED goes out. Plug the probe into
VCC. The LED is lit. VCC is the same as a '1'. You have just installed R2
and D1and used the gate U4E.

Now let's connect U4A, B, C, & D along with R1 and C1 and SW1 and
SW2. All of these parts are in the upper left quadrant of the print. First
install R1 and C1. You'll notice that one side of the cap goes to GND and
one side of the resistor goes to VCC. You'll also notice that one side of
the cap is marked + on the schematic. This is another one of the 22UF
caps. You'll notice that the UF doesn't appear next to the 22 on the
schematic. That is because all of the caps are assumed to be in
microfarads (UF) unless otherwise noted. This saves having to write UF
beside each one, cluttering up the print with needless text. Also the word
OHM does not appear beside any of the resistors, for the same reason. All
the resistors are assumed to be in Ohm. What you should end up with is
the - side of C1 plugged into GND, the other side plugged into the strip
for pin 1 of U4. Then one side of R1 plugged into VCC and the other
plugged into the strip for U4 pin 1.

Remember the chips are numbered from left to right, U1 through U5, the
way we plugged them into the breadboard. Now jumper from U4 pin 2 to
U4 pin 3. Jumper U4 pin 6 to U4 pin 9. Then U4 pin 8 to U4 pin 5. Now
take the green wire from the left switch (SW1, the one you marked
LOAD/RUN) and plug it into U4 pin 1. Plug the black wire from the
same switch into GND. The red wire from this switch won't be used at all.
Now take the green wire from the right switch (SW2, the one you marked
BREAK/NORMAL and plug it into GND. Plug the red wire into U4 pin 5
and the black wire into U4 pin 9. Flip both switches so the handles are
pointing to the right (toward the side that has the ends of the leads of the
switches. This puts both switches in the positions shown on the
schematic, or the normal positions. This is the position that you would
have the switches to allow the MCU to run normally. Double check all
connections; until you are satisfied they are right. Now turn on the power,
and the Probe LED should lite (this assumes that the end of the probe is
not plugged into anything). Plug the probe into U4 pin 2 and the LED
should go out. Now flip the left switch (LOAD/RUN) to the left (LOAD),
the LED should lite. Move the probe to U4 pin 4, the LED should be out.
332
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Now flip the left switch (LOAD/RUN) to the right (RUN), and the LED
should lite. Move the probe to U4 pin 6. The LED should be lit. Flip the
right switch (BREAK/NORMAL) to the left (BREAK) and the LED
should go out. Move the probe to U4 pin 8. The LED should be lit. Flip
the right switch (BREAK/NORMAL) to the right (NORMAL), the LED
should go out.

8-11. Microcontroller Development Boards.


It worth notice to mention that there are three kinds of microcontroller
boards, which are widely known to help design engineers developing
their microcontroller-based systems:

1. The evaluation boards. This type of boards is designed by some


microcontroller or microprocessor manufacturers to demonstrate its
features. Using such a board a design engineer can decide whether the
microcontroller will meet their needs for the design they are creating.
These boards are generally somewhat expensive (because they are
produced in small numbers) except when the part is being 'pushed' by the
manufacturer and there is some sort of promotional deal going on.
2. Embedded controller boards. These are generally boards
dedicated to some particular function (like driving a stepper motor, etc)
and are usually available pretty cheaply on the surplus market.
3. The Single Board Computers (SBC). These are generally
produced by a third party using some manufacturers. They are generally
pretty flexible single board computers but they may not 'expose' all
features. SBCs come in different sizes and prices, and some are available.
Usually, SBCs come with software development tools.

Fig. 8-27. Photograph of two single-board computers (SBCs).

333
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

Nowadays, there exist two famous SBC‟s, namely:


Arduino and Raspberry Pi (TPI) boards. The Arduino
PCB is designed around an 8-bit Atmel AVR or 32-bit
Atmel ARM. All boards are programmed via RS-232
serial port or USB. The optional Ethernet port makes it
easy to make a data logger, or a web enabled sensor.
Arduino boards can be purchased pre-assembled or as do-
it-yourself kits. The software consists of a standard
programming language compiler. Arduino programs are
written in C/C++. The Arduino IDE comes with a software
library called "Wiring" from the original project, which
makes many common input/output operations much easier.
The Arduino libraries make it easy to start with a working
demo and modify the code for a particular application. An
Arduino's microcontroller is also pre-programmed with a
boot loader that simplifies uploading of programs to the
on-chip flash memory.

Fig. 8-28. Photograph of A single-board computer (SBC).

334
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

The RPI is an SBC developed by the Raspberry Pi Foundation


with the intention of promoting the teaching of computer science
in schools. Early Raspberry Pi boards were based on the Atmel
ATmega644 microcontroller. Modern Raspberry Pi board have a
Broadcom BCM2835 system on a chip (SoC), which includes an
ARM1176JZF 700 MHz CPU, 512MB RAM, USB port and can
use external SD memory cards, for booting or storage. The
Foundation provides Linux distributions (Debian, Arch, Android
and other variants) for ARM processor. Development tools
which support Python as a main programming language are also
planned. However, writing a device driver for Linux from
scratch is not a trivial task.

8-12. Building Your Own 8051 Development Board


We‟ll here describe here how to build your own 8051 microcontroller
development board. The 8051 development board provides an easy-to-use
and low-cost way to develop your 8051 based microcontroller projects,
without purchasing any other equipment, such as IC programmers or
emulators.

Fig. 8-29. The circuit diagram of a simple 8051 development board, with external
RAM or Flash. The monitor ROM is written onto the 8kB Flash of the 8752MCU.
The 6264 is a 8kB flash memory and the 74HC373 is an octal latch.

335
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

The 8051 development board provides a number of features that are


designed to make the board easy to use, and yet keep the cost of getting
started with an 8051 project as low as possible. Using a pre-programmed
87C52 chip, no other equipment (other than a power supply and serial
cable) is required to develop projects based on the 8051 microcontroller.
The complete development board has the following components:
i- Monitor ROM:
The board uses PAULMON2 monitor ROM to provides a simple menu-
based system that enables you to download your own code on the board.
The PAULMON2 monitor ROM has easy to understand menus, prompts,
and most functions use a sequence of single key commands. All functions
have plenty of on-screen help messages. In addition, the PAULMON2
provides many features aside from program download, such as a full-
screen memory editor, un-assembler, and a trace execution mode.
ii-Flash ROM, Permanent User Program Storage:
As you work on your project, most code downloads will be to the SRAM
memory. When your code is working, you will probably want to operate
your project without need to be connected to a PC. The board contains a
Flash ROM chip, which can hold your code permanently. Using
PAULMON2, you can download code to the Flash ROM in almost
exactly the same way as the SRAM (most, but not all, flash chips are able
to write at 57600 baud, so you may need to use 19200 baud).
PAULMON2 recognizes a 64 byte header, which you place into your
program. Setting a few bytes in this header tells PAULMON2 to auto-run
your program when the board is booted, instead of running the normal
menus. By using this non-volatile Flash ROM feature of the board and
PAULMON2, you can easily make the board run your project when it is
powered up. No EPROM or other device programmer is needed, and the
difficult problems than can sometimes arise when a project is moved
from a monitor environment to a complete stand-alone operation are
easily avoided. If your code must be changed, or the board needs to be
used for a different project, there is a jumper that will cause PAULMON2
to erase the Flash ROM when the board is rebooted, making the menu
system available again for more development.

iii- I/O Expansion, 32 Signals and 8-Bit Bus Lines


The board has an 82C55 chip, which provides 24 I/O lines, in addition to
the 8 I/O pins from the 87C52's port 1. Eight of the 24 lines from the
82C55 have LEDs connected to them. The commonly used bus signals
for I/O chips are also provided on the edge of the board, with clearly
labeled silk screen lettering next to each pad.
336
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

iv- Serial Port Switching:


For some projects, where the project communicates with another device,
the menu system and code downloads could interfere with the other
device which would "hear" all of this communication when the board is
running PAULMON2 and not the project code. For these types of
applications, the board has a second serial connector, and a simple
switching circuit (controlled by pin 14 on the 87C52). To use this, the
first action taken by the downloaded program would be to drive pin 14
low, causing the 8051's UART to be routed to the other DB-9 connector.
While debugging, you code can temporarily switch the port back to send
debugging messages to the PC screen. When the board is rebooted, the
87C52 drives this pin high automatically, so PAULMON2 Monitor ROM
will always reappear.... unless of course, there is a user auto-startup
program stored in the Flash ROM.

Fig. 8-30. The 8051 development board.

v- Pad-Per-Hole Prototype Area


The lower third of the board is a pad-per-hole prototype area, which
provides enough space to construct additional circuitry for many projects.
In order to use the development board proceed as follows:
 Build or buy your 8051 based hardware.
 Download and configure a copy of the PAULMON2 monitor.
 Program the EPROM with PAULMON2.
 Run your terminal emulation program (e.g. Windows hyper-terminal).
337
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

 Turn on your 8051 board and press Enter (for auto baud detection)
 Write an 8051 program, or copy one of the examples
 Download the Intel-Hex file ( 'D' command)
 Jump to your program ( 'J' command)

Fig. (8-11). The complete development board circuit diagram. The 39F512 is a 64kB
SRAM, the 62256 is a 32kB flash memory and the 8255 is a 4-port PIO.

338
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-13. Summary

In this chapter we introduced the basic principles for building a


single-computer board, which is based on the 8051
microcontrollers.

339
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-14. PROBLEMS

8-1) When dealing with multiple device interrupts , which mechanism is


easy to implement
a) Polling method
b) Vectored interrupts
c) Interrupt nesting
d) None of the above

8-2) What is meant by RTOS (real-time operating systems) ? In which


applications they are important?

8-3) List and explain the important routines, from which the
microcontroller BIOS (Basic Input/Output) system is built.

8-4) What do you know about the Monitor ROM, which may be used in
microcontroller systems?

8-5) Describe the operation of the MAX232, and show why we it is


necessary to connect such a large number of capacitors around it.

8-6) Which of the following sentences is right?


(a) ARM7 provides for three types of interrupt sources (requests), NMI,
IRQ (interrupt request) and FIQ (fast interrupt request)
(b) ARM7 provides for four types of interrupt sources (requests), IRQ1,
IRQ2, FIQ1 and FIQ2.
(c) ARM provides SWI n instruction, where n is multiplied by
0x00000004 by processor to compute the interrupt vector address
(d) Hardware or software Interrupts in 80x86 are pre-assigned interrupt-
types or interrupt-type as per n in INT n instruction, respectively.

8-7) When dealing with multiple device interrupts , which mechanism is


easy to implement
a) Polling method
b) Vectored interrupts
c) Interrupt nesting
d) None of the above

8-8) Explain how to interface a 16-key lead-per-key keypad to a


microcontroller, using only 16 pins and one interrupt input.

340
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

8-9) Explain how to interface a 16-key coded keypad to a


microcontroller, using only 8 pins and one interrupt input.

8-10) Repeat the above problem for a 24-key coded keypad, using only 8
pins and one interrupt input.

8-11) Is it possible to use less than 8 pins to connect a matrix (coded)


keypad to a microcontroller?

8-12) Explain how to interface a parallel LCD to a microcontroller, using


only 4 pins and 3 control lines.

8-13) Explain how to interface LCD to a microcontroller, using only 1


pins and 3 control lines.

8-14) The following circuit may be used to connect any keypad to any
microcontroller, using only one pin (an interrupt pin).

i) Explain the operation principle of the circuit and find-out the


suitable values for its components, for the case of a 4x4 keypad connected
to an 8051 controller operating at 12MHz..
ii) Write down an assembly service routine to drive such a keypad,
when a key is pressed.
Hint: Looking at the above figure, you notice a familiar 4x4 keypad with
a single difference--each row and column are separated by a resistor. If
key #1 is pressed, the resistance between nodes A and B (R 1AB) is equal to
341
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8

1.5*R; for key #2--R2AB = 1.5*R+R = 2.5*R; and so on ... key #N--RNAB
= N.5*R. The variable resistor network is connected to a 555 timer,
configured as an oscillator with the period T = 1.4*R AB*C.
The oscillator runs only when a key is pressed, making an interrupt
request for the microcontroller. The INT0 pin of the microcontroller is set
up as edge-sensitive. The general algorithm can be described as follows:
1) After detecting the edge on the INT0 pin, wait 20 ms to eliminate
ringing;
2) Detect the next edge and start the internal timer;
3) The following edge stops the internal timer. The measured period (the
time between two consecutive positive edges) will define the key number.
Any microcontroller with a built-in timer can implement this idea.
8-15) Write a template assembly program that can be used to interface a
7-bit ADC (like ADC 8040) to Atmel microcontrollers

342
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

CHAPTER 9: Miscellaneous Microcontroller Projects

9-1. Introduction.
In this chapter we present the practical implementation details of some
useful projects, on the basis of the 8051 and PIC microcontrollers. As we
move through this chapter, we will attempt to keep a dual track, both
hardware and software. Each project is supplied with its hardware circuit
diagram, as well as the software source code in either C-langue or
assembly or both.

APPLICATION CIRCUITS

Sensing Driving Display

Light Sensor Stepper Motor LED Probe

Buzzer X-Y Table LED Blinker

Digital Thermometer ROBOT 7-Segment Display

Digital Voltmeter EEPROM LCD Driver


Programmer

Fig. (9-1). Proposed microcontroller-based applications

343
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

So far, our work with the microcontroller has been to assemble a


program, and load and run it in the simulator. Now we start the
implementation process that we will repeat in many examples throughout
this chapter. Construction of microcontroller-based hardware is
interesting, because you work both sides of the problem, both hardware
and software. In most other fields of computers, you normally specialize
in either the hardware area or the software area. When a problem comes
up, the software people always point to the hardware as the problem and
the hardware people point to the software as the culprit. In our area,
microcontroller system design, a problem is viewed in a sort of stereo,
seeing both from a hardware point of view and at the same time, from a
software point of view. This stereo view gives an insight into the problem
that will ultimately cause the correct diagnosis to be arrived at, usually
much quicker than the two sides together could do.

9-2. LED Blinker (AT89C2051 Microcontroller)


We will start with a simple example that shows how to set up an
Atmel892051 microcontroller-to turn on and off a LED, in a continuous
manner. A basic circuit of the 89C2051 shown here can be made easily
using point-to-point soldering with a simple universal PCB. Use an
ordinary 20-pin socket, do not use a circle-pin socket. D1 is a small dot
LED. U2 can be either 7805 or 78L05. U3 is optional for correcting any
polarity DC adapter. Without the 2051 chip in the socket, checks the
connection, then measures +5V between pin 20 and pin 10. Test the LED
by shorting P1.7 pin to GND.

The list of components:


1 - AT89C2051-24PC Microcontroller,
11.0592 MHz Crystal
1- 7805 Voltage regulator,
DB102 Bridge rectifier
2 - 33pF Capacitors ,
470 uF Capacitor ,
0.1uF Capacitor,
10uF capacitor
1 - 180Ohm Resistors
1- 7805 Voltage regulator
1 – LED

You can test your board with either LED.c, or LED.asm. In the first case
you have to compile the LED.c program, using C51, and download the
resultant LED.hex file to the 2051 microcontroller. If you don‟t have a
C51 compiler, you can compile the LED.asm, using A51 assembler, and
344
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

download the LED.hex file to the 2051 microcontroller Both LED.c and
LED.asm make the LED blink every 0.5 second.

Fig. 9-2. The LED blinker circuit.

The listing of LED.c is as follows:

/* ****************************************************
Simple LED Blinker Program (LED.c)
Complement P1.7 every 0.5 sec
****************************************************** */
#include 8051io.h // include i/o header file
#include 8051reg.h
#define n 50
extern register char cputick; // cputick was incremented every 10ms
register unsigned char sec100,flag1;
/******************************************************************/
task1(); // functions declarations
task2();
/******************************************************************/

345
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

main()
{
flag1 = 0;
sec100 = 0;
serinit(9600); // set timer0 to be 16 bit counter
while(1)
{
while (cputick == 0)
cputick = 0;
task1();
task2();
}
}//***************************************************************

task1() // set bit 0 of flag1 every n*10ms


{
sec100++; // increment sec100
if (sec100 >= n)
{ sec100 = 0; // clear sec100
flag1 |= 0x01; // set bit 0 of flag1
}
} //***************************************************************

task2()
{
if ((flag1 & 0x01) != 0) // execute below if bit 0 of flag1 is set
{
P1 ^= 0x80; // exclusive or the latch bit 7 with 0x80
asm " CPL P1.7"; // complement P1.7
flag1 &= ~0x01; // clear bit 0 of flag1
}
} //**************************************************************

The equivalent assembly code (LED.asm) is as follows:

;*************************************************************** *
; Simple LED Blinker Program (LED.asm)
;****************************************************************
#INCLUDE "8051EQU.INC" ;include predefined constants
;*** ************************************************************
; RESET ; reset routine (not implemented here)
; ***************************************************************
.ORG 0H ; locate routine at 00H
AJMP START ; jump to START (in main program below)
;****************************************** *********************
; INTERRUPTS Entry (not used here). Place interrupt routines at
; appropriate memory locations
.ORG 03H ;external interrupt 0
RETI
.ORG 0BH ; timer 0 interrupt
RETI

346
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

.ORG 13H ;external interrupt 1


RETI
.ORG 1BH ; timer 1 interrupt
RETI
.ORG 23H ; serial port interrupt
RETI
;************************************** *************************
.ORG 25H ; locate beginning of rest of program
;************************************ ***************************
; Subroutines.
;********************************************************* ******
; The DELAYMS and DELAYHS subroutines are for delays so we can slow
; down the blinking so we can see it. Without delay, it will blink
; so fast and looks like it’s always on
;********************************************************* ******
; 1- INITIALIZE Subroutine
;****************************************************************
; This subroutine sets up control registers
INITIALIZE:
MOV TCON,#00H
MOV TMOD,#00H
MOV PSW,#00H
MOV IE,#00H ;disable interrupts (put 0 in IE bit)
RET
;****************************************************************
; 2- DELAYMS Subroutine
;****************************************************************
; This subroutine makes a delay of 1 ms, given that the clock speed
; is 11.059 MHz.

DELAYMS: ; The DELAYMS subroutine starts here


MOV R7,#00H ; put value of 0 in register R7
LOOPA: ; start millisecond delay loop
INC R7 ; increase R7 by one (R7 = R7 +1)
MOV A,R7 ; move value in R7 to A (Accumulator)
CJNE A,#0FFH,LOOPA ;compare A to FFH(256). If not equal go LOOPA
RET ;return to the point that this routine was called from

;********************************************************** ******
; 3- DELAYHS Subroutine
;*****************************************************************
; This subroutine makes a delay of 0.5 sec, given that the clock
; speed is 11.059 MHz.
DELAYHS: ;The DELAYHS delay subroutine starts here
MOV R6,#00H ;put 0 in register R6 (R6 = 0)
MOV R5,#002H ;put 2 in register R5 (R5 = 2)
LOOPB:
INC R6 ; increase R6 by one (R6 = R6 +1)
ACALL DELAYMS ;call the routine above. run and return here.
MOV A,R6 ;move value in R6 to A
JNZLOOPB ;if A is not 0, go to LOOPB
DEC R5 ;decrease R5 by one. (R5 = R5 -1)
MOVA,R5 ;move value in R5 to A
JNZLOOPB ;if A is not 0 then go to LOOPB.
RET
;*********************** ******************************************
; 4- STARTUP_HANDSHAKE Subroutine
;****************************************************************
; The following subroutine is required to convince the 2051
; microcontroller that reset is properly set
;
347
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

STARTUP_HANDSHAKE: ;The STARTUP_HANDSHAKE subroutine starts here


SETB P3.7 ; let P3.7 = 1
LOOK_FOR_ZERO:
JB P3.7,LOOK_FOR_ZERO
CLR P3.7 ; let p3.7 = 0
ACALL DELAYMS
RET
;******************************************************************
; main program
;******************************************************************
;
START: ; On power up, program jumps to this point
ACALL INITIALIZE ;set up control registers
ACALL STARTUP_HANDSHAKE ;set up control registers
LOOP:
CPL P0.0 ;ComPLement (invert) P1.0 (this makes LED change)
ACALL DELAYHS ;go to above routine that causes a delay
AJMP LOOP ;go to LOOP(jump back to point labeled LOOP)
.END ;end program (this point will never be reached!)
;******************************************************************

9-3. Flashing a LED with PIC (PIC16F876 microcontroller)


We‟ll begin with the easy project of flashing an LED on and off. While
this seems simple, even experienced PIC developers often start with this
just to make sure things are working properly. Sometimes, we will flash a
LED on an unused I/O pin just to give visual feedback that the program is
running. In this example, we‟ll flash an LED connected to port B pin 0
(RB0). The PIC I/O can individually sink or source 25 milliamps (mA) of
current. That is more than enough to drive an LED directly. The software
will light the LED for one second, then shut it off for one second, and
then loop around to do it again. While this program is simple, getting the
LED to flash on and off verifies that you successfully wrote the program
in PicBasic, compiled/assembled it, programmed the PIC, and correctly
built the PIC circuit. That is a big first step, and why you‟ll find this first
project very rewarding.

9-3.1. Circuit Diagram


Figure 9-3 shows the schematic for this project; it will become the main
building block for many of your PicBasic designs. It contains a 4-MHz
resonator connected to the PIC OSC1 and OSC2 pins. It also has a 1k
pull-up resistor from the MCLR pin to Vdd voltage of 5 V. These are the
only connections a PIC needs to run besides power and ground. That
makes getting projects going much easier.

348
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

Fig. 9-3. The LED flasher circuit.

9-3.2. MBASIC (PBC) Code


The PBC code for this project is written to turn the B0 pin of Port B on
and off at 1-second intervals. The first part of the program sets up the
symbol LED to represent the Port B pin. This isn‟t necessary, but makes
it easier to read than just putting a “0” everywhere the symbol LED is.
Next, Port B is set for which pins are inputs and which are outputs.
Notice how PBC uses the DIRS directive and outputs are a “1” and inputs
a “0”. Finally, we enter the main code section. We use the High and Low
commands to control Port B pin 0. The Pause command is used to create
the 1-second delay. The main program runs in a continuous loop using
the GOTO command to jump it back to the start

main: label.
„ [ Title ]
„ File...... proj1PBC.bas
„ Language.... PicBasic
„ Purpose... PIC16F876 flash LED
„ ================[ Program Description ]==========
„ This is a simple program written to fl ash an LED by turning it
„ on for one second and off for one second. The LED should be
„ connected to portB pin 0 (16F876 pin 21) with the Cathode to
„ ground and the anode at the PIC. A 100 ohm resistor is used in
„ series with the LED to limit the current.

349
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

„================= [ Code ] =====================

Symbol LED = 0 „Rename pin 0 of portb (PIC 16F84 pin 6) to LED


DIRS = %00000001 „Setup port b as RB7-RB1 inputs, RB0 as output

main: „Label for beginning of main loop


High LED „Set pin 0 of portb high (5 V) which turns the LED on
Pause 1000 „Pause 1000 milliseconds (1 second) with LED on
Low LED „Set pin 0 of portb low (0 V) which turns the LED off
Pause 1000 „Pause for 1 second with LED off
goto main „Jump to the main label and do it all again

END „

350
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-4. Playing Sound


This project shows how we can interface our microcontroller to a buzzer.
When a push-button switch is pressed (e.g. simulating a burglar), the
buzzer will turn on and o 30 times and then stop. Electronic sound
generation requires an audible device. There are several devices:
Piezo sounders: these devices operate by an external DC source.
An internal oscillator applies an AC signal to a piezo substrate and this
causes alternating deformation of the disc, producing sound output. These
devices require about 8 to 20 mA current and generate a sound output of
80 to 100 dBA, at a distance of approximately 30 cm. The frequency
response of these devices is in a narrow band, generally in the region 3 to
5 KHz. Piezo sounders usually emit a single tone but some models can
emit two or more tones and can also provide pulsed tone outputs. Piezo
sounders operate over a wide DC voltage range and as a result of this,
they are widely used in small portable electronic equipment.
Buzzers: these are mechanical devices which produce sound via a
magnetized arm repeatedly striking a diaphragm. These devices operate
with a DC voltage and the current requirement is small, generally in the
region of 10 mA. Buzzers generate a `buzzing' noise (single tone) in the
frequency range 300 to500 Hz. Buzzers are small devices and they can be
either panel mounted or PCB mounted.
Sounders: these audible devices generally operate with a DC
voltage in the range 3 to 24 V. The current requirement is around 15 mA.
The sound output of sounders is single tone at 3 KHz or less, with 80 to
85 dBA at a distance of 30 cm.
Transducers: these devices generally operate with a small DC
voltage (around 3 V) and require external drive circuitry. Sound output is
85 dBA or more at a distance of 30 cm. The resonant frequency of
transducers is 3 KHz or less. These devices are usually used as mini
speakers in PCB mounted applications.
Speakers (Coil type): these devices operate by a coil attracting and
repelling a magnetized diaphragm. Coil type devices are generally used
when multitone sound or speech is required.

The first project shows how to use a microcontroller to synthesize a


sound, at a given frequency. This design is intended for use with an
Atmel 2051 microcontroller (a 20 pin version of the 8051
microcontroller). An 8051 or 8052 can be substituted for the 2051 if the
connections are moved to the appropriate pins on those chips. The circuit
diagram of this application is shown below. Bit 7 of port 1 is connected
directly to a small buzzer. This type of connection is possible if the
current requirement of the buzzer is not more than about 20 mA. The port
351
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

output is in current source mode so that the buzzer will turn on when the
port output is at logic LOW (0 V). Bit 0 of port 3 is connected to a push-
button switch which is normally held at logic HIGH by a pull-up resistor.
The buzzer used in figure is assumed to draw not more than 20 mA and
thus we can connect the buzzer directly to the microcontroller. R2 – 100k,

Fig. (9-3). Circuit diagram of a music synthesizer.

352
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

In this project a continuous single tone output is produced on the speaker


when a push-button switch is activated. Timer interrupt of the
microcontroller is used to generate the time delay required for the tone. In
this project the frequency of the generated tone is 1 kHz (i.e. a period of 1
ms). The circuit diagram of this project is same as the one in Project 12
(i.e. Fig. 4.3) except that the buzzer is replaced with a small speaker. Bit 7
of port 1 is connected directly to a small speaker via a MOSFET
transistor. The port output is in voltage mode so that the speaker will turn
on when the port output is at logic HIGH (5V). Bit 0 of port 3 is
connected to a push-button switch which is normally held at logic HIGH
by the pull-up resistor R2.

Program Description
The speaker is initially turned OFF. The push-button switch is then
checked and when the switch is pressed, timer 1 of the microcontroller is
initialized to generate interrupts at regular intervals. When a timer
interrupt is generated the state of the timer is reversed. i.e. if the timer is
on, it is turned o and if it is o, it is turned on. The frequency of this
waveform is set to be in the audible range and thus it generates an audible
sound on the speaker

Main program
START
Turn OFF speaker
IF push-button switch is pressed THEN
Initialize timer 1 togenerate interrupts every 250 ms
Wait for timer interrupt
END
Timer 1 initialization
START
Enable timer 1 interrupts
Set timer 1 to mode 8-bit auto-reload
Load timer value 6 (i.e. count of 250 ms) intotimer register
Enable microcontroller interrupts
Turn on timer 1
END
Timer 1 interrupt service routine
START
IF 500 ms has elapsed THEN
Complement speaker output
ENDIF
END
353
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

Program Description
The buzzer is initially turned OFF. The push-button switch is then
checked and when the switch is pressed, the buzzer is turned on and o 30
times, with a 1 second delay between each output. The following
pseudocode describes the functions of the program:

#include <AT892051.h>
sbit SPEAKER=P1^7;
sbit PUSH_BUTTON =P3^0;
int count;

/* //////////Timer 1 initialization routine //////////////*/


void init_timer()
{
ET1=1; /* Enable timer 1 int */
TMOD=0x20; /* Timer 1 in Mode 2 */
TH1=0x6; /* 250 ms count */
EA=1; /* Enable Interrupts */
TR1=1; /* Turn ON Timer 1 */
}/*///////////////////////////////////////////////////////////////////*/

/*/////////// Timer 1 interrupt service routine///////// */


timer1() interrupt 3
{
count++; /*Inc. count*/
if(count == 2) /*count=2*/
{
count=0; /*Reset count*/
SPEAKER=~SPEAKER;
}
}/*///////////////////////////////////////////////////////////////////*/

main() /*/////////////////// main program /////////////////*/


{
count=0; /*Initialize count*/
SPEAKER=0; /*Speaker OFF*/
while(PUSH_BUTTON == 1)
{
}
init_timer(); /*Initialize timer*/
}/*/////////////////////////////////////////////////////////////////////*/

354
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-5. Light Sensor (Collecting Light Data and sending it to a PC)


This project shows how to set up a microcontroller-based system that
converts a signal from a light sensor to a 6 bit digital value. This value
can be used by the microcontroller, perhaps for a robotic controller, or as
in this tutorial, sent to the PC. It uses the AT89C2051 microcontroller to
collect data and send it to the PC.

A MAX232 chip is used to convert the signals from and to RS232 levels
for sending and receiving through the serial port. The 2051
microcontroller has a built in analog comparator that is used to make a
simple analog to digital converter to convert the light sensor output to a
digital value. Refer to the diagram below to build the circuit.

Fig. (9-4). Circuit diagram of the light sensor.

9-5.1. The Light Sensor


Light sensors are one of the most common types of sensors. They are
used in night lights, street lights, alarms, toys, cameras, etc. We are using
a CDS (Cadmium Sulfide) light-dependent resistor (LDR) or Photocell to
detect light. The resistance of this sensor varies based on the amount of
light that hits it. The resistance can vary from 300K in the dark to 1K in
the light. Our goal is to convert this into a digital value. We have to
convert the variable resistance into a voltage and then the voltage into a
digital value. To convert the resistance into a voltage, we use a second
resistor Rb. Then assuming that no current goes into pin 13, you can find
355
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

V1. To find V1 you can use Ohms Law. With Vcc = 5V, The Ohm Law
gives you :

(5 - V1) / Rpc = V1 / Rb

where Rpc is the resistance of the sensor (photocell). Then you solve for:

V1 = 5*Rb / (Rpc + Rb)

Then the maximum voltage is when Rpc is at its minimum, 1K. Then

V1max = 5*Rb / (1k + Rb)

The minimum voltage is when

Rpc = 300K. V1min = 5*Rb / (300k + Rb).

Using the equations for V1 max and min you can determine that 5.1K is a
good value for Rb. 5.1K gives you a wide voltage range from minimum
to maximum. 5.1K works well for general light to dark situations. If you
are only interested in bright environments (are you making an outside
robot?) then use a larger value of Rb to shift the light sensitivity range
towards bright lights (Perhaps 50K). Or if you are interested in dark
environments (are you making a robotic vampire dog that barks at the
moon and hides from bright lights?) then use a smaller value of Rb
(perhaps 510). Now we have a sensor voltage, V1, that varies from about
0.1 V to 4.2 V

9-5.2. Analog to Digital Conversion using the 2051


Here we use the built in analog comparator on the 2051 (not a normal
feature of 8051 based chips). The voltage generated by the sensor circuit
is connected to the negative input of the comparator (P1.1) and we will
generate a voltage to connect to the positive input of the comparator
(P1.0). The output of the comparator goes to P3.6. P3.6 is not an external
pin on the 2051. It can only be accessed by the internal software. If the
voltage at P1.0 is higher than P1.1 then P3.6 will be a 1. If the voltage at
P1.0 is lower than P1.1 then P3.6 will be a 0. By using the other 6 Port 1
pins (P1.2 through P1.7) we can generate a voltage using a resistor
network connected to those pins. By changing the values of the Port 1
pins we will get as close as possible to matching the voltage from the
sensor circuit. Then we will have a 6 bit digital value that is a reflection
of the sensor voltage at P1.1.
356
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

Each of the 6 Port 1 pins is connected to V0 through a resistor. Setting a


pin to 0 or 1 subtracts from the voltage at V0 or doesn't. The value of the
resistor determines how much voltage is subtracted. If all 6 pins are set to
1 then no current is flowing through the resistor network and V0 = 5V.
The small resistor on P1.7 (240 ohms) can subtract the most voltage.
When we set it to 0 current flows through Ra and the voltage at V0 goes
down. The exact amount depends on the value of Ra. The resistors are
chosen so they are roughly twice the value of the resistor connected to the
next higher pin. (Ideally they would be exactly double the other value but
it is difficult to get resistors that have exactly the right values.) By
doubling the resistance, the pin can subtract half as much voltage. When
you get to P1.2 with the 10K resistor, it only has a small effect on the
voltage at V0 when you set P1.2 to 0 or 1.

The actual voltage at V0 is determined by the resister Ra. To find a good


value for Ra look at what happens when our digital output is about at the
half way point 011111.

P1.7 is the only pin that is drawing current. Starting at Vcc, the current
goes through Ra and then through the 240 ohm resistor to ground (P1.7 =
0). To make the voltage at V0 equal to 2.5V (half of Vcc), make Ra 240
ohms. But since we know the sensor voltage V1 only goes up to 4.2 V
you may want to make the halfway point by 2.1V. Use 330 ohms for Ra
to get 2.1V

for the halfway digital output of 011111. (We use 011111 as the halfway
point because that means that only the 240 ohm resistor going to P1.7 is
active)

Now we can control the voltage at V0 fairly accurately with P1.2 through
P1.7. To make a small change in voltage, change the lower pins and to
make a large change in voltage change the higher pins. By starting with
P1.7 through P1.2 set to 000000 (P1.7 is on the left and P1.2 is on the
right) and counting up to 111111 you can get 64 different voltages!

To find the right digital output to create the right voltage to match the
voltage at P1.1 (V1), we start at 000000 and count up until the
comparator output at P3.6 switches to 1 to tell us our generated voltage is
higher than the sensor voltage. Then we can "track" the voltage by
adjusting the value up and down depending on the output of the
comparator. Since the comparator only tells us high or low (it can not tell
you if you have an exact match) then one possibly annoying aspect of this
approach is that the P1.2 bit is constantly switching from 0 to 1 to
357
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

0 to 1... as the comparator output tells us we are low, then high, then low.
To avoid having to watch the 6 bit value oscillate (also called jitter) we
just use the top 5 digits as our answer. Look at the documentation in the
software for the 2051 in light.asm for more details on the tracking
routine. For this project we are sending the upper 5 digit value (P1.3
through P1.7) to the PC.

You will need a device programmer to program the 2051. Make sure the
power is off to the circuit you have built. Connect the circuit to the PC's
serial port, Comm1. Connect the power to the breadboard. The circuit
should send a continuous stream of values to the PC. The parts for this
project include:

1 - AT89C2051-24PC Microcontroller
1 - 11.0592 MHz Crystal
2 - 33pF Capacitors
1 - 10 uF Capacitor
1 - 220 uF Capacitor
1 - 8.2k Resistor
5 - 240 Ohm Resistors
5 - 510 Ohm Resistors
5 - 1k Resistors
5 - 2.2k Resistors
5 - 5.1k Resistors
5 - 10k Resistors
5 - 15k Resistors
1 - MAX232
5 - 1 uF capacitors
1 - DB9 connector
1 - CDS Photocell Light Sensor

9-5.3. The Software


The basic process of compiling an assembly language program and
loading it into the microcontroller is so simple. The 2051 assembly
language program for this project light..asm is shown below.
The software (light.asm) is as follows:
;********************* *******************************************
; Light Sensor program (light.asm)
;*****************************************************************
;
#INCLUDE "8051EQU.INC" ;include predefined constants
;
;*** ************************************************************
; RESET ; reset routine (not implemented here)
; ***************************************************************
.ORG 0H ; locate routine at 00H
AJMP START ; jump to START (in main program below)

358
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

;****************************************** *********************
; INTERRUPTS Entry (not used here). Place interrupt routines at
; appropriate memory locations
;****************************************************************
.ORG 03H ;external interrupt 0
; :
RETI
.ORG 0BH ; timer 0 interrupt
; :
RETI
.ORG 13H ;external interrupt 1
; :
RETI
.ORG 1BH ; timer 1 interrupt
; :
RETI
.ORG 23H ; serial port interrupt
; :
RETI
;************************************** *************************
.ORG 50H ;locate beginning of rest of program
;************************************ ***************************
; Subroutines.
;********************************************************* ******
; 1- INITIALIZE Subroutine
;****************************************************************
; This subroutine sets up control registers
;
INITIALIZE: ;set up control registers
;
MOV TH1, #0FDH ;Set up for 9600 baud rate
MOV SCON, #01010000B ;Mode = 8 bit UART
MOV TMOD, #00100001B ;Sets Timer1 to 8 bit auto reload
MOV TCON, #01000000B ;Turns Timer1 on
RET
;****************************************************************
; 2- SEND Subroutine
;****************************************************************
; This routine transmits the value in A through the serial port.
;
SEND:
CLR TI ;Clear Transmit Flag
MOV SBUF, R1 ;Transmit Byte
WAIT:
JNB TI, WAIT ;Wait for transmission to be completed.
RET
;******************************************************************
; main program
;******************************************************************
;
START: ; On power up, program jumps to this point

MOV SP, #030H ;Set Stack Pointer to 30H in RAM


ACALL INITIALIZE ;Set up control registers
MOV A, #00000011B ;Init P1 with P1.0&P1.1 as in, Others 0

;The tracking routine below uses a value stored in A. At the


;beginning of each loop the value in A is moved to P1. The external
;network creates a voltage using the pins of P1. The voltage is
;compared to another voltage using the built in ;ananlog comparator.

359
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

;One voltage goes to P1.0 & the other to P1.1 and ;the result goes to
;P3.6. P3.6 is a 1 if P1.0 is higher and 0 ;otherwise. The routine
;below allows the six bits P1.2 through P1.6 ;to go between 000000
;and 111111.

LOOP:
MOV P1, A ;Move value in A to P1
MOV R2, A ;Move Value to R2 for storage
CLR ACC.0 ;Clear the bits of A that are not
;part of actual light value
CLR ACC.1
CLR ACC.2 ;Ignore Lowest Bit of 5 Digit Value
RR A ;3 "Rotate Right" One Bit Commands
RR A ;Moves the 4 highest bits of light
; value from 0xxx x000 to 0000 xxxx
RR A
MOV R1, A ;Move Value to R1 for transmit to PC
MOV A, R2 ;Restore A to her previous value
ACALL SEND ;Send Value in R1 to PC
JB P3.6, OVER ;Check Comparator. Jump if P1.0 is
;higher voltage than P1.1
CJNE A, #0FFH, INCREMENT ;Don't go over 1111 1111
AJMP LOOP
INCREMENT:
INC A ;INCrment the 8bit value of P1 (in A)
SETB ACC.0 ;Keep A.0 and A.1 at 1 to match P1
SETB ACC.1 ; (and keep P1.0 and P1.1 inputs)
AJMP LOOP
OVER:
CJNE A, #03H, DECREMENT ;Don't go under 0000 0011
AJMP LOOP
DECREMENT:
CLR ACC.0 ;CLeaR A.0 to 0
CLR ACC.1 ;CLeaR A.1 to 0
DEC A ;DECrement the 8bit value of P1(in A)
; Note that A.0 and A.1 will go back to 1s due to DEC operation
AJMP LOOP

.END ;End program

;********************************************************************

360
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-6. Temperature Sensor (Collecting Temperature Data to a PC)


This project shows how to use a microcontroller to interface to the
DS1620 temperature sensor IC. This value can be used by the
microcontroller directly or, as in this tutorial, sent to the PC. It uses the
AT89C2051 microcontroller to collect data and send it to the PC. A
MAX232CPE chip is used to convert the signals from and to RS232
levels for sending and receiving through the serial port.

Fig. (9-5). The temperature sensor circuit

9-6.1. The Temperature Sensor


To get a temperature reading we use the DS1620 integrated circuit. It is
an 8 pin chip that has a built in system that measures the temperature and
converts the reading into a 9 bit binary value. It has an accuracy of 0.5
degrees C and a range of -55 to 125 C. The temperature reading is
updated about once per second. A digital interface is included in the chip
that allows us to connect a microcontroller to the chip and send it
commands and receive the temperature data back from the chip. The
temperature is received in the microcontroller as 2 bytes. The second byte
only contains a sign bit to signify whether the temperature is above or
below 0 degrees Celsius. For this project we are ignoring the sign bit and
just using the first byte. We will assume the temperature is above 0
degrees C (32 F). The value in the first byte is the number of 0.5 degree
increments. For example, if we get a 1 then the temperature is 0.5 C.

361
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

If we get a 10 then the temperature is 5 degrees C. The range of possible


values is 0 to 250 which is 0 to 125 degrees C. (The DS1620 can also
measure down to -55 degrees C).

For this project we are only using the serial interface pins, 1, 2, and 3.
The pins 5, 6, and 7 have other functions that are used in thermostats.
They change from 0 to 1 when a certain temperature is reached (for
example, to turn a heater on and off. The parts for this project includes:

1 - AT89C2051-24PC Microcontroller (unprogrammed)


1 - 11.0592 MHz Crystal
2 - 33pF Capacitors
1 - 10 uF Capacitor
1 - 220 uF Capacitor
5 - 2.2k Resistors
1 - MAX232
5 - 1 uF capacitors
1 - DB9 connector
1 - DS1620 Temperature Sensor

9-6.2. The Software


The 2051 assembly language program for this project is temp.asm. You
will need a device programmer such as the PG302 to download the
program into the 2051. The temp.asm program, shown below,
demonstrates a serial interface with another chip. This is a fairly common
situation. The serial interface can be created with only 2 or 3 pins. There
is usually a clock line and a data line. In this case there is also a control
line called Reset that acts as a control signal, signaling the begining and
end of each communication sequence. The clock is generated by the
microcontroller, giving the microcontroller complete control over the bit
by bit transmission. In this case the microcontroller is responsible for
initiating each exchange of data over the serial link. Another possible
configuration (for example, 2 microcontrollers linked together) could
allow the device on either end to initiate an exchange.

Make sure the power is off to the circuit you have built. Connect the
circuit to the PC's serial port, COM1. Connect the power to the
breadboard. The circuit should send a continuous stream of values to the
PC. The sample program receives the original value and displays it on
the screen. It also converts the value to Celsius and Fahrenheit and
displays those. The software (temp.asm) is as follows:

362
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

;********************************************************************
;* Temperature Sensing Program (temp.asm)
;********************************************************************

#INCLUDE "8051EQU.INC" ;include predefined constants

;*****************************************************************
; Names (Constants)
;*****************************************************************
; Give names to pins to simplify code writing. This also makes it
; easy to change pin assignments later.

DQ .equ P3.5 ; let P3.5 be named DQ (Data Query)


CLK .equ P3.4 ; let P3.4 be named CLK (Clock)
RST .equ P3.3 ; let P3.3 be named RST (Reset)
;
;********************************************************************
; RESET ; reset routine (not implemented here)
; ***************************************************************
.ORG 0H ; locate routine at 00H
AJMP START ; jump to START (in main program below)
;****************************************** *********************
; INTERRUPTS Entry (not used here). Place interrupt routines at
; appropriate memory locations

.ORG 03H ;external interrupt 0


; :
RETI
.ORG 0BH ; timer 0 interrupt
; :
RETI
.ORG 13H ;external interrupt 1
; :
RETI
.ORG 1BH ; timer 1 interrupt
; :
RETI
.ORG 23H ; serial port interrupt
; :
RETI
;*****************************************************************
.ORG 25H ;locate beginning of rest of program
;;****************************************************************
; Subroutines.
;********************************************************* ****** ;
; 1- INITIALIZE Subroutine
;****************************************************************
; This subroutine sets up control registers for serial port
;
INITIALIZE:
; The value in TH1 determines the baud rate.
; The baud rate will either be the low rate or the high rate,
; depending on whether the first bit in PCON is 0 or 1
; To change the baud rate, uncomment the line with the value of TH1
; that you need and comment out the old line. Do the same for PCON.
;
; MOV TH1, #0FFH ;Set up FOR 28800 or 57600 baud rate
; MOV TH1, #0FEH ;Set up for 14400 or 28800 baud rate
MOV TH1, #0FDH ;Set up for 9600 or 19200 baud rate
;
363
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

MOV PCON, #00000000B ; set SMOD for regular baud rate


; MOV PCON, #10000000B ; set SMOD for double baud rate
;
MOV SCON, #01010000B ;Mode = 8 bit UART
MOV TMOD, #00100001B ;Sets Timer1 to 8 bit auto reload
MOV TCON, #01000000B ;Turns Timer1 on
RET
;****************************************************************
; 2- DELAYMS Subroutine
;****************************************************************
; This subroutine makes a delay of 1 ms, given that the clock speed
; is 11.059 MHz.
DELAYMS: ;millisecond delay routine
MOV R7,#00H ;put value of 0 in register R7
LOOPA:
INC R7 ;increase R7 by one (R7 = R7 +1)
MOV A,R7 ;move value in R7 to Accumulator (A)
CJNE A,#0FFH,LOOPA ;compare A to FF (256). If not equal
;go to LOOPA
RET ;return to the point where routine was
; called from
;****************************************************************
; 3- DELAYS Subroutine
;****************************************************************
; This subroutine makes a delay of 1 s, given that the clock speed
; is 11.059 MHz.
DELAYS: ;One second delay routine
MOV R6, #00H ;put 0 in register R6 (R6 = 0)
MOV R5, #004H ;put 5 in register R5 (R5 = 4)
LOOPB:
INC R6 ;increase R6 by one (R6 = R6 +1)
ACALL DELAYMS ;call the routine above. It will run
;and return to here.
MOV A, R6 ;move value in R6 to A
JNZ LOOPB ;if A is not 0, go to LOOPB
DEC R5 ;decrease R5 by one. (R5 = R5 -1)
MOV A, R5 ;move value in R5 to A
JNZ LOOPB ;if A is not 0 then go to LOOPB.
RET
;*******************************************************************
; 4- SEND Subroutine
;*******************************************************************
; This routine transmits the value in A through the serial port.
;
SEND:
CLR TI ;Clear Transmit Flag
MOV SBUF, A ;Transmit Byte
WAIT:
JNB TI, WAIT ;Wait for transmission to be completed.
RET
;
;******************************************************************
; 5- Write1620 Subroutine
;******************************************************************
; This routine writes the value in A to the DS1620
;
WRITE1620:
MOV R0, #08H ; Set Counter for 8 bits
NEXTBITWRITE:
364
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

CLR CLK ; Start clock cycle


RRC A ; Rotate A Right into Carry Bit
; (Lowest Bit in A goes to C)
MOV DQ, C ; Move outgoing bit to DQ
SETB CLK ; Rising Edge of Clock makes one clk cycle
DJNZ R0, NEXTBITWRITE
RET
;
;******************************************************************
; 6- Read1620 Subroutine
;******************************************************************
; This routine reads a value from the DS1620 and puts it in A
;
READ1620:
MOV R0, #08H ; Set Counter for 8 bits
SETB DQ ; Set DQ to 1 to enable it as an input pin
NEXTBITREAD:
CLR CLK ; Start clock cycle
MOV C, DQ ; Move incoming bit to DQ
SETB CLK ; Rising Edge of Clock makes one clk cycle
RRC A ; Rotate A Right via C (C goto High Bit of A)
DJNZ R0, NEXTBITREAD
CLR DQ
RET
;
;******************************************************************
; 7- CONFIGURE Subroutine
;******************************************************************
; Routine to Configure DS1620
CONFIGURE:
SETB RST ; Make 1620 reset go High to start transfer
MOV A, #0CH ; Send the "Write Config" command to 1620
ACALL WRITE1620
MOV A, #00001010H ; CPU = 1, 1Shot = 0, THF = 0, TLF = 0
ACALL WRITE1620 ; Send the Configuration Byte
CLR RST ; Make 1620 RST go Low to end transfer
RET
;
;*******************************************************************
; 8- START_CONVERT Subroutine
;******************************************************************;
; Routine to Start Temperature Conversion on 1620
;
START_CONVERT:
SETB RST ; Make 1620 reset go High to start transfer
MOV A, #0EEH ; Send the "START CONVERT" command to 1620
ACALL WRITE1620
CLR RST ; Make 1620 reset go Low to signal end transfer
RET
;
;********************************************************************
; 9- READ_TEMPRATURE Subroutine
;******************************************************************;;
Routine to Read Temperature from 1620
;
READ_TEMPERATURE:
SETB RST
MOV A, #0AAH ; Send the "Read Temperature" command
ACALL WRITE1620
365
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

ACALL READ1620 ; Get first byte of temperature


MOV R1, A ; Store Byte in R1
ACALL READ1620 ; Get second byte of temperature
MOV R2, A ; Store Byte in R2
CLR RST ; End Transfer
RET
;
;******************************************************************
; main program
;******************************************************************
;
START: ; On power up, program jumps to this point

MOV SP, #030H ;Set Stack Pointer to 30H


ACALL INITIALIZE ;Set up control registers
SETB CLK ; Start with CLK equal to 1
ACALL CONFIGURE ; Configure DS1620
;********************************************************************
; wait 10 MS for Configuration to be Written

ACALL DELAYMS
ACALL DELAYMS
ACALL DELAYMS
ACALL DELAYMS
ACALL DELAYMS
ACALL DELAYMS
ACALL DELAYMS
ACALL DELAYMS
ACALL DELAYMS
ACALL DELAYMS

LOOP:
ACALL START_CONVERT ; Send command to Start conversion
ACALL DELAYS
ACALL READ_TEMPERATURE ; Get Temperature Reading
MOV A, R1
ACALL SEND ; Send value to serial port
AJMP LOOP ;go to LOOP(jump back to point labeled LOOP)

.END ;end program (this point will never be reached!)


;
;*******************************************************************

366
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-7. Data Collection (Analog Data Acquisition)


This project shows how to set up a system for collecting data through a
computers serial port. It uses an ADC0804 chip to convert from analog
to digital, an AT89C2051 microcontroller to control the ADC0804 and
send data to the PC, and a MAX232CPE chip to convert the signals from
and to RS232 levels for sending and receiving from the PC. Refer to the
diagram below as you go through the individual steps in building the
circuit.

Fig. (9-6). Circuit diagram of the data collector.


367
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-7.1. Analog to Digital Conversion - The ADC0804 IC

The easiest way to do analog to digital conversion is to use a ready-made


IC such as the ADC0804 that does the work for you. The analog voltage
is applied to pin 6 and the result is available at pins 11 through 18. We
will connect pin 1 (Chip Select) to ground so that the chip is always
enabled. If you wanted to use more than one ADC you could use this pin
to control which chip is currently enabled.

The ADC0804 includes an internal oscillator which requires an external


capacitor and resistor to operate. Connect the 150 pF capacitor from pin 4
to ground and the 10k ohm resistor from pin 4 to pin 19. Also for power,
Connect pin 20 to 5 V. Connect Pin 8 to ground. Connect pin 10 to
ground.

9-7.2. Interfacing the ADC0804 to the 2051


As we mentioned so far, the Atmel AT89C2051 is a 20 pin version of the
8051 and uses the same language. For more information about
programming the chip, refer to Appendix F. To control the analog-to-
digital converter ADC0804, we will use 3 lines from the Atmel 2051.

Connect pin 2 (Read) from the ADC0804 to pin 7 (P3.3) of the 2051.
Connect pin 3 (Write) to pin 8 (P3.4). Connect pin 5 (Interrupt) to pin 9
(P3.5). The 8 bit Output Data from the ADC0804 will be connected to
Port 1 of the 2051. Connect pin 18 (D0) of the ADC0804 to pin 12 of the
2051 (P1.0). Connect pin 17 (D1) to pin 13 (P1.1). Connect pin 16 (D2)
to pin 14 (P1.2). Connect pin 15 (D3) to pin 15 (P1.3). Connect pin 14
(D4) to pin 16 (P1.4). Connect pin 13 (D5) to pin 17 (P1.5). Connect pin
12 (D6) to pin 18 (P1.6). Connect pin 11 (D7) to pin 19 (P1.7).
368
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

The 2051 pins 12 and 13 do not have internal pull up resistors so external
pull up resistors are required. Connect a 2.2k ohm resistor from pin 12 of
the 2051 to 5V. Connect a 2.2k ohm resistor from pin 13 of the 2051 to 5
V. To power the 2051, Connect pin 20 of the 2051 to 5V. Connect pin 10
of the 2051 to ground.

For the 2051 oscillator, Connect the 11 MHz Crystal from pin 4 of the
2051 to pin 5 of the 2051. Connect one 33 pF capacitor from pin 4 of the
2051 to ground. Connect the other 33 pF capacitor from pin 5 of the 2051
to ground.

For the 2051 reset circuit, Connect the 8.2k ohm resistor from pin 1 of the
2051 to ground. Connect the 10uF capacitor from pin 1 of the 2051 to 5V.
The 2051 controls the analog to digital conversion process. The
conversion process has several stages.
Stage 1) To trigger a new conversion, we must make pin 3 (Write) low
and then return it to the high state. The conversion process starts when
Write goes high (rising edge triggered).

Stage 2) When the conversion process is complete, pin 5 (Interrupt) will


go low.

Stage 3) When we see pin 5 (Interrupt) go low, we must make pin 2


(Read) low to load the new value into the outputs D0 - D7.

Stage 4) Next we read the values into the 2051 Port 1.

Stage 5) Finally, we return pin 2 (Read) to the high state. The next
conversion can be started immediately

9-7. 3. Communicating with the PC (via MAX232)


Now that we have the 8 bit value in the 2051, we want to send that value
to the PC. The 2051 has a built in serial port that makes it very easy to
communicate with the PC's serial port but the 2051 outputs are 0 and 5 V
and we need +10 and -10 V to meet the RS232 serial port standard. The
easiest way to get these values is to use the MAX232. The MAX232 acts
as a buffer driver for the processor. It accepts the standard digital logic
values of 0 and 5V and converts them to the RS232 standard of +10 and -
10 V. It also helps protect the processor from possible damage from static
that may come from people handling the serial port connectors.

369
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

The MAX232 requires 5 external 1uF capacitors. These are used by the
internal charge pump to create +10Vand -10V. For the first capacitor, the
negative leg goes to ground and the positive leg goes to pin 16. For the
second capacitor, the negative leg goes to 5 V and the positive leg goes to
pin 2. For the third capacitor, the negative leg goes to pin 3 and the
positive leg goes to pin 1. For the fourth capacitor, the negative leg goes
to pin 5 and the positive leg goes to pin 4. For the fifth capacitor, the
negative leg goes to pin 6 and the positive leg goes to ground.

The MAX232 includes 2 receivers and 2 transmitters so two serial ports


can be employed. We will only use one transmitter in this project. The
only connection that must be made to the 2051 is one jumper from pin 3
of the 2051 to pin 11 of the MAX232. To power the MAX232, Connect
pin 16 to 5V and Connect pin 15 to ground.

The only thing left is that we need some sort of connector to connect to
the serial port. The sample code below is written for Comm1 and most
computers use a 9 pin DB9 male connector for Comm1 so a 9 pin female
connector is included for this project. You may also want to buy a DB9
extension cable (Shown on order form as DB9 to DB9 cable) to make the
connection easier. There should be 3 wires soldered to the DB9 connector
pins 2, 3 and 5. Connect the pin 5 wire to ground on the breadboard.
Connect the wire from pin 2 of the connector to pin 14 of the MAX232.
The other wire is for receiving and is not used in this project.

9-7.4. The Software


The 2051 assembly language program for this project is adcproj.asm.
You will need a device programmer such as the PG302 to program the
2051. Make sure the power is off to the circuit you have built. Connect
the circuit to the PC's serial port, Comm1. Turn on the power to the
breadboard. The circuit should send a continuous stream of values to the
PC. This program takes the received value and divides it by 51 to find
the corresponding voltage level. (The minimum value is 0 which is 0V
and the maximum value is 255 which is 5V.)
;********************************************************************
;* Data Collection program
;********************************************************************
#INCLUDE "8051EQU.INC" ;include predefined constants
;********************************************************************
; VARIABLES AND CONSTANTS
;********************************************************************
; PORT USAGE
; Port1 - ADC Result (Input)
; P3.5 - ADC Complete (Input Active Low)
; P3.4 - Start ADC (Output Active Low)
370
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

; P3.3 - Load values to output (Output Active Low)


;
;********************************************************************
; RESET ;reset routine
.ORG 0H ;locate routine at 00H
AJMP START ;jump to START
;********************************************************************
; INTERRUPTS (not used) ;place interrupt routines at appropriate
;memory locations
.ORG 03H ;external interrupt 0
RETI
.ORG 0BH ;timer 0 interrupt
RETI
.ORG 13H ;external interrupt 1
RETI
.ORG 1BH ;timer 1 interrupt
RETI
.ORG 23H ;serial port interrupt
RETI
;********************************************************************
;
.ORG 25H ;locate beginning of rest of program
;
;********************************************************************
; 2- INITIALIZE Subroutine
;********************************************************************
; This routine sets up control registers

INITIALIZE:
MOV TH1, #0FDH ;Set up for 9600 baud rate
MOV SCON, #01010000B ;Mode = 8 bit UART
MOV TMOD, #00100001B ;Sets Timer1 to 8 bit auto reload
MOV TCON, #01000000B ;Turns Timer1 on
RET
;********************************************************************
; 2- SEND Subroutine
;********************************************************************
; This routine transmits the value in A through the serial port.
;
SEND:
CLR TI ;Clear Timer1 Flag
MOV SBUF, A ;Transmit Byte
WAIT:
JNB TI, WAIT ;Wait for transmission to be completed.
RET
;********************************************************************
; main program
;******************************************************************
;
START: ; On power up, program jumps to this point
MOV SP, #030H ;Set Stack Pointer to 30H
ACALL INITIALIZE ;Set up control registers
ORL P1,#0FFH ;Make Port 1 an input port
SETB P3.5 ;Make P3.5 an Input pin
LOOP:
CLR P3.4 ;Prepare for A/D Conversion
SETB P3.3 ;Set Read to High
SETB P3.4 ;Start Analog to Digital Conversion
WAITFORDONE:
JB P3.5, WAITFORDONE ;Wait until Conversion is complete

371
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

CLR P3.3 ;Load 8 bit value to ADC0804 Outputs


MOV A,P1 ;Read ADC0804 Output
ACALL SEND ;Send Value to PC
SETB P3.3 ;Disable ADC0804 Output
AJMP LOOP ;Go to LOOP(jump back to point LOOP)
.END ;End program

9-7.5. Testing the Circuit


To test your circuit, connect various voltages to pin 6 of the ADC0804. If
you connect a jumper from pin 6 to 5 V, the voltage on the sample
program should say 5V. Remove the jumper.

Try connecting a 2.2k resistor from pin 6 to ground and another 2.2k
resistor from pin 6 to 5V. The result should be around 2.5V. Remove the
resistors.

Try playing with the 220 uF capacitor and the 15k Ohm resistor. Connect
the negative leg of the capacitor to ground and the positive leg to pin 6 of
the ADC0804. Connect the resistor from pin 6 to 5V. The voltage should
rise quickly and then slower as it approaches 5V. Now remove the
resistor. The voltage should stay at the same voltage and slowly decay as
the capacitor loses its charge. Connect the resistor from pin 6 to ground to
quickly discharge the capacitor.

9-8. Stepper Motor Driver


This project shows how to build a stepper driver using atmel 2051. M1 is
a stepper taken from an old CD drive or hard disk drive. There are five
pins, namely, common, coil 1, 2, 3 and 4. Resistance measured between
common pin and each coil is about 75 Ohms. Driving current for each
coil is then needed about 60mA at +5V supply.

A Darlington transistor array, ULN2003 is used to increase driving


capacity of the 2051 chip. Each output provides 500mA max at 50V. P1.4
to P1.7, four output pins are connected to the input of the ULN2003 as
shown in the circuit. Four 4.7k resistors help the 2051 to provide more
sourcing current from the +5V supply. The serial port is optional for your
project.

A stepper motor is an electromagnetic device that converts electrical


pulses into mechanical rotational steps. The stepper motor rotation angle
is proportional to the input pulses. One of the most significant advantages
of stepper motors is their ability to be accurately controlled in open loop.
Unlike servo motors, a stepper motor doesn‟t need to expensive feedback
and position sensing devices, such as optical encoders.

372
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

Figure (9-7): Circuit Diagram of the stepper motor driver.

There exist 3 basic types of stepper motors, namely: Variable reluctance


(VR) stepper motors, permanent magnet (PM), and hybrid motors.
Permanent magnet motors maybe unipolar or bipolar motors.

Fig. (9-8). Cross section of a permanent magnet bipolar stepper motor.


373
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

The following table indicates the most common drive modes of a


stepper motor.
1. The Wave drive (1 phase is on at a time, ABAB)
2. Full-step drive (2 phases on at a time, ABABABAB)
3. Half-step drive (1&2 phases on, ABBABA
ABBABA)

Table 8-10. Stepping modes of the stepper motor


Wave drive Full step drive Half-wave drive
Phase 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8
A 1 1 1 1 1 1
B 1 1 1 1 1 1
A 1 1 1 1 1 1
B 1 1 1 1 1 1

9-8.2. Software
The following program describes the stepper motor driver. The 10ms
time base is changed with a simple TF0 polling instead of using interrupt.
The program is just to send the stepper's energizing pattern to the P1
every 10ms. Flag1 is used for inter-task communication.

C-Program
/********************************************************
* STEPPER.C
********************************************************/
#include 8051io.h
#include \8051reg.h
#define n 400
register unsigned char j, flag1, temp;
register unsigned int cw_n, ccw_n;
unsigned char step[8]={0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90}
flag1 mask byte
0x01 run cw()
0x02 run ccw()

main()
{
flag1=0;
serinit(9600);
disable(); /* no need timer interrupt */
cw_n = n; /* initial step number for cw */
flag1 |=0x01; /* initial enable cw() */

374
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

while(1)
{
tick_wait(); // wait for 10ms elapsed
energize(); // round-robin execution the following tasks every 10ms
cw();
ccw();
}
}//********************************************************
cw()
{
if((flag1&0x01)!=0)
{
cw_n--; /* decrement cw step number */
if (cw_n !=0)
j++; /* if not zero increment index j */
else
{
flag1&=~0x01; /* disable cw() execution */
ccw_n = n; /* reload step number to ccw counter */
flag1 |=0x02; /* enable cww() execution */
}
}
}//********************************************************

ccw()
{
if((flag1&0x02)!=0)
{
ccw_n--; /* decremnet ccw step number */
if (ccw_n !=0)
j--; /* if not zero decrement index j */
else
{
flag1&=~0x02; /* disable ccw() executon */
cw_n = n; /* reload step number to cw counter */
flag1 |=0x01; /* enable cw() execution */
}
}
}//********************************************************

tick_wait(){ /* cputick was replaced by simpler ASM code 10ms wait */


asm" JNB TCON.5,*"; /* wait for TF0 set */
asm" CLR TCON.5"; /* clear TF0 for further set */
asm" ORL TH0,#$DC"; /* reload TH0 with $DC, TL0 = 0 */
}//********************************************************
energize()
{
P1 = step[(j&0x07)]; /* only step 0-7 needed */
}//********************************************************

375
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-9. Clock Controller


The Clock Controller, shown in figure below, was designed to be an
exemplary of using 'C' language to control timer0 interrupt, 7-segment
LED and keypad scanning. It provides 1-bit sink current driving output,
for driving a voltage (mains) load via a relay, or opto-triac. Many projects
requiring 7-segment display and keypad interfacing may get the idea from
the clock circuit and software.

Figure (9-8). The clock controller circuit.

As shown in figure, you need a 89C2051, a 4-digit 7-SEG LED module


and a 4-key switch . As show in figure, The bits P1.0-P1.7 drives the 7-
segment common anode LED with sink current. P3.0-P3.3 also drives a
base pin of 4-PNP transistor, 2N2907 with sink current. The 2nd 2-digit
LED that connected to P3.2 and P3.3 is rotated 180 degrees to the 1st 2-
digit allowing the point segment to be used for 1 second blinking. P3.0-
P3.3 also connects four momentary switches while the other legs are tied
to input port P3.4.

During display and key switch scanning, a logic '0' is shifted from P3.0 to
P3.3, if there was a key pressed, P3.4 then became low. P3.7 is a 1-bit
sink current which can drive an external load. For example, the circuit
uses a 2N2907 transistor, connected to P3.7 to drive a small 5V relay.
The P3.7 and can also control an AC load through a TRIAC, like
MOC3040.

376
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-9.1. Software
The program clock.c is written in „C‟ language and can be complied by
any C51 compiler. The hex file of clock.c suitable for downloading by
Easy-Downloader is clock.hex. The Clock1.c was modified for C51
compiler. The function that updates real-time clock was moved into
timer0 interrupt service routine. The HEX file is Clock1.hex smaller than
compiled by Micro-C.

C-Program

/* ********************************************************
CLOCK.C

* **** **** ****


* * * * * * * *
* * * * * * *
* **** * * * *
* * * * * * *
* * * * * * * *
* **** **** ****
set set time manual
HOUR MIN ON/OFF ON/OFF
**********************************************************/

#include c:\mc51\8051io.h
#include c:\mc51\8051reg.h

extern register char cputick;


unsigned register char sec100, sec, sec5, min, hour, flag1, command, ACC, temp,
opto;
unsigned register char i, digit, buffer[4], onHour1, onMin1, offHour1, offMin1;
register char key, delay, count1;
char convert[10] = {0x3F, 0x0c, 0x76, 0x5e, 0x4d, 0x5b, 0x7b, 0x0e, 0x7f, 0x5f};

//****************************************************

main()
{
opto = 0xff;
cputick = 0;
hour = 18;
min = 0;
sec = 0;
key = -1;
flag1 = 0;
onHour1 = 18; /* 18:30 turn lamp on */
onMin1 = 01;
offHour1 = 18; /* 21:30 turn off */
377
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

offMin1 = 02;
count1 = 0;
buffer[0] = 0x40;
buffer[1] = 0x40;
buffer[2] = 0x40;
buffer[3] = 0x40;
serinit(9600); /* must be invoked for tiny model */

while(1)
{
while ( cputick < 1)
scanLED();
cputick = 0;
/************the following tasks execute every 10ms ********/
time();
timeToBuffer();
blink();
offmsd();
keyexe();
keydelay();
comparetime();
}
}//****************************************************
/* ************* change constant below for other Xtal ********/
time () /* update real-time clock */
{
sec100++;
if (sec100 >= 100) /* 100 * 10 ms = 1 s */
{sec100 = 0;
flag1 |= 0x05; /* set bit 0, bit 2 */
temp = 50;
sec++;
if (sec >= 60)
{sec = 0;
flag1 |= 0x02; /* set bit 1 */
min++;
if (min >= 60)
{min = 0;
hour++;
if (hour >= 24)
{hour = 0;
}
}
}
}
}//****************************************************
/* scan 4-digit LED and 4-key switch, if key pressed key = 0-3 else key = -1 */

378
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

scanLED()
{
int i;
digit = 0x08; key = -1;
for( i = 0; i < 4; i++) /* 4-DIGIT scanning */
{
P3 = ~digit & opto; /* send complement[digit] */
P1 = ~buffer[i]; /* send complement[segment] */
pause(1); /* delay a while */
P1 = 0xff; /* off LED */
if ((P3 & 0x10) == 0) /* if key pressed P3.4 became low */
key = i; /* save key position to key variable */
digit>>=1; /* next digit */
}
}//****************************************************
timeToBuffer()
{
buffer[0] = convert[min%10];
buffer[1] = convert[min/10];
buffer[2] = convert[hour%10];
buffer[3] = convert[hour/10];
}//*****************************************************
blink()
{
if((flag1 & 0x04) != 0) /* check bit 2 if set decrement temp until zero */
{temp--;
if (temp != 0)
{
buffer[1] |= 0x80;
buffer[2] |= 0x80;
}
else( flag1 &= ~0x04);
}
}//****************************************************
keyexe()
{
if (key != -1)
{
if ((flag1 & 0x80) == 0)
/* within 0.5 sec after 1st press the following execution is not allowed */
{
flag1 |= 0x80;
delay = 50;
switch(key){
case (0): /* key position 0 */
manualOnOff(); /* service key 0 */
break;
case (1): /* key position 1 */
savetimeOnOff1(); /* service key 1 */
break;
379
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

case (2): /* key position 2 */


setmin(); /* service key 2 */
break;
case (3): /* key position 3 */
sethour();
}
}
}
}//****************************************************

sethour()
{
hour++;
if ( hour== 24)
hour = 0;
}//*****************************************************
setmin()
{
min++;
sec = 0;
if( min == 60 )
min = 0;
}//*****************************************************

savetimeOnOff1()
{
count1++;
if (count1 == 1)
{
onHour1 = hour;
onMin1 = min;
buffer[0] = 0x00;
buffer[1] = 0x68;
buffer[2] = 0x78;
buffer[3] = 0x71;
showOnce();
}
else
{
count1 = 0;
savetimeOff1();
}
}//****************************************************

savetimeOff1()
{
offHour1 = hour;
offMin1 = min;
buffer[0] = 0x63;
380
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

buffer[1] = 0x63;
buffer[2] = 0x78;
buffer[3] = 0x71;
showOnce();
}//****************************************************

manualOnOff()
{
opto= ~opto | 0x7f; /* complement bit 7 which in turn activates P3.7 */
if ((opto & 0x80) == 0)
{
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0x68;
buffer[3] = 0x78;
showOnce();
}
else
{
buffer[0] = 0;
buffer[1] = 0x63;
buffer[2] = 0x63;
buffer[3] = 0x78;
showOnce();
}
}//*****************************************************
showOnce()
{
int i;
for(i=0;i<500;i++)
scanLED();

}//*****************************************************
keydelay()
{
if ((flag1 & 0x80) !=0)
{
delay--;
if(delay == 0)
flag1 &= ~0x80;
}
}//*****************************************************
comparetime()
{
if((flag1 & 0x01) != 0 )
{
flag1 &= ~0x01;
if(hour == onHour1 && min == onMin1)
opto = 0x7f; /* clear P3.7 turning opto on */
381
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

if(hour == offHour1 && min == offMin1)


opto = 0xff; /* set bit P3.7 turning opto off */
}
}//*****************************************************

offmsd()
{
if (buffer[3] == 0x3f) /* if msd = '0' then put blank unstead */
buffer[3] = 0x00;
}//*****************************************************

pause(j)
{
int i., j;

for (i = 0; i < j; i++)


;
}//*****************************************************

9-10. Digital Thermometer (0-100 °C) with LCD


The Digital Thermometer project shows how to use 'C' language, a
program a dual-slope analog-to-converter (ADC), an LCD driver, and
also demonstrates some digital filtering techniques.

9-10. 1. Hardware Description


The Digital Thermometer is a device designed for measuring time and
temperature. The circuit of the Digital thermometer employs the
89C4051, 20-pin Microcontroller with built-in 4kB code memory.
Temperature is measured by LM35D, National Semiconductor
Temperature sensor which produces 10mV/°C. The CA3162 ADC, is
actually a 3-digit DVM (digital voltmeter) which converts DC output
provided by LM35D and sends BCD output to port1 (P1.0-P1.3). The
program resided in code memory of 89C4051 was written in „C‟
language, thermo.c. The program read BCD output from the A/D
converter, performs digital filtering,9-point moving average, and sends
the output reading to a 16x1 line LCD display. A 10ms cputick was used
as a timebase producing 1s for time counting. The LCD displays time in
1s and temperature in 0.1°C resolutions.

Figure (9-9) depicts the circuit diagram of the Digital Thermometer. The
MCU is ATMEL 89C4051 CMOS Microcontroller having 4kB code
memory, 128 bytes On-chip RAM and 8-bit Port1 and Port3. The A/D
chip is HARRIS CA3162, 3-digit DVM. The A/D converter employs
dual-slope integrator providing 10Hz sampling rate. Digital output sent to
MCU is multiplex four bit BCD started from MSD, LSD and NSD
382
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

respectively. The MSD signal was tied to P3.7 indicating first digit ready
to be read. Integrating capacitor is a 330nF Polyester type. The 10k POT
connected to pin13 is a gain adjustment and 50k POT to pin 8 and 9 is for
zero adjustment. The input of the converter is true differential pin 11 for
HI and pin 10 LO signal. Temperature was measured by a precision solid-
state sensor from National Semiconductor, LM35D. The output signal is
10mV/°C. Since the A/D converter is capable of providing 0-1000mV
reading with 1mV resolution, thus the converter can resolve 0.1°C (not
absolute accuracy). A 100k and 0.02uF forms a first order low-pass filter
used to be front-end hardware filtering. The 16x1 line LCD is connected
in 4-bit interfacing to P1.4-P1.7 with control signal RS and E to P3.4 and
P3.5 respectively. The +5V power supply uses a 78L05 voltage regulator
(TO92 case) with external +9V adapter.

Figure (9-9). : Circuit diagram of the Digital Thermometer.

383
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-10. 2. Software
The program thermo.C that control the Digital thermometer is
written in „C‟ language and can be compiled by any C51
Compiler The memory model is TINY that use minimal
hardware, i.e., single chip mode. The hex file of thermo.C
suitable for downloading by Easy-Uploader is thermo.hex.
Variables and stack use the area of 128-byte on-chip RAM. The
algorithm of the control program (in the form of a pseudo code)
is as follows:

initialize timer0
init variable
init LCD module
put title message to LCD buffer
do forever
{
do the following tasks every 100 ms;
time(); // update time base
putxin(); // put converted digital data to 9-word FIFO buffer
puttemp(); // put temperature reading to LCD
puttime(); // put second counter to LCD
}
The main program separates tasks into four tasks, namely, time(),
putxin(), puttemp(), and puttime(). These tasks were executed every
100ms. Time() set FLAG1 bit0, bit1 and bit2 when time has elapsed
100ms, 1st 10 count, and 1s respectively. Putxin() shifts a converted
digital word to LSW of 9-word registers performing 9-point data moving.
Puttemp() computes average value of 9-sample and put to LCD buffer.
Similarly puttime() writes variable count to LCD buffer.

The device driver routines are readadc(), read BCD from CA3162,
LCDINI( ), initialize LCD, LCDWI(), write LCD instruction, LCDWD( ),
write ASCII code to LCD buffer, pulseE() generates Enable pulse, and
delay(n), delay n milliseconds. As seen in the listing of thermo.c
program, some function has embedded assembly code because of time
critical requirements. The variables ACC and temp are used to pass value
to and from „C‟ program. Please study in details writing style and
variables usage.
384
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-10.3. ADC Adjustment


Before inserting LM35D, ADC needs an adjustment by adjusting ZERO
which done by short pin HI and LO to GND. Then adjust 50k POT at pin
8 and 9 until temperature reading is 0. Put the reference voltage source
500mV to input of the A/D, adjust 10k POT until display shows 50.0.

C-Program
/*******************************************************************
Thermo.C
Thermo.c is a source program for interfacing 89C4051 with CA3162 9-bit ADC and
16x1 line LCD display. LM35 is used to be temperature sensor, 10ms cputick
generates 100 ms timebase. LCD display shows time in sec unit and temperature in
Celcius. FIR filters do filtering raw data producing 0.1 C reading.
*******************************************************************/

#include 8051io.h
#include 8051reg.h

extern register char cputick; /* cputick increments by 1 every 10 ms */


unsigned register int count, i,adc, min, max;
unsigned register char sec100, sec10, ACC, initcount, flag;
unsigned register int msd, nsd,l sd;
unsigned register int xin[10];
//******************************************************

main()
{
TMOD = 0x21; /* set timer0 to 16-bit counter */
serinit(9600);
cputick = 0;
i = 0;
count=0;
sec100=0;
sec10=0;
flag = 0;
initcount=0;
asm "E EQU $B5"; /* bit define for P3.5 and P3.4 */
asm "RS EQU $B4";
asm " CLR E";
asm " CLR RS";
P1 = 0;
delay(5);
i_LCD();
puttitle();
delay(5000); /* show quantities to be measured */
flag |= 0x04;
385
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

puttime();
xin[0]=10000;
flag |= 0x02; /* show invalid display by putting out-of-range xin value */
puttemp();
TCON = 0x59;
while(1) /* run continuously */
{
do
{
; /* put tasks require 51's speed here */
}
while ( cputick < 10); /* 10 * 10 ms = 100 ms */
cputick = 0;
/* put tasks requires 100 ms tick here */
asm " setb $b0";
time(); /* update time base */
putxin(); /* put converted digital data to 9-word buffer */
puttemp(); /* put temperature reading to LCD */
puttime(); /* put second counter to LCD */
asm " clr $b0";
}
}//******************************************************
time()
/* flag
%00000001 set bit0 every 100 ms
%00000010 set bit1 after first 9-samples
%00000100 set bit2 every 1 s
*/
{
sec100++;
if (sec100 >= 1) /* 1 * 100 ms = 100 ms */
{sec100 = 0;
sec10++;
initcount++;
flag |= 0x01; /* set bit 0 in flag */
if (initcount >= 10)
{
initcount = 10;
flag |= 0x02;
}
if (sec10 >= 10)
{ sec10 = 0;
count++; /* increment count every 1 sec */
flag |= 0x04;
/* sendreading(); */
}
}
}//******************************************************

386
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

pause(j)
int j;
{
int i;
for (i = 0; i < j; i++) ;
}//******************************************************

LCDWI(A) /* write instruction to LCD */


char A;
{
ACC = A; /* use ACC for interfacing to Assembly */
asm {
MOV A,ACC
CLR RS
CLR E
MOV P1,A
SETB E
NOP
CLR E
SWAP A
MOV P1,A
SETB E
NOP
CLR E
}
pause(1);

}//******************************************************

LCDWD(A)
char A;
{
ACC = A; /* use ACC for interfacing to Assembly */
asm {
MOV A,ACC
SETB RS /* write data */
CLR E
MOV P1,A /* check for p1.0-p1.4 */
SETB E
NOP
CLR E
SWAP A
MOV P1,A
SETB E
NOP
CLR E
}
pause(1);
}//******************************************************

387
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

i_LCD() /* initialize LCD in accordance with Hitachi 44780 4-bit */


{
P1 = 0x30;
pulseE();
delay(10);
pulseE();
delay(1);
pulseE();
delay(1);
P1 = 0x20;
pulseE();
pulseE();
pulseE();
LCDWI(0x28); /* function set 4-bit bus, 1/16 line, 5*7 dots */
LCDWI(0x0c); /* display on/off on display,off cursor, no blink */
LCDWI(0x06); /* entry mode DDRAM address + */
LCDWI(1); /* clear display */
delay(5);
}//******************************************************

pulseE()
{
asm{
SETB E
NOP
CLR E
}

}//******************************************************
puttime()
{
int temp;
char zero;
if ((flag & 0x04) == 4)
{
flag &= ~0x04;
zero = 0;
LCDWI(0x80); /* leftmost digit */
if (count/10000 != 0)
{
LCDWD(count/10000+48);
zero = 1;
}
else LCDWD(' ');
temp = count%10000;
if ((zero == 0) && (temp/1000 == 0))
LCDWD(' ');
else {
LCDWD(temp/1000+48);
388
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

zero = 1;
}
temp = temp%1000;
if ((zero == 0) && (temp/100 == 0))
LCDWD(' ');
else {
LCDWD(temp/100+48);
zero = 1;
}
temp = temp%100;
if ((zero == 0) && (temp/10 == 0))
LCDWD(' ');
else LCDWD(temp/10+48);
temp = temp%10;
LCDWD(temp+48);
LCDWD(' ');
LCDWD('s');
LCDWD(' ');
}
}//******************************************************

/*
puttime()
{
int temp;
char zero;
zero = 0;
LCDWI(0x80); /* leftmost digit */
LCDWD(' ');
LCDWD(count/10000+48);
temp = count%10000;
LCDWD(temp/1000+48);
temp = temp%1000;
LCDWD(temp/100+48);
temp = temp%100;
LCDWD(temp/10+48);
temp = temp%10;
LCDWD(temp+48);
LCDWD(' ');
LCDWD('s');
}//******************************************************/

time1ms() /* 1 ms delay with XTAL 11.0592MHz */


{
int i;
for (i = 0; i < 8 ; i++)
;
}

389
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

delay(n) /* do nothing n*1ms */


int n;
{
int i;
for (i=0; i< n ; i++)
time1ms();

}//******************************************************

int readtemp()
{
P1 = 0xff; /* make P1.0 to P1.3 to be input port */
asm " SETB $B7";
asm " JNB $B7,*";
asm " JB $B7,*";
delay(1);
msd = (P1 & 0x0f);
delay(2);
P1 = 0xff;
lsd = P1 & 0x0f;
delay(2);
P1 = 0xff;
nsd = (P1 & 0x0f);
return(msd*100+nsd*10+lsd);

}//******************************************************

putxin() /* put raw data to FIFO buffer */


{
if ((flag & 0x01) ==1)
{
flag &= 0xfe;
xin[9]=xin[8];
xin[8]=xin[7];
xin[7]=xin[6];
xin[6]=xin[5];
xin[5]=xin[4];
xin[4]=xin[3];
xin[3]=xin[2];
xin[2]=xin[1];
xin[1]=xin[0];
xin[0]=readtemp();
}
}//******************************************************
int average()
{
return((xin[0]+xin[1]+xin[2]+xin[3]+xin[4]+xin[5]+xin[6]+xin[7]+xin[8]+xin[9])/10)
;
}//******************************************************

390
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

puttemp()
{
int temp,t;
if((flag & 0x02)== 2)
{ flag &= ~0x02;

LCDWI(0xc0);
LCDWD(' ');
temp=average();
adc=temp;
if (temp < min)
min = temp;
if (temp > max)
max = temp;
if ( (temp < 999) && (temp > 0)) /* limit measuring range to 0-100 c */
{
t = temp/100;
if(t != 0)
LCDWD(t+48);
else LCDWD(' ');
temp = temp%100;
LCDWD(temp/10+48);
LCDWD('.');
LCDWD(temp%10+48);
}
else
{
LCDWD('-');
LCDWD('-');
LCDWD('-');
LCDWD('-');
}

LCDWD(0xdf); /* i.e., 'C */


LCDWD('C');
LCDWD(' ');
}
}//******************************************************

puttitle()
{
LCDWI(0x80);
LCDWD('D');
LCDWD('i');
LCDWD('g');
LCDWD('i');
LCDWD('T');
LCDWD('h');
LCDWD('e');

391
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

LCDWD('r');
LCDWI(0xc0);
LCDWD('m');
LCDWD('0');
LCDWD('-');
LCDWD('1');
LCDWD('0');
LCDWD('0');
LCDWD(0xdf);
LCDWD('C');

}//******************************************************

392
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-11. Building a Microcontroller Programmer


This project shows how to build your own personal programmer for
programming HEX code into the Atmel Flash-based microcontrollers
AT89C2051 (2k Flash) or AT89C4051 (4k Flash). Simple hardware and
easy to use software under DOS and Window, are provided.

The Easy-DownLoader was originally introduced to enable engineering


students and amateurs to build their own microcontroller circuits. The
circuit was actually introduced in Atmel application notes. The circuit
features low-cost and easy use. The later version was designed to be used
with 2051 and 4051 chips. There are no separate functions like other
programmer e.g., blank check, erase, write. Simply type, C:\..>EZ hello,
the hex file "hello.hex" will then be programmed to the chip
automatically. If the chip is not blank or the code is locked, it will erase
first, then write and verify.

9-11.1. Programmer Hardware


Figure 9-10 depicts a circuit diagram of the Easy-DownLoader. As
shown, the circuit uses a 89C2051 microcontroller to host the writer.hex
firmware. The other components include a 8-bit latch 74LS373, an RS232
serial driver like DS275, a 5V voltage regulator 7805, an adjustable
voltage regulator LM317, and two transistors, 2N2222A and 2N2907A.

The programming voltage control circuit is the same as recommended by


Atmel application note. It can be raised from 0V, 5V and 12V by
appropriated signal from P3. The 8-bit latch, 74LS373 provides some
signal for selecting the programming modes. A byte to be programmed or
read back is sent/received through P1. Incrementing address is done by
pulsing a positive pulse to XTAL pin. The circuit may be built using
simple point-to-point soldering with a general purpose PCB or making a
special PCB shown below.

The finished board should be tested without any chips; 1) +5V supply, 2)
programming voltage 0V, 5V and 12V by connecting the pin that control
(P3.5 and D) 2N2222A and 2N2907 to +5V and/or GND. The output of
the power supply adaptor should be approximately 15Vdc 100mA, in
order to be able to generate 12V and 5V on the board.

393
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

Figure (9-10): Circuit Diagram of Easy-DownLoader V1.1

394
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

Figure 9-11. The PCB of the Easy-DownLoader V1.1

Fig. 9-12. The Atmel Programmer after implementation

395
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-11.2. Bill of Materials (BOM)


The following table indicates the components you need to implement the
microcontroller programmer and their prices (as of August 2003). As
shown in the table, the ZIF socket is expensive. However, you may use a
much cheaper normal 20-pin socket, but take care to handle the MCU
gently with a suitable tool.

Item Estimated Prices (LE)


DB9 + cable RS-232 14
Microcontroller 89C2051 25
Crystal oscillator 11.0592 MHZ 5
8-bit latch 74LS373 3.75
Bridge rectifier (1 A) 1
LED 0.25
Voltage regulator 7805 1.5
BJT 2N222NA / 2N2907 1
transformer 220ACV ~ 15V 6.5
20 pin ZIF socket 25
20 pin NORMAL socket 0.5
resistance 8.2KΩ 0.15
resistance 1KΩ 0.45
resistance 10 KΩ 0.3
resistance 1.15 KΩ 0.15
resistance 2.15 KΩ 0.15
resistance 0.294 KΩ 0.15
resistance 4.7 KΩ 0.15
capacitor 100µF, 50V 0.25
capacitor 0.1 µF 0.15
capacitor 1µF 0.15
capacitor 30 PF 0.3
capacitor 10µF 0.45

9-11.3. Programmer Software


Two files that you should get are: writer.hex 4,871 bytes, the Intel hex
file firmware for 89C2051 chip ( the actual code size is 2021 bytes) and,
EZ.exe 20,800 bytes the DownLoader program run on PC, send hex file
to the DownLoader. T

he original Writer.C program was written in 'C'. To modify it you need a


C51 compiler. The C-program listing is as follows:

396
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

/******************************************************************
Writer.C
PC code for downloading HEX file
******************************************************************/

#include c:\mc51\8051io.h
#include c:\mc51\8051reg.h
#define xon 0x11
#define xoff 0x13

extern register char cputick;


register int i;
unsigned register char ACC,temp;
register char command;
char *title[] = "\n Easy-DownLoader V1.1 for ATMEL 89C2051/4051"
char *prompt[] = "\n >"
char *ok[] = "\n ok"
register int count;

/*****************************************************************
Main Program
*****************************************************************/
main()
{
////////////////////// define ASM EQU for assembly interfacing //////////////////////////////
asm"LM317 EQU $b5";
asm"LE EQU $b7";
asm"prog EQU $b2";
asm"rdy EQU $b3";
asm"xtal EQU $b4";
asm"p10 EQU $90";
asm"p11 EQU $91";
asm"p12 EQU $92";
asm"p13 EQU $93";
asm"p14 EQU $94";
cputick = 0;
i = 0;
count = 0;
serinit(9600);
getch();
putstr(*title);
asm " clr LE";
initpowerup();
sendprompt();
while(1)
{
while ( cputick < 1) ;
cputick = 0;

397
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

/* run the following tasks every 10 ms */


getcommand();
prompting();
erase();
write();
read();
lock();
setcounter();
}
}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
getnum()
{
char s[6]; /* put to global variables instead five characters plus terminator */
char c;
int i;
c = 0;
for (i = 0; c != 10; i++)
{
putch(xon);
c = getch();
s[i] = c;
}
s[i] = '\0';
if (i==0)
return (-1);
else
return (_atoi(s));
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
getcommand()
{
if ((SCON & 0x01) != 0)
command = getch();
else command = -1; /* no cammand has entered */
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char getconsole()
{
if ((SCON & 0x01) != 0)
return(getchr()); /* use getchr() instead,ie. no echo */
else return(-1);
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
putok()
{
putstr(*ok);
sendprompt();
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sendprompt()
{
putstr(*prompt);
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

398
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

prompting()
{
if (command == '\n')
{
putstr(*title);
sendprompt();
}
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pulseLE()
{
delay(1);
asm" setb LE";
delay(1);

asm" clr LE";


delay(1);
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
erase()
{
if (command == 'e')
{
asm {
setb p12 /* set erase mode */
clr p11
clr p10
}
pulseLE();
asm {
clr p14
clr LM317
}
pulseLE();
delay(100); /* raise program supply up to 12V */
for (i=0; i < 10; i++) /* erase entire PEROM array (2kB) */
{
asm " clr prog";
delay(10); /* 10 ms prog pulse */
asm " setb prog";
delay(1);
}
initpowerup(); /* reset internal address counter to 000h */
putok();
}
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
write()
{
if (command == 'w')
{

399
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

asm {
clr p12 /* set program mode */
setb p11
setb p10
}
pulseLE();
asm {
clr p14
clr LM317
}
pulseLE();
delay(100); /* rise supply up 12V */
asm" clr IE.7";
for (i = 0; i < count; i++)
{ /* use XON & XOFF flow control */
putch(xon); /* send XON */
P1 = getchr();
putch(xoff); /* send XOFF */
pulseProg();

/*
asm " clr prog";
asm " nop";
asm " nop";
asm " nop";
asm " nop"; /* pulse prog ~4 microsecond */
asm " setb prog";
*/
asm " nop";
asm " jnb rdy,*";
asm " nop";
asm " setb xtal";
delay (1);
asm " clr xtal";
}
asm" setb IE.7";
asm " setb LM317";
asm " setb p14";
pulseLE();
putok();
}
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

read() /* read code with the number of bytes set by 's' command */
{
if (command=='r')
{
initpowerup();
/* delay(100); */

400
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

asm {
clr prog
clr p12
clr p11
setb p10
}
pulseLE();
for(i = 0; i < count; i++)
{
asm" setb prog";
asm" mov P1,#$FF"; /* put FF before read back */
delay(1);
printA(); /* read in HEX */
asm" setb xtal"; /* next address */
delay(1);
asm" clr xtal";
/* chkXOFF(); */ /* If flow is controlled by XON/XOFF */
}
putok();
}
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
printA()
{
ACC = P1;
ACC >>= 4; /* shift right 4 bits */
putHEX();
ACC = P1&15;
putHEX();
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
putHEX()
{
if (ACC > 9)
putch(ACC+55);
else putch(ACC+48);
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
chkXOFF() // use XON and XOFF for controlling flow with host computer
{
if(getconsole() == xoff)
{
do;
while(getconsole() != xon);
}
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
lock() // only protection mode 3, i.e., disabled further program and verify
{
if (command == 'l')
{
P1 = 0x07;
pulseLE();

401
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

asm " clr LM317";


delay(100);
pulseProg();
P1 = 0x06;
pulseLE();
pulseProg();

asm " setb p14";


asm " setb LM317";
pulseLE();
putok();
}
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
setcounter()
{
if (command == 's')
{
count = getnum();
putok();
}
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pulseProg()
{
asm " clr prog";
asm " nop";
asm " nop";
asm " nop";
asm " setb prog";
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
I
nitpowerup()
{
asm {
clr prog
clr xtal
setb LM317
setb p14
setb rdy
}
pulseLE();
delay(100);
asm {
setb prog
clr p14
setb LM317
}
pulseLE();
delay(100);
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

402
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

time1ms() /* 1 ms delay with XTAL 11.0592MHz */


{
int i;
for (i = 0; i < 8 ; i++) ; // Just loop and do nothing
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

delay(n) /* do nothing n*1ms */


int n;
{
int i;
for (i=0; i< n ; i++)
time1ms();
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

printhelp()
{
if (command == '?')
{
putstr("\n e erase");
putstr("\n rb read BIN");
putstr("\n rh read HEX");
putstr("\n w write");
putstr("\n l lock");
}
putok();
}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Functional Test
Use a given programmer (or Easy DownLoader) to write the writer.hex
into the 2051 chip. Put the programmed 2051 chip to the board. Invoke
any communication software with 9600 baud, 8-data bit, and no parity.

 Connect DB-9 to COM1, say,


 Press enter key, the title "Easy-DownLoader for ATMEL 89C2051/4051"
will appear on the screen.
 Type > s2048 (set byte counter to 2k)
 Type > r (read 2kB), on screen would show FFFFFFFFFFF...
indicating corrected wiring for P1. If you put the chip which is already
programmed, r (read) command will show the hex code with the number
of byte set by s (set) command.
 Try > e (erase) command to erase the entire program, if you wish.

Figure 9-13 shows example of using Xtalk communication program to test


the board. You can also use any other PC communication utility. Note that
the Window HyperTerminal is no longer supported in recent Windows.
However, instead of using such communication utilities, try with the
403
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

downloader program "EZ" to help you write the hex file to the chip.
Example of using EZ downloader is shown in figure 9-14, below.

9-11.4. Using Easy DownLoader for Windows


The EZ Downloader V3 for Window provides a simple means of sending
HEX file to the writer board. To connect the board with EZ, click on the
available COM port, say COM1. Then the EZ will try to recognize the
microcontroller chip. After chip recognition, locate and send your
Hexfile, that all. Since there is no signature byte that indicates chip
number and programming voltage, you have to choose the appropriated
memory size either 2051 or 4051 manually, i.e., 2048 or 4096
respectively. Also, EZ DownLoader V3.1 for Window is an upgraded
version of EZ3 with RAED and SAVE AS features for reading HEX code
resided in the chip and save as an Intel HEX file. EASY DownLoader
version 4 Program can also be used to recognize the programmer board
and connect it to the PC, via the COM port.

Fig. 9-14. Example of using EZ program to write the writer.hex to 2051 chip

404
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

Figure 9-15. Main window of the EZ 4.0 up-loader software interface, recognize the
chip automatically.

405
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-12. EPROM / FLASH Memory Programmer


The following application is not really a microcontroller-based project.
However, when you develop a microcontroller application which needs
an external EPROM space (for large code), you will need to program that
EPROM. We introduce here a simple but efficient programmer for so
many EPROMS devices of many families (like 27xxx, 29xxx, XXX080).
You can use this programmer to program the EPROM or FLASH
memory inside a wide range of, Atmel and Microchip microcontrollers. A
complete list of supported EPROM/FLASH memories that you can
program is given in Appendix D.

9-12-1. The Hardware


The following EPROM Programmer, figure 10-20, is called the Wilem
programmer. The double-sided PCB of the EPROM Programmer is
shown below in figures 9-16(a, b).

Figure 9-16. The Wilem EPROM programmer board.

As shown in figure, has to be connected to the PC parallel port via a 25-


pin connector. You can set DIP switches and jumpers to select different
devices. For instance, you set the jumpers to A18 for standard use. You
can also set the jumper to A19 for XXX080 and 29X040 chips as well as
the 29F040/29C040/27C080/27C801 devices. A19, A20, A21 jumpers
are used to connect the 16-bit 42-pin adapters (27C400..27C322) or the
TSOP 48 adapter. The two DIP switch should be both ON. You can select
Vpp = 21V if the 8.2 Zener diode is mounted.
406
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

Figure 9-17. The EPROM programmer circuit diagram.

407
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

(a) Solder Side

(b) Component Side.


NB. Some components also exist on the solder side

Figure 9-18. The Wilem EPROM programmer PCB. The PCB Size: 160x100mm
(eurocard format). Adjust if necessary (within 1mm is ok). Drill: 0.7-08 mm

408
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-12.2. The Software:


The software driver (and its source) that you‟ll use with this programmer
is downloadable. The driver interface is shown in Fig. (9-21) below.

Fig. 9-19. The EEPROM Programmer.

In order to program a specific EPROM chip proceed as follows. In the


program set to 'Willem' (only needed with first use). You can select a
device using Device button. The DIP switches can be red (like in the
software), white or other colors. After selecting a device, Insert chip and
check ID (not possible with some older devices). Erase if necessary, load
program file and program, the Vcc LED will light and with 27,28 devices
the Vpp LED also.

Normally you should not change tWP and tWC parameters unless you
know what you are doing. If you get random write errors with 27(C)XXX
eproms try higher settings. Older EPROMS like the 2716 need higher
settings. In the Buffer section you can see the contents of your program
file or the chip if you have done a chip read. The CONFIGS section
give an overview of all settings and parameters. If you need PIC in circuit
programming, you can use a DIP connector for the 18 pin PIC 16F84
socket (5 GND, 12 clock, 13 data I/O, 14 Vcc). The Test H/W section is
for testing

409
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-12.3. The Source Code


If you‟d like to modify the above interface or add some features, you cad
compile its source program. We show here just a part of the code. The
following listing depicts the main C++ program (EPROM.CPP), which
has to be compiled under Windows (e.g. using Microsoft VC++
compiler).

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// EPROM.CPP //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <vcl.h>
#pragma hdrstop

USERES("EPROM.RES");
USEFORM("uEprom.cpp", frmEprom);

//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->Title = " EPROM Programmer";
Application->CreateForm (__classid(TfrmEprom), &frmEprom);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException (&exception);
}
return 0;
}
//---------------------------------------------------------------------------

410
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

9-13. Summary

We have just traced all the steps that take us through the development
process. First a program is written or modified with a text editor. The
program is assembled into an object file. The object file is downloaded to
the microcontroller and executed. Operation is monitored with the logic
probe to note any problems or whether a change has produced the desired
result. If there is a problem, the program is loaded into the simulator and
execution is monitored to reveal the problem. And then you do it all over
again. This cycle is repeated many times before even a crude system is
written, and then many more times to get to a workable prototype. This is
just a rough outline of the actual process. You may or may not use the
logic probe, nor the simulator. We sometimes use the test LED and an
instruction to light it placed at the suspected problem area for software
debugging, instead of the simulator. The simulator is good for initial
testing of a program, but ultimately you will want to know which path a
conditional jump took when a certain event occurred.

411
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9

PROBLEMS

1) Write an assembly program to drive a 16-key lead-per-key keypad

412
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

Chapter 10: Microcontroller Selection Guide


All the previous chapters have been laying the ground work and basic
concepts common to most microcontrollers. When you start a
microcontroller-based project, you’ll ask yourself: Which microcontroller
should I use and what are the differences between them? This is finally,
what all the previous chapters have been getting you ready for. To start
looking for the most suitable microcontroller you’ll be using in your real
project.

10-1. Introduction
There are a wide variety of microcontrollers that can be used in control,
communication, and robotics projects. Some of the most popular are
8051's, 80186, 6811's ,PIC's and ARM. This topic engenders hot debates
of the merit of one chip over the other. However, when deciding which
microcontroller to use, and which devices to implement in a design, there are lots of
things to consider besides whom else is using these devices

 What exactly my requirements


 What are the features in available microcontrollers and at what price.
 Can I expect help when I am having problems?
 What development tools are available and how much do they cost ?
 What sort of documentation is available (manuals, application notes)?
 Can I work a deal by purchasing more devices at one manufacturer?
That is, purchasing not only the microcontroller, but also peripherals
 Do they support OTPs, windowed devices, mask parts?

Therefore, the best way for you to decide is to understand your problem
requirements and see which devices fit your needs. At that point, you can
look at issues of support platforms, cross-compilers, cost etc to make the
best decision. Microcontrollers are characterized by several parameters:

• Core Processor type (CISC or RISC)


• Precision (8 bit, 16 bit, 32 bit)
• Memory (ROM, RAM, EPROM, EEPROM, Flash)
• I/O (Number of channels)
• Timers (MFT, RTI, Watchdog)
• ADC (Number of channels, number of bits)
• Serial interface (SCI, SPI, CAN, USB)
• Maximum bus frequency (MHZ) and operating voltage
• Package option (number of pins).

413
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

10-2. INTEL Microcontrollers:


Intel's 8-bit MCS51 microcontroller family is optimized for control-
oriented applications that require expanded RAM, and high performance.
The MCS96 microcontroller family includes products for high-speed
input/output, motor control, CAN products and event processing.
10-2.i. MCs 51
The MCs 51 is a family of 8-bit microcontrollers, with 32 KB ROM, 32
I/O, and 3 16-bit timers. The MCs51 family has the following versions:
 80C31BH-24 ROMless (128 Bytes RAM) *
 80C51BH-24 4K ROM *
 87C51-24 4K OTP/EPROM *
 80C32-24 ROMless (256 Bytes RAM)
 80C52-24 8K ROM
 87C52-24 8K OTP/EPROM
 80C54-24 16K ROM
 87C54-24 16K OTP/EPROM
 80C58-24/-33 32K ROM
 87C58-24/-33 32K OTP/EPROM
 80C51FA-24/-33 ROMless (256 Bytes RAM) with PCA
 83C51FA-24/-33 8K ROM with PCA
 87C51FA-24/-33 8K OTP/EPROM with PCA
 87C51FB-24/-33 16K ROM with PCA
 87C51FB-24/-33 16K OTP/EPROM with PCA
 87C51FC-24/-33 32K ROM with PCA
 87C51FC-24/-33 32K OTP/EPROM with PCA

10-2.ii. MCs 96/196/960 Families


The MCs 8096 is a family of 16-bit microcontrollers, with 10-bit ADC.
It is equipped with many registers, internal RAM, the usual compliment
of on-board peripherals (serial, A/D, PWM, timer/counters, etc)
The third generation of Intel microprocessors, the 80C196 is a 16-bit
processor. Originally fabricated in NMOS (8096), it is now mainly
available in CMOS. Intel Corp. has recently introduced a clock-doubled
(50MHz) version of the 80C196. Among the many features it includes
are: hardware multiply and divide, 6 addressing modes, high speed I/O,
A/D, serial communications channel, up to 40 I/O ports, 8 source priority
interrupt controller, PWM generator, and watchdog timer.The MCs 8960
is a family of 32-bit microcontrollers, with more capabilities than its
predecessors.

414
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

10-3. Dallas Microcontrollers


The Dallas Semiconductor (Now Maxim) DS5000 is a microcontroller
based on the Intel 8051 Soft Microcontroller. It looks like an 8051 as far
as programming and the general pinout of the package It has a Bootstrap
Loader, 32 I/O lines, 2 Timers/Counters, 5 Interrupts/2 Priority levels,
128 Bytes On-chip RAM, ROM-less. There is a lithium battery inside the
DS5000 that keeps all the memory alive when power is turned off. This is
one of the neatest features of the DS5000, and I don't know of another
micro that has this. In most micros there is PROM or EPROM. The
DS5000 is available as a separate 40-pin IC or as a whole development
kit (with 8K/32k Byte XRAM and Battery Backup).

10-4. Atmel CISC Microcontrollers


Atmel offers a broad range of CISC microcontrollers based on the 8051
architecture. The product line includes MCS-51® industry standard
socket drop-in devices, In-System Programming capability, and small
footprint 20-pin derivatives in ROMless, ROM, OTP & Flash. Some of
the devices also take advantage of the high-speed core (X2) mode which
doubles the internal clock frequency for CPU and peripherals upon
selection. This section will give a quick overview of the Atmel CISC
controllers.

10-4.1. Atmel 89C5x (socket drop-in) Microcontrollers


The Atmel AT89C5x is a family of powerful microcontrollers, which is
based on the Intel 8051 microcontroller architecture. It is fully compatible
with the industry standard 8051 instruction set. The Atmel 89C51/52/55
are 40-pin versions and are fully compatible with the Intel 8051/52
microcontroller.

AT89C51 AT89C52 AT89C55


FLASH 4K 8K 20K
SRAM 128 256 256
Timer/Counters 2 3 3
SPEED 0-24 MHz 0-24 MHz 0-28 MHz

10-4.2. Atmel 89Cx051 (Small FootPrint) Microcontrollers


The Atmel 89Cx051 is a family of highly-flexible and cost-effective
microcontrollers. The Atmel 89Cx051 MCU’s are versions 20-pin of the
8051 microcontroller and looks like an 8051 as far as programming. The
8051 or 8052 can be substituted for the AT89Cx051 if the connections
are moved to the appropriate pins on those chips

415
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

AT89C1051 AT89C2051 AT89C4051


Package 20 PIN 20 PIN 20 PIN
FLASH 1K 2K 4k
SRAM 64 128 128
Timer/Counters 1 2 2
Comparator 1 1 1
IO DRIVE 20mA 20mA

The Atmel 89C2051 is a low voltage (2.7V-6V), CMOS 8-bit


microcontroller with 2 KB of Flash erasable and programmable read only
memory (EPROM). The 2051 provides the following features:

* 2 k bytes of Flash (89C4051 has 4kB, 89C1051 has 1kB Flash)


* 128 bytes of RAM
* 15 I/O lines (P1.0-P1.7, P3.0-P3.5, P3.7)
* two16-bit timer/counters (T0, T1)
* five vector, two-level interrupt architecture (INT0, INT1)
* full duplex serial port (RXD, TXD)
* precision analog comparator (AN0, AN1)
* on chip oscillator and clock circuitry

It should be noted that the 2051 supports two software selectable power
saving modes. The Idle Mode stops the CPU while allowing the RAM,
timer/counters, serial port and interrupt system to continue functioning.
The Power Down Mode saves the RAM contents but freezes the
oscillator disabling all other chip functions until the next hardware reset.
The following figure shows a comparison between the different types of
Atmel CISC microcontrollers

10-4.3. The Atmel AT89S8252 (ISP) Microcontrollers


The Atmel AT89S8252 is a high performance microcontrollers with
enhanced 8052 CPU core. The AT89S8252 microcontroller has a 2 kB
EEPROM in addition to the 8kB FLASH memory. It can execute from
FLASH while writing to EEPROM. It also has the following features:
– 4 Ports (32 I/O Pins)
– 256B SRAM
– 3 Timers
– Watchdog timer
– SPI serial interface
– 8k bytes downloadable FLASH via SPI
– 2kB on-board EEPROM with 100,000 erase/write cycles
– Interrupt Recovery from Power Down
416
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

Fig. 10-4. Block diagram of the Atmel AT89S8252 microcontroller.

Fig. 10-5. In-circuit programming of the AT89S8252, via the SPI port.

10-4.4. Atmel AT83C5134/35/36 Microcontrollers (with USB)


The Atmel AT83C5134/35/36 microcontrollers are high performance
ROM versions of the 80C51 microcontrollers with USB functions. It is
pin-compatible with AT89C5130A 16-KB and AT89C5131A 32-KB ISP
flash microcontrollers, allowing those devices be used for development
while this device can be used in mass production to reduce costs.
417
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

It features a full-speed USB module that is compatible with the USB


specification version 2.0. This module integrates the USB transceivers
and the serial interface engine with digital phase locked loop and 48-MHz
clock recovery. It also includes USB event detection logic and FIFO
buffers supporting the mandatory control endpoint and five versatile
endpoints with minimum software overhead.

Fig. 10-6. Architecture of the AT83

Fig. 10-7. Connection of the AT89S8252


418
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

The device retains the features of the Atmel 80C52 and adds 1024 bytes
of on-chip ERAM, a dual data pointer, a 16-bit up/down timer, a
programmable counter array, up to four programmable LED current
sources, a programmable hardware watchdog, and a power-on reset.
– Maximum Core Frequency 48 MHz in X1 Mode, 24 MHz in X2 Mode
– Full-duplex Enhanced UART (EUART), TxD and Rxd
– Three 16-bit Timer/Counters: T0, T1 and T2
• 8/16/32-Kbyte On-chip ROM and 256 Bytes of Scratchpad RAM
• 512 byte or 32-Kbyte EEPROM(1)
• On-chip Expanded RAM (ERAM): 1024 Bytes
• USB 2.0 Full Speed (12Mbps) with Interrupt on Transfer Completion
– 48 MHz DPLL for Full-speed Bus Operation
– USB Bus Disconnection on Microcontroller Request
• 5 Channels Programmable Counter, PWM and Watchdog Timer
• Keyboard Interrupt Interface on Port P1 (8 Bits)
• SPI Interface (Master/Slave Mode)
• 34 I/O Pins
• 4 Direct-drive LED Outputs with Programmable Current Sources:
• 4-level Priority Interrupt System (11 sources)
• Low Voltage Range Supply: 2.7V to 3.6V
• Packages: Die SO28, QFN32, MLF48, TQFP64

419
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

Fig. 10-3. Different types of the AT89Cxx51/52,.

10-5. MOTOROLA Microcontrollers:


The MC680x is a family of 8-bit microcontrollers, which is based on the
MC6800 microprocessor. It has the following variants: 6805, 6808, 6811
Also, MC68C12 is a 16-bit microcontroller family. Some Motorola
microcontrollers have digital signal processing (DSP) capabilities.

These devices combine the control advantages of a microcontroller


(MCU) with the high computation speed of a DSP to create a single-chip
solution for embedded system designs. For instance, the Motorola
DSP56Fxxx family is based on a 16-bit 6808 microcontroller core, with
DSP capabilities. These microcontrollers are usually packaged in 100-pin
QFP and run at frequencies up to 40 MHz. They are equipped with 63kB
program Flash, 8kB data Flash, 4kB RAM, 6 channel PWM, up to 2
timers, and 2 four channels 10-bit ADC.
420
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

10-5.1. Architecture of M6805


The 6805 family is Motorola's simplest and least-expensive family of
microcontrollers. The breadth of devices is quite large, ranging from tiny
16-pin chips to larger parts with more memory and peripherals. Nearly all
the devices are single-chips and use ROM or OTP ROM. Though
intended to be replaced by the newer HC08 family, the 68x05 devices are
still widely used, and excellent choices for all sorts of simple tasks.

The 6805 family provides the following features:


• Fully static design with industry standard M68HC05 family CPU core
• On chip crystal oscillator
• 2.1 MHz internal operating frequency at 5V; 1.0 MHz at 3V
• High speed version available
• 176 bytes of RAM
• 5936 bytes of user ROM plus 14 bytes of user vectors
• 256 bytes of EEPROM with internal charge pump and security bit
• Self test/bootstrap mode
• Three 8-bit parallel I/O ports and one 8-bit input-only port
• Software option available to output the internal E-clock to port pin PC2
• 16-bit timer with 2 input captures and 2 output compares
• Computer operating properly (COP) watchdog timer
• Serial communications interface (SCI) with programmable baud rate
• 2 pulse length modulation systems which can be used as D/A converter
• 8 channel A/D converter
• One interrupt request input plus 4 on-board hardware interrupt sources
• Complete development system support using the MMDS05
• Available in 52-pin PLCC, 64-pin QFP and SDIP packages.

10-5.2. Architecture of M6808


The CPU of 6808 has two 8 bit accumulators (A & B) that can be
concatenated to provide a 16 bit double accumulator (D). Two 16-bit
index registers are present (X,Y) to provide indexing to the memory map.

10-5.3. Architecture of M6811


The 6811 is also a 8-bit microcontroller. It has two index registers, so it is
very good for processing data. Although an 8-bit processor, the 6811 has
some 16-bit instructions (add, subtract, multiply, shift, and rotates). A
16-bit stack pointer is also present, with stack manipulation instructions.

421
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

Fig. 10-9. Architecture of Motorola 6805 microcontroller.

10-5.4. Architecture of M6812


The MC68x12 microcontroller is a 16-bit device. Its modules include a
16-bit central processing unit (CPU12, two asynchronous serial
communications interfaces (SCI0 and SCI1), a serial peripheral interface
(SPI), a timer and pulse accumulation module, an 8-bit ADC, 1kB RAM,
4kB EEPROM, and memory expansion logic with chip selects, key
wakeup ports, and a phase-locked loop (PLL).

422
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

Fig. 10-10. Architecture of Motorola 68x12 microcontroller.

10-5.5. Architecture of M683xx


The 683xx family from Motorola are highly integrated CPU's, which
maybe used as microcontrollers. Some members of this family have
onboard RAM (eg, up to 2K), none have on-board ROM, but they do
have timers, software programmable chip selects, etc, making it possible
to build very small but complete systems. The 683xx family includes the
following CPU's:
423
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

68302: has on-board nice serial controller, internal 68000 CPU and RISC
core, in addition to some memory.

68330: has a 32-bit CPU core, which is in between a 68000 and a 68020.

68331: added standard asynchronous serial controller (UART).

68332: added separate Time Processing Unit (TPU) and some RAM. The
TPU can do things like off-line PWM processing.

68340: deleted TPU, added Direct-Memory Access (DMA) controller.

The Motorola M680302 CPU was originally designed for communication


equipment, especially the ISDN (Integrated Service Digital network). It
has a main RISC core, but it can execute all M6800 instructions, plus the
additional 16 opcodes of the M6803U4. It has also the following features:

 Bus compatibility with the M6800 family.


 A fully synchronous design that helps developers avoid timing
problems.
 Two input capture functions and three output compare functions
 A built-in Serial Communications Interface (SCI).

10-6. Zilog Microcontrollers:


The Z8 is a family of 8-bit microcontrollers, with the following variants:

 Z8601 Single-chip microcomputer with 2K ROM


 Z8602 Development device with memory interface
 Z8603 Prototyping device with EPROM interface
 Z8611 Single-chip microcomputer with 4K ROM
 Z8612 Development device with memory interface
 Z8613 Prototyping device with EPROM interface

The Z86xx microcontrollers are 8-bit OTP versions of Z8


microcontrollers. The members of this family contain up to 16 kB on-chip
ROM, 236 Byte on-chip RAM and up to 32 I/O lines. In addition, all
Z86E members have 6 interrupt inputs, 2 timer/counters, a WDT and run
at 12 MHz. The Z8 microcontrollers are available in 28-pin DIP/SOIC as
well as 40 pin QFP/PLCC packages.

424
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

Fig. 10-11. Block diagram of Z8 MCU.

425
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

Fig. 10-12 Pin-out diagram of Z8 MCU.

10-7. MICROCHIP Microcontrollers:


The PIC microcontrollers are not derivative or compatible with MCS51
microcontrollers. The Microchip PIC microcontroller families are based
on the Harvard RISC microprocessor core. Some PIC microcontrollers
have analog capabilities; others have industry standard buses, LCD, or
high voltage capabilities. The PIC12 through PIC18 families are equipped
with flash memory for program store.

10-7.i. PIC12 Family:


The PIC12Cxx microcontrollers are 8-bit microcontrollers. They have 6
I/O pins with 25mA source/sink per I/O, 4 oscillator selections including
the internal 4 MHz RC oscillator with programmable calibration, and
Power-on Reset. PIC12 microcontrollers have up to 128 Byte data RAM,.
The program memory is 768 (Bytes), 512 (Words) wide. PIC12
microcontrollers are available in 8-pin SOIC and 8-pin DIP packages.
Some members of the family incorporate 2 timers + watch-dog timer
(WDT), and up to 2 8-bit ADC.

426
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

10-7.ii. PIC16 Family:


The PIC16Cxx is a family of 8-bit, ROM based micro controllers with a
RISC architecture inside.

10-7.iii. PIC18 Family


The PIC18Cxx microcontrollers a 8-bit microcontroller which operates at
frequencies up to 40MHz. The PIC18Cxx has a Controller Area Network
(CAN) peripheral interface into an 64- or 68-pin package and is upwards
compatible with PIC12X, 16X, and 17X devices and provide a seamless
migration path of software to higher levels of hardware integration. The
program memory of the PIC18C858 is 32768 (Bytes), 16384 (Words).
Some members of the family have 4 timers+WDT, 2PWM, and up to 16
10-bit ADC. The PIC18C858 features a C-compiler friendly development
environment, 2 capture/compare and PWM functions, as well as 16
channels of 10-bit Analog-to-Digital converter (ADC). The synchronous
serial port can be configured as either 3-wire Serial Peripheral Interface
(SPI) or the 2-wire Inter-Integrated Circuit (I2C) bus. It also has an
Addressable Universal Asynchronous Receiver Transmitter (AUSART).
All of these features make the PIC18 an ideal choice for automotive and
industrial applications.
Table 10-3. PIC 8-bit microcontrollers

Enhanced
Base Line Mid-Range PIC18
Mid-Range
PIC12F1XXX,
Families PIC10,12, 16 PIC12, 16
PIC16F1XXX
PIC18
No. of Pins 6-40 8-64 8-64 18-100
Up to 128
Prog Memory Up to 3 KB Up to 14 KB Up to 28 KB
KB
Up to 368
Data Memory Up to 134 Bytes Bytes
Up to 1.5 KB Up to 4 KB
Instruction
12-bit 14-bit 14-bit 16-bit
Length
Instruction set 33 35 49 83
Speed (MIPS) 5 5 8 Up to 16
Enhanced
Baseline + Mid-range + Mid-range
• Comparator · SPI · High +
• 8-bit ADC · I2C Performance • CAN
Feature • Data Memory · UART · Multiple • LIN
•Internal · PWM communication • USB
Oscillator · 10-bit ADC peripherals • Ethernet
· OP-Amps • 12-bit
ADC
427
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

10-7.iv. dsPIC Family:


Microchip's dsPIC™ family of devices closes the performance gap by
providing easy migration from microcontrollers (MCUs) to digital signal
processors (DSP) performance. The 30Fxxxx family is a 16-bit (data)
non-pipelined modified Harvard RISC machine, which combines the
control advantages of a high-performance 16-bit microcontroller with the
high computation speed of a fully implemented digital signal processor
(DSP) to produce a tightly coupled single-chip single-instruction stream
solution for embedded systems designs. The microcontrollers of this
family can incorporate up to 256 kB flash EPROM (program + memory),
up to 4kB SRAM and up to 10-channel 10-bit ADC.

Fig. 10-13. Microchip dsPIC microcontroller

The PIC microcontrollers are available with different memory options


which are mask ROM, EPROM and flash memory. They are denoted
with different symbols as given in the following table:

Table 10-4. Designation of PIC microcontrollers

Symbol Memory Type Example


C EPROM PIC16Cxxx
CR Mask ROM PIC16CRxxx
F Flash memory PIC16Fxxx

PIC microcontrollers are also available with extended voltage ranges


which reduce the frequency range. The operating voltage range of these
PICs is 2.0-6.0 volts. The letter ‘L’ is included in controller’s name to
denote extended voltage range controllers. For example, PIC16LFxxx
(Operating voltage 2.0-6.0 volts).

428
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

10-8. ARM Microcontrollers


The ARM processor range provides solutions for open platforms in
wireless, consumer and imaging applications, embedded real-time
systems for storage, automotive, industrial and networking applications,
and secure applications for smart cards and SIM cards.

The ARM Cortex microprocessor series are usually equipped with


peripheral devices, as systems on chip (SoC), and used as
microcontrollers. These series include ARM Cortex A, ARM Cortex R
and ARM Cortex M. The latest Cortex family includes a wider range of
processors than earlier families. These processors are suitable for very
different kinds of application, and several profiles (M0, M1, M3 andM7)
were therefore introduced to distinguish what targets they are adapted to.

The ARM Cortex M3 is a relatively new kid on the embedded controller


block. The ARM Cortex-M3 32-bit processor has been specifically
developed to provide a high-performance, low-cost platform for a broad
range of applications, including microcontrollers, automotive body
systems, industrial control systems and wireless networking.

The Cortex-M3 processor incorporates:

 A 32-bit processor core with low gate count and low latency interrupt
processing
 RISC processor, 3-stage pipeline Harvard architecture, pipeline core
incorporating branch speculation, single cycle multiplication, and
hardware division, giving a Dhrystone benchmark of 1.25
DMIPS/MHz
 A nested vectored interrupt controller (NVIC) closely integrated with
the processor core to achieve low latency interrupt processing
 MPU is included
 Cortex-M3 processor is configured for SmartFusion2 MSS uses only
little endian
 Auxiliary Control Register is included
 Multiple high-performance bus interfaces
 A debug solution with the optional ability to do the following:
o Implement breakpoints and code patches
o Implement watchpoints, tracing, and system profiling
o Support printf() style debugging
o Bridge to a trace port analyzer
429
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

Manufacturers of the Cortex-M3 processor integrated circuits are


permitted some latitude in configuring a particular implementation of the
Cortex-M3 processor delivered by ARM. For instance, the SmartFusion1
and SmartFusion2 profiles of M3 were introduced by Microsim Corp. the
following

Table 10-1(a). Cortex-M3 Devices Compared (from Microsim)

Feature SmartFusion SmartFusion2


Microcontroller Subsystem (MSS)
Cortex-M3 processor 100MHz 166MHz
Flash (eNVM) 512 Kbytes 512 Kbytes
SRAM (eSRAM) 64 Kbytes 80 Kbytes
Ethernet MAC 10/100 10/100/1000
USB - 1
CAN 2.0A and B - 1
I2C 2 2
SPI 2 2
16550 UART 2 -
Multi-Mode UART - 2
32-Bit Timer 2 2
SDRAM Controller - Yes
DDR2 2nd Controller - Yes
DDR3 2nd Controller - Yes
High Performance DMA - Yes
PLL's 2 8
RC Oscillator 1 100MHz 50MHz
User I/O

430
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

Maximum 204 574

Feature SmartFusion SmartFusion2


Programmable Analog
ADCs(8-/10-/12-bit SAR) 3 -
DACs (8-/16-/24-bit) 3 -
Comparators* 10 -
High Voltage Monitors* 10 -

In addition to the on-chip Advanced high-performance bus (AHB) and


thge infrastructure supporting the Cortex-M3, Microsemi offers a broad
portfolio of IP cores for use in the FPGA fabric to implement custom
design solutions.

Table 10-1(b). Cortex-M3 Devices Compared (from Microsim)

Feature SmartFusion SmartFusion2


FPGA Fabric
System Gates 500,000 12 Million
Logic Elements 11,520 Tiles 120,348 4 input LUTs
Total RAM 108 Kbits 4,500 Kbits
4608 bit RAM Block Yes -
1K bit Micro Ram - Yes
18K bit Large Ram - Yes

431
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

10-9. Microcontroller Evaluation Boards


Evaluation boards (or single-board computers) help you quickly get
started with new microcontroller architectures. Many manufacturers offer
assembled evaluation boards which allow you to use a PC as a host
development system. We present here some of these evaluation boards

i- Parallax Basic Stamp


This is a small single-board controller that runs BASIC, and costs only
$39. A SIP version for about $30 is also available. THE 256 byte
EEPROM can hold a program of up to about 100 instructions. The
BASIC Stamp programming package is a complete development package
from Parallax Inc. for about $100.

ii- Motorola EVBU, EVB, EVM, EVS


This is a series of very popular evaluation/development systems based on
the 68hc11. It comes complete with the BUFFALO monitor and varying
types of development software. Commonly used for university courses.

iii- Motorola 68705 starter kit


Motorola 68705 is a complete development system, software, hardware,
simulator, emulator, manuals, etc for just $100.

iv- Dallas Semiconductor DS5000TK


The DS5000TK allows evaluation of any DS5000 series device in any
existing application without circuit changes. The included DS5000T
plugs into the supplied serial interface pod which provides a connection
to a host PC. A target cable connects the pod to the target system.
Programs can be downloaded directly to the chip (no EPROM
programming!) using the built-in serial loader. With Dunfield's
Development System, you end up with a cheap "pseudo-ICE". Dunfield
also has a circuit if you want to build a similar device.

v- Philips/CEIBO DS750
Philips CEIBO DS750 is based on the low-end Philips 87C75x parts. It is
sold for $100 (from Philips), with a "pseudo-ice" for testing your code in-
circuit. It allows source-code debugging in assembler (included), C, and
PL/M, with an interface similar to that of Borland's Turbo Debugger.
This board is very popular with students and consultants for
experimenting with 80C51 code. It includes a VERY NICE book which
describes the theory of operation of the board itself, and includes a good
number of experiments that you can try for yourself.

432
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

vi- American Educational Systems AES-51, AES-11, AES-88


This is a perfect system for students and hobbyists. So, if you'd like to
start learning about microcontrollers, but the thought of finding all the
components and then building an application scares you, take a look at
the line of boards available from American Educational Systems. This
might be the easiest way to get started.

Fig. 10-14(a). The BASIC stamp evaluation board.

Fig. 10-14(b). The Atmel 89S and AVR evaluation board.

433
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

For about $300, you can get the complete packaged AES educational
tool. It has three boards: AES-51 (8051), AES-11 (68HC11), and AES-88
(8088). All three boards are built along the same lines and include RAM,
ROM, LCD display, keypad, A/D, serial ports, digital I/O ports, and logic
probe. Also, AES includes is a full bookshelf of documentation. These
boards are ridiculously easy to use and program - you can get started
experimenting and designing right away. Even professionals will find this
system useful as a prototyping tool and test bed.

434
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

10-10. Summary

There are a wide variety of microcontrollers that can be used in control,


communication, and robotics projects. Some microcontrollers may use
4bit words and operate at clock rate frequencies as low as 4kHz, Other
microcontrollers may use 32-bit words and operate at clock rate
frequencies as high as 1GHz. Intel developed a computer system on a
chip which combined RAM and ROM on the same chip, the Intel 8048,
introduced in 1977. Some of the most popular microcontrollers nowadays
are Intel 8051's, Motorola (now Freescale) 6811's , Microchip PIC's and
ARM from many vendors. They can be found in many electrical devices
such as washing machines, microwave ovens, and mobile phones.

Intel's 8-bit MCS51 microcontroller family is optimized for control-


oriented applications that require expanded RAM, and high performance.
The MCS96 microcontroller family includes products for high-speed
input/output, motor control, CAN products and event processing.

Atmel offers a broad range of CISC microcontrollers based on the 8051


architecture. The product line includes MCS-51® industry standard
socket drop-in devices, In-System Programming capability, and small
footprint 20-pin derivatives in ROMless, ROM, OTP & Flash. Some of
the devices also take advantage of the high-speed core (X2) mode which
doubles the internal clock frequency for CPU and peripherals upon
selection. This section will give a quick overview of the Atmel CISC
controllers.

The PIC microcontrollers are not derivative or compatible with MCS51


microcontrollers. The Microchip PIC microcontroller families are based
on the Harvard RISC microprocessor core. Some PIC microcontrollers
have analog capabilities; others have industry standard buses, LCD, or
high voltage capabilities. The PIC12 through PIC18 families are equipped
with flash memory for program store.

ARM is a family of processors based on a reduced instruction set


computing (RISC) architecture developed by British company ARM
Holdings. 37 billion ARM processors have been produced as of 2013, up
from 10 billion in 2008. They are employed in 95% of smartphones, 35%
of digital televisions and set-top boxes and 10% of mobile computers.

435
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10

436
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

APPENDICES

339
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

340
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

APPENDIX A: The 8051 Instruction Reference


In this Appendix we’ll go through an in-depth explanation of the 8051
instructions. We need to do this before we go any further in our final
projects, so you can better understand them. In these descriptions, several
things are used throughout, that I need to explain, to make it all clearer.
Here they are:

Rn - is one of the eight possible registers in the current register bank.


Remember, there are four possible banks of registers, one of which is the
currently selected bank. Each bank has 8 registers (R0-R7) that can be
used.
direct - is one of the 256 possible direct addresses in the internal RAM of
the 8051. Remember that the 8051 has two distinct sections of memory.
One is the on-board internal RAM, which has 256 addresses, the first 128
being the scratchpad RAM (00-7FH), and the last 128 being the Special
Function Registers (80-FFFH). The other is the external RAM, of which,
in our case, has 32,768 addresses (0–3FFFFH). There are a few
instructions that can have two direct addresses. They are referred to as
direct1 and direct2.

rel - is a relative offset from the next instruction's address. This can be +/-
127 from that address. Remember that the PC is incremented when the
current instruction is loaded, so the offset is relative to the address of the
next instruction. This doesn't matter to you, the programmer, because the
assembler calculates this address based on the address of the label you
placed in the instruction, referring to the relative address in question. The
assembler will, however, give an error if you try to reference an
address further than +/- 127 from the next instruction's address.

Ri - is one of the two registers, in the current bank, that can be used to
index (point to) an internal RAM location. This can be either R0 or R1.
Only these two can be used, and is a hardwired feature of the 8051.

#data - is immediate 8 bit (byte) data. This means that the instruction
contains this data. In the case of a mov A,#data , a two byte
instruction, the first byte is the mov A, command and the second byte is
the data. In this case, that data would be placed in the accumulator.
#data16 - is immediate 16 bit (2 byte) data. This is used with instructions
to load a 16 bit register, like dptr, with an address. The DPTR is the only
16 bit register to use this type of data.
341
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

@ - means "at the address pointed to by". An example may be add


A,@R0. This would add the contents of the accumulator, to the data at the
address in internal RAM, pointed to by R0, and store the result back into
the accumulator.

bit - is a single bit, within a bit addressable byte, in the internal RAM.
Remember that the internal scratchpad RAM is divided up functionally
into different sections. The first 32 bytes hold the 4 register banks, each
with 8 registers. The next 16 bytes are the bit addressable locations, each
location having 8 bits, for a total of 128 bits. These represent bits 00-7fh.
These can be assigned labels with the .equ assembler directive, so that
you don't have to remember their values. The value for a particular bit is
determined by which bit position, in which byte, is being referenced. Bit
0, of the first bit addressable byte, is bit 00h. Bit 7, of the last bit
addressable byte, is bit 7fh. There are also several bit addressable
locations in the Special Function Registers. These occupy bit addresses
80-ffh, making a total possible of 256 bit addresses.

/bit (actually bit with a bar over it) - is the complement of a bit. It
simply means that if the actual state of a particular bit is 0, this would
return a 1 instead. I've never used this feature, but it's there, none the less.

Addr 11 - is an 11 bit, absolute, address. This is a somewhat difficult


concept, but here goes. The actual addressing within the 8051, with the
exception of internal RAM, is 16 bits. This allows for 65,536 unique
addresses. Using 11 bit addressing limits the number to 2048 (2K). To
use this type of addressing, the assumption is made that the effected
address resides within the 2K block you are currently in. There are thirty-
two 2K blocks of memory inside the 8051 address range, looking at it this
way. The first is 0000-07FFH, the second is 0800-0FFFH, the third is
1000-17FFH, and so forth. You may never use this type of addressing,
due to the problem of knowing which 2k block a particular instruction, or
label, is in. Since, using an assembler, you don't know which actual
address any particular instruction or label is at, it makes it risky to use
this kind of addressing. The instruction takes the same amount of time to
execute as a long address (16 bit) and the only savings is 1 byte of
program memory. If you are pressed for space, you can use this type of
addressing.

addr 16 - is a 16 bit, long, address. This can be any address within the
address space of the 8051. This addressing takes a 3 byte instruction, as
opposed to 2 bytes for absolute addressing.
342
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

( ) - means "the contents of". For instance (A) means the "contents of the
accumulator".

(( )) - means "the contents of the location pointed to by the contents of".


For instance ((Ri)) means the contents of the location pointed to by the
contents of Ri.

Lastly, when using an assembler, a label can be assigned to any direct


location, bit location, long address, absolute address, or relative address
in the 8051, so that you refer to it by the name instead of the actual value.
This makes things much easier to keep up with. The following
descriptions don't use this, but remember it's there.

Also, the assembler has some hard-coded names that can be used to refer
to different bits and direct addresses in the Special Function Registers.
For instance bit 0 of the accumulator (direct bit address e0h) is referred to
as acc.0 .

There are four flags in the 8051 that indicate various conditions as the
result of an instruction. These are the C (carry), AC (auxiliary carry), OV
(overflow), and P (parity) flags.

The C flag is set by either an overflow or underflow of the accumulator. If


you add a number to the accumulator that results in a number greater than
255 (FFH), a carry will result. If you subtract a larger number from a
smaller number, a borrow will result. If neither of these happen, the carry
flag will be cleared. The carry flag can also be set, cleared, or
complemented by Boolean instructions.

The AC flag is set when the previous operation resulted in a carry


(addition) or a borrow (subtraction) from the high order nibble. This is
used for BCD arithmetic.

The OV flag is set when a carry was generated into the high order bit, but
not a carry out of the high order bit, or if there was a carry out of the high
order bit, but not a carry into the high order bit. It is normally used in 2's
complement arithmetic. OV is also set if a divide by zero was executed.

The P flag is set if the modulo-2 sum of the eight bits of the accumulator
is 1 (odd parity). It's cleared if even parity. This is an extravagant way of
saying that if you add up the number of 1's in the accumulator, and they
come out odd, P is set. If there is an even number, P is cleared.

343
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

There is one more flag (F0) that can be set by software for whatever
purpose. It's really just another bit to twiddle, but it gets saved when the
PSW is pushed. All these flags reside in the PSW (Program Status Word)
register. Here is how they are laid out.

PSW.0 (PSW bit 0) is P


PSW.1 is unused
PSW.2 is OV
PSW.5 is F0
PSW.6 is AC
PSW.7 is C

PSW.3 and 4 indicate what register bank is currently selected. PSW.3 is


the low order bit and PSW.4 is the high order bit.

00 is bank 0
01 is bank 1
10 is bank 2
11 is bank 3

This is how the register bank is selected. You load the PSW with the
value that corresponds to the register bank you want to select. a 00h
selects bank 0, 08h selects bank 1, 10h selects bank 2, and 18h selects
bank 3. At power up or after a reset, bank 0 is always selected, until you
select another. The main reason to use bank switching is to allow for
faster ISR's or subroutines and also lessen the need for a larger stack. By
using a register bank to hold most of the variables used by a particular
routine, that runs a lot, extra pushes and pops can be avoided that would
have saved and restored these variables in the stack, also saving precious
machine cycles.

We typically use bank 0 for the operating loop, another bank for the RS-
232 ISR, another for the 120 Hz ISR, and another for whatever.

The stack is a portion of internal RAM (typically towards the end of


RAM) that is used for temporary storage of addresses and data. When a
call or interrupt happens, 2 bytes are pushed for the return address. Then
as many bytes as needed are also pushed, to save their contents, for the
return. This usually includes the accumulator, since it's used by so many
instructions, and the PSW, since it holds the state of which bank is being
currently used and may be holding some flag contents that will be needed
upon return from the routine. This means that, at a minimum, 4 bytes will
be pushed for every interrupt or subroutine routine. If the stack overflows
344
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

(runs out of internal RAM), your system is basically toast, and mumbles
off to mama every time. So the stack is made as large as possible.

When the system boots up, the SP register is initialized to an address.


This is called the "top of the stack". From that point on, the stack "grows
downward" for each push (towards the end of RAM). As addresses and
data are "popped off" the stack, those bytes are freed up, to be used again.
The problem is that you may be inside a subroutine, when an interrupt
occurs, and that ISR may be interrupted by a higher priority interrupt.
Each of these events caused the stack to grow deeper. As each finishes,
the addresses and data are popped off the stack, and eventually it returns
to the top of the stack again. The trick is make enough room for as deep
as the stack might ever get, without running out of memory. This is
usually not a problem, but it must be considered, and enough room
allowed for the stack to grow.

The instructions of the 8051 are divided into five types. They are
Arithmetic Operation, Logical Operation, Data Transfer, Boolean
Variable Manipulation, and Program Branching. Capitalization is used in
these descriptions, though no caps are used in my actual code. Also I've
included a logical explanation to the right of each instruction. This gives
a short visual summary of what the instruction does. Some are too
complicated to describe this way, and I don't.

There are a total of 111 separate instructions, but many variations. I note
any flags that are affected by the instruction. If no flags are mentioned,
then none are affected.

345
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

A-1. Arithmetic Operation

ADD A, Rn (A)=(A) + (Rn) Flags C, AC, OV

Adds the contents of a register to the contents of the accumulator and


stores the result back into the accumulator.

ADD A, direct (A)=(A) + (direct) Flags C, AC, OV

Adds the contents of a direct address to the contents of the accumulator


and stores the result back into the accumulator.

ADD A, @Ri (A)=(A) + ((Ri)) Flags C, AC, OV

Adds the contents of the location pointed to by Ri to the contents of the


accumulator and stores the result back into the accumulator.

ADD A, #data (A)=(A) + #data Flags C, AC, OV

Adds the immediate data in the instruction to the contents of the


accumulator and stores the result back into the accumulator.

ADDC A, Rn (A)=(A) + (C) + (Rn) Flags C, AC, OV

Adds the contents of the register plus the contents of the carry flag, to the
contents of the accumulator, and stores the result back into the
accumulator.

ADDC A, direct (A)=(A) + (C) + (direct) Flags C, AC, OV

Adds the contents of the carry flag, plus the contents of the direct
location, to the contents of the accumulator and stores the result back into
the accumulator.

ADDC A, @Ri (A)=(A) + (C) + ((Ri)) Flags C, AC, OV

Adds the contents of the location pointed to by Ri, plus the contents of
the carry flag, to the contents of the accumulator, and stores the result
back into the accumulator.

ADDC A, #data (A)=(A) + (C) + #data Flags C, AC, OV

Adds the contents of the carry flag, plus the immediate data, to the
346
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

contents of the accumulator and stores the result back into the
accumulator.

SUBB A, Rn (A)= (A) - (C) - (Rn) Flags C, AC, OV

The contents of the carry and the contents of the register are subtracted
from the accumulator and the result is stored back into the accumulator.

SUBB A, direct (A)=(A) - (C) - (direct) Flags C, AC, OV

The contents of the carry and the contents of the direct location are
subtracted from the accumulator and the result is stored back into the
accumulator.

SUBB A, @Ri (A)=(A) - (C) - ((Ri)) Flags C, AC, OV

The contents of the carry and the contents of the location pointed to by
Ri, are subtracted from the accumlator and the result is stored back into
the accumulator.

SUBB A, #data (A)=(A) - (C) - #data Flags C, AC, OV

The contents of the carry and the immediate data are subtracted from the
accumulator and the result is stored back into the accumulator.

INC A (A)=(A) + 1

Increments the contents of the accumulator by 1.

INC Rn (Rn)=(Rn) + 1

Increments the contents of the register by 1.

INC direct (direct)=(direct) + 1

Increments the contents of the direct location by 1.

INC @Ri ((Ri))=((Ri)) + 1

Increments the contents, of the location pointed to by Ri, by 1.

347
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

INC DPTR (DPTR)=(DPTR) + 1

Increments the contents of the dptr register by 1.

DEC A (A)=(A) -1

Decrements the contents of the accumulator by 1.

DEC Rn (Rn)=(Rn) - 1

Decrements the contents of the register by 1.

DEC direct (direct)=(direct) - 1

Decrements the contents of the direct location by 1.

DEC @Ri ((Ri))=((Ri)) - 1

Decrements the contents of the location pointed to by Ri, by 1.

MUL AB (B15-8), (A7-0)=(A) * (B) Flags C, OV

Multiplies the contents of the accumulator by the contents of register b


and stores the low order byte back into the accumulator and the high
order byte back into register b. This multiplies two 8 bit numbers with a
16 bit result. If the result is greater than 255, in other words the b register
has something other than zero in it, the OV flag will be set. The C flag
will always be cleared.

DIV AB Flags C, OV

Divides the accumulator by the b register and places the integer part of
the quotent in the accumulator. The integer remainder is placed in the b
register. The C flag is always cleared. In the event that the b register was
originally zero (divide by zero), the OV flag will be set, indicating a
divide by zero error.

DA A Flags C, AC

This instruction is VERY complicated. It is used to adjust the


accumulator after an add, that involved BCD (binary coded decimal)
348
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

numbers, so that the accumulator has the proper BCD result in it. I'm not
going to discuss this instruction any further, due to it's complexity and the
use of BCD. You can find a two page description of how it works in
Intel's "MCS 51 Microcontroller Family User's Manual". It is a handy
instruction if you are going to be using BCD numbers, otherwise you will
never use it. DA A stands for "Decimal adjust Accumulator for
Addition". It could be handy for interfacing to a BCD display.

A-2. Logical Operation

ANL A, Rn (A)=(A) AND (Rn)

The contents of the accumulator are ANDED with the contents of the
register and the result is stored back into the accumulator.

ANL A, direct (A)=(A) AND (direct)

The contents of the accumulator are ANDED with the contents of the
direct location and the result is stored back into the accumulator.

ANL A, @Ri (A)=(A) AND ((Ri))

The contents of the accumulator are ANDED with the contents of the
location pointed to by Ri, and the result is stored back into the
accumulator.

ANL A, #data (A)=(A) AND #data

The contents of the accumulator are ANDED with the immediate data and
the result is stored back into the accumulator.

ANL direct, A (direct)=(direct) AND (A)

The contents of the accumulator are ANDED with the direct location and
the result is stored back into the direct location.

ANL direct, #data (direct)=(direct) AND #data

The contents of the direct location are ANDED with the immediate data
and the result is stored back into the direct location.

349
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

ORL A, Rn (A)=(A) OR (Rn)

The contents of the accumulator are OR'ed with the contents of the
register and the result is stored back into the accumulator.

ORL A, direct (A)=(A) OR (direct)

The contents of the accumulator are OR'ed with the contents of the direct
location and the result is stored back into the accumulator.

ORL A, @Ri (A)=(A) OR ((Ri))

The contents of the accumulator are OR'ed with the contents of the
location pointed to by Ri, and the result is stored back into the
accumulator.

ORL A, #data (A)=(A) OR #data

The contents of the accumulator are OR'ed with the immediate data and
the result is stored back into the accumulator.

ORL direct, A (direct)=(direct) OR (A)

The contents of the accumulator are OR'ed with the direct location and
the result is stored back into the direct location.

ORL direct, #data (direct)=(direct) OR #data

The contents of the direct location are OR'ed with the immediate data and
the result is stored back into the direct location.

XRL A, Rn (A)=(A) XOR (Rn)

The contents of the accumulator are XOR'ed with the contents of the
register and the result is stored back into the accumulator.

XRL A, direct (A)=(A) XOR (direct)

The contents of the accumulator are XOR'ed with the contents of the
direct location and the result is stored back into the accumulator.

350
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

XRL A, @Ri (A)=(A) XOR ((Ri))

The contents of the accumulator are XOR'ed with the contents of the
location pointed to by Ri, and the result is stored back into accumulator.

XRL A, #data (A)=(A) XOR #data

The contents of the accumulator are XOR'ed with the immediate data and
the result is stored back into the accumulator.

XRL direct, A (direct)=(direct) XOR (A)

The contents of the accumulator are XOR'ed with the direct location and
the result is stored back into the direct location.

XRL direct, #data (direct)=(direct) XOR #data

The contents of the direct location are XOR'ed with the immediate data
and the result is stored back into the direct location.

CLR A (A)= 0

The accumulator is cleared, or zero'ed out.

CPL A (A)=(/A)

The contents of the accumulator is complemented. All one's become


zero's and all zero's become one's.

RL A

The contents of the accumulator are rotated left by one bit. Bit 7 goes into
bit 0.

RR A

The contents of the accumulator are rotated right by one bit. Bit 0 goes
into bit 7.

RLC A Flags C

351
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

The contents of the accumulator are rotated left, through the carry flag.
Bit 7 goes into the carry, and the carry goes into bit 0.

RRC A Flags C

The contents of the accumulator are rotated right, through the carry flag.
The carry goes into bit 7 and bit 0 goes into the carry.

SWAP A (A3-0)=(A7-4)

The upper nibble of the accumulator is swapped with the lower nibble.
This can also be looked at as a 4 bit rotate. No flags are affected.

A-3. Data Transfer

MOV A, Rn (A)= (Rn)

The accumulator is loaded with the contents of the register.

MOV A, direct (A)=(direct)

The accumulator is loaded with the contents of the direct location.

MOV A, @Ri (A)=((Ri))

The accumulator is loaded with the contents of the location pointed to by


Ri.

MOV A, #data (A)= #data

The accumulator is loaded with the immediate data.

MOV Rn, A (Rn)=(A)

The register is loaded with the contents of the accumulator.

MOV Rn, direct (Rn)= (direct)

The register is loaded with the contents of the direct location.

MOV Rn, #data (Rn)= #data

352
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

The register is loaded with the immediate data.

MOV direct, A (direct)= (A)

The direct location is loaded with the contents of the accumulator.

MOV direct, Rn (direct)= (Rn)

The direct location is loaded with the contents of the register.

MOV direct1, direct2 (direct1)= (direct2)

The direct1 location is loaded with the contents of the direct2 location.

MOV direct, @Ri (direct)= ((Ri))

The direct location is loaded with the contents of the location pointed to
by Ri.

MOV direct, #data (direct)= #data

The direct location is loaded with the immediate data.

MOV @Ri, A ((Ri))= (A)

The location pointed to by Ri is loaded with the contents of the


accumulator.

MOV @Ri, direct ((Ri))= (direct)

The location pointed to by Ri is loaded with the contents of the direct


location.

MOV @Ri, #data ((Ri))= #data

The location pointed to by Ri is loaded with the immediate data.

MOV DPTR, #data16 (DPTR)= #data16

The DPTR register is loaded with the 16 bit immediate data.

353
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

MOVC A, @A + DPTR (A)= ((A) + (DPTR))

The accumulator is loaded with the location in program memory pointed


to by the original contents of the accumulator plus the contents of the dptr
register. This is a handy instruction for implementing a lookup table in
program memory. Say you created a table of ascii values that represent
the numbers 0 thru 9. The ascii value for 0 would be the first entry in the
table and the ascii value for 9 would be the last entry in the table. By
setting dptr to the start of the table, if the accumulator had a 0 in it, the
instruction would return with the first entry in the table, which is the ascii
value for 0, in the accumulator. Walla! I use this one regularly.

MOVC A, @A + PC (A)=((A) + (PC))

This instruction acts exactly as the previous one except the PC (program
conter) is the register used. I haven't came up with a good use for this
instruction yet. But it is there to use.

MOVX A, @Ri (A)= ((Ri))

Loads the accumulator with the contents of the location, in external data
memory, pointed to by Ri. This means that the first 256 locations in
external data memory could be used by this instruction, possibly for
frequently used variables or buffers. There are other options for this
instruction if you are using p2 and p0 of the 8051 for an external memory
address/data bus. You could load p2 with the high order address bits and
then use this instruction to access the 256 locations, or the page of
memory pointed to by p2. This would allow you to create 256 pages of
256 locations, using a 64K RAM chip. I haven't used this instruction for
anything yet, but it seems like it could be useful.

MOVX @Ri, A ((Ri))= (A)

This is just like the previous instruction, except that the external location
is loaded with the contents of the accumulator.

MOVX A, @DPTR (A)= ((DPTR))

Loads the accumulator with the contents of the location in external data
memory pointed to by dptr. This one works for all the locations in

354
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

external data memory, and I use it a lot.

MOVX @DPTR, A ((DPTR))= (A)

Loads the location in external data memory pointed to by dptr, with the
contents of the accumulator. Again, I use this one a lot for larger buffers
that I don't have space for in internal data RAM.

PUSH direct (SP)=(SP) + 1 ; ((SP))=(direct)

Increments the stack pointer (SP) and stores the contents of the direct
location into the location pointed to by sp. This is one of the most used
instructions. It, along with the POP instruction, implement the stack
within the 8051. The stack is used to temporarily store addresses and
datA, to allow the use of subroutines, with less memory overhead than
would be possible without it. It also allows for relatively fast temporary
storage and retrieval of information. The stack resides in internal RAM,
usually towards the end of the internal RAM.

POP direct (direct)=((SP)) ; (SP)=(SP) - 1

Loads the direct location with the contents of the location pointed to by
the sp, then decrememts the sp register.

XCH A, Rn (A)=(Rn)

The contents of the accumulator and the contents of the register are
swapped. This is handy for intermediate storage of the accumulator
contents, or for retrieving the contents of a register, while also saving the
contents of the accumulator.

XCH A, direct (A)=(direct)

The contents of the accumulator and the contents of a direct location are
swapped. Also handy.

XCH A, @Ri (A)=((Ri))

The contents of the accumulator and the contents of the location pointed
to by Ri are swapped.

XCHD A, @Ri (A3-0)=((Ri3-0)

355
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

The low order nibble of the accumulator and the low order nibble of the
location pointed to by Ri are swapped. The high order nibbles are not
affected.

A-4. Boolean Variable Manipulation

CLR C (C)=0

The carry flag is cleared.

CLR bit (bit)=0

The direct bit location is cleared.

SETB C (C)=1

The carry flag is set.

SETB bit (bit)=1

The direct bit location is set.

CPL C (C)=(/C)

The carry flag is complemented. If it was a 0, it's now a 1, and vise versa.

CPL bit (bit)=(/bit)

The direct bit location is complemented.

ANL C, bit (C)=(C) AND (bit)

The carry flag is AND'ed with the direct bit location and the result is
stored back into the carry.

ANL C, /bit (C)=(C) AND (/bit)

The carry flag is AND'ed with the complement of the direct bit location
and the result is stored back into the carry.

356
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

ORL C, bit (C)=(C) OR (bit)

The carry is OR'ed with the direct bit location and the result is stored
back into the carry.

ORL C, /bit (C)=(C) OR (/bit)

The carry is OR'ed with the complement of the direct bit location and the
result is stored back into the carry.

MOV C, bit (C)= (bit)

The carry flag is loaded with the contents of the direct bit location.

MOV bit, C (bit)= (C)

The direct bit location is loaded with the contents of the carry.

A-5. Program Branching

ACALL addr 11

The PC is incremented by 2 and then it is pushed onto the stack, low byte
first (2 pushes, one for each byte) and the immediate 11 bits of the
instruction are concatenated with (added in, but not ADDED to) the high
order 5 bits of the incremented PC, creating the 16 bit address. The sp is
incremented by 2 in the process. The incremented PC value and the
address to which the call is being made, must reside in the same 2K block
of memory. I never use this one.

LCALL addr 16

The PC is incremented by 2 and pushed (as the previous instruction) on to


the stack, then the PC is loaded with the immediate 16 bit address in the
instruction. This is the one I always use for a call.

RET

The PC is popped off of the stack, loading it with the address popped off
(2 pops, one for each byte). The sp is decremented by two in the process.

RETI

357
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

This does the same thing as the RET, but in addition, it re-enables the
interrupts to accept another interrupt of the same or lower level (priority).
This is used to return from an interrupt service routine. Should an
interrupt of a higher level occur, it is serviced, even though it might be in
the middle of servicing a lower level interrupt.

AJMP addr 11

This does the same thing as the ACALL, except no address is pushed
onto the stack.

LJMP addr 16 (PC)= addr 16

The PC is loaded with the immediate address in the instruction, which


causes the next instruction to come from the new address. Same as the
LCALL except no address is pushed onto the stack.

SJMP rel

The PC is incremented by 2 and then the relative offset is added to the PC


to get the new address. The next instruction will come from there. This is
good for short jumps (+/- 127 locations from the incremented PC
address).

JMP @A + DPTR (PC)=(A) + (DPTR)

The PC is loaded with the address resulting from adding the contents of
the accumulator to the contents of the DPTR register. Neither the
accumulator nor DPTR contents are changed. This could be used for
making a jump table. The accumulator contents would determine what
jump was executed in the table. If the DPTR is set to the start of the table
and the accumulator has an even number in it, then the AJMP at that
location would be executed. If the accumulator has multiples of 3 in it,
then you could use LJMP's in the table. A seemingly handy, but tricky,
instruction that I've never used, so far.

JZ rel

The PC is incremented by two (to get to the address of the next


instruction, as normal). If the accumulator contents are zero, then the
relative offset in the instruction is added to the incremented PC and the
next instruction comes from there. If the accumulator isn't zero, the next
instruction after the JZ is executed.
358
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

JNZ rel

This acts just like the JZ, except the relative offset is added if the
accumulator isn't zero, or the next instruction after the JNZ is executed, if
it is zero.

JC rel

The PC incremented by 2, and if the carry is set, the relative offset is


added to the PC and the next instruction comes from there. Otherwise the
next instruction after the JC is executed.

JNC rel

Like the JC except the offset is added if the carry is 0, otherwise the next
instruction is executed.

JB bit, rel

As in previous examples the PC is incremented by two. If the direct bit


location is 1, the offset is added, otherwise the next instruction is
executed.

JNB bit, rel


Same as JB, except offset is added if the direct bit location is 0, otherwise
the next instruction is executed.

JBC bit, rel

Same as JB, except that if the bit is 1, it is cleared and the offset added.
Otherwise the next instruction is executed.

CJNE A,direct, rel Flags C


Compares the accumulator with the direct location and, if they're not
equal, adds the offset to the PC. Otherwise the next instruction is
executed. If A is less than direct, then C is set. Otherwise it's cleared.

CJNE A, #data, rel Flags C


Compares the accumulator with the immediate data and, if they're not
equal, adds the offset. Otherwise the next instruction is executed. If A is
less than #datA, then C is set. Otherwise it's cleared.
359
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A

CJNE Rn, #data, rel Flags C

Compares the register with the immediate data and, if they're not equal,
adds the offset. Otherwise the next instruction is executed. If Rn is less
than #datA, then C is set. Otherwise it's cleared.

CJNE @Ri, #data, rel Flags C

Compares the location pointed to by Ri, with the immediate data and, if
they're not equal, adds the offset. Otherwise, the next instruction is
executed. If @Ri is less than #datA, then C is set. Otherwise it's cleared.

DJNZ Rn, rel

Decrements the register and, if not zero, adds the offset to the PC.
Otherwise, the next instruction is executed. This is used for looping.

DJNZ direct, rel

Decrements the contents of the direct location and, if not zero, adds the
offset. Otherwise, the next instruction is executed. Used for looping.

NOP

This instruction does absolutely nothing, except waste instruction cycles.


That's it's sole purpose. Sometimes it's necessary to wait a short time after
executing an instruction, before executing another. You may need to use
it for I/O accesses mostly. You output the select lines and then wait a
small time to let the chips setup, then read or write. The NOP instruction
uses up only one instruction cycle.

360
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

APPENDIX A2: Test of all 8051 Opcodes (in all configurations)

The following program is a test of all 8051 opcodes in all configurations.


You may edit or download it, compile it and trace its execution using any
simulator, in order to understand the 8051 assembly instructions and
addressing mechanisms. You may also consider it as a reference for all
possible configurations of the 8051 assembly instructions.

.org 0
stest: acall stest
ajmp*
ljmp *+5 ;jump over next line of code
add a,#00
sjmp *-h'd ;jump to stest
add a,#h'ff
add a,00
add a,h'ff
add a,@r0
add a,@r1
add a,r0
add a,r1
add a,r2
add a,r3
add a,r4
add a,r5
add a,r6
add a,r7
addc a,#00
addc a,#h'ff
addc a,00
addc a,h'ff
addc a,@r0
addc a,@r1
addc a,r0
addc a,r1
addc a,r2
addc a,r3
addc a,r4
addc a,r5
addc a,r6
addc a,r7
ajmp stest
361
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

anl a,#00
anl a,#h'ff
anl a,00
anl a,h'ff
anl a,@r0
anl a,@r1
anl a,r0
anl a,r1
anl a,r2
anl a,r3
anl a,r4
anl a,r5
anl a,r6
anl a,r7
anl h'00,a
anl h'ff,a
anl h'00,#00
anl h'00,#h'ff
anl h'ff,#00
anl h'ff,#h'ff
anl c,00
anl c,h'ff
anl c,/00
anl c,/h'ff
cjne a,h'00,stest
cjne a,h'ff,stest
cjne a,#h'00,stest
cjne a,#h'ff,stest
cjne r0,#h'00,stest
cjne r7,#h'ff,stest
cjne @r0,#h'00,stest
cjne @r1,#h'ff,stest
clr a
clr h'00
clr h'ff
clr c
cpl a
cpl h'00
cpl h'ff
cpl c
da a
dec a
dec r0
362
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

dec r1
dec r2
dec r3
dec r4
dec r5
dec r6
dec r7
dec h'00
dec h'ff
dec @r0
dec @r1
div ab
loop1: djnz r0,loop1
djnz r1,loop1
djnz r2,loop1
djnz r3,loop1
djnz r4,loop1
djnz r5,loop1
djnz r6,loop1
djnz r7,loop1
djnz h'00,loop1
djnz h'ff,loop1
inc a
inc r0
inc r1
inc r2
inc r3
inc r4
inc r5
inc r6
inc r7
inc h'00
inc h'ff
inc @r0
inc @r1
inc dptr
loop: jb h'00,loop
jb h'ff,loop
jbc h'00,loop
jbc h'ff,loop
jc loop
jmp @a+dptr
jnb h'00,loop
363
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

jnb h'ff,loop
jnc loop
jnz loop
jz loop
lcall stest
ljmp stest
mov a,r0
mov a,r1
mov a,r2
mov a,r3
mov a,r4
mov a,r5
mov a,r6
mov a,r7
mov a,h'00
mov a,h'ff
mov a,@r0
mov a,@r1
mov a,#h'00
mov a,#h'ff
mov r0,#h'00
mov r0,#h'ff
mov r0,h'00
mov r0,h'ff
mov r0,a
mov r1,#h'00
mov r1,#h'ff
mov r1,h'00
mov r1,h'ff
mov r1,a
mov r2,#h'00
mov r2,#h'ff
mov r2,h'00
mov r2,h'ff
mov r2,a
mov r3,#h'00
mov r3,#h'ff
mov r3,h'00
mov r3,h'ff
mov r3,a
mov r4,#h'00
mov r4,#h'ff
mov r4,h'00
364
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

mov r4,h'ff
mov r4,a
mov r5,#h'00
mov r5,#h'ff
mov r5,h'00
mov r5,h'ff
mov r5,a
mov r6,#h'00
mov r6,#h'ff
mov r6,h'00
mov r6,h'ff
mov r6,a
mov r7,#h'00
mov r7,#h'ff
mov r7,h'00
mov r7,h'ff
mov r7,a
mov h'00,a
mov h'00,r0
mov h'00,r1
mov h'00,r2
mov h'00,r3
mov h'00,r4
mov h'00,r5
mov h'00,r6
mov h'00,r7
mov h'00,h'00
mov h'00,h'ff
mov h'00,@r0
mov h'00,@r1
mov h'00,#h'00
mov h'00,#h'ff
mov h'ff,a
mov h'ff,r0
mov h'ff,r1
mov h'ff,r2
mov h'ff,r3
mov h'ff,r4
mov h'ff,r5
mov h'ff,r6
mov h'ff,r7
mov h'ff,h'00
mov h'ff,h'ff
365
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

mov h'ff,@r0
mov h'ff,@r1
mov h'ff,#h'00
mov h'ff,#h'ff
mov @r0,#h'00
mov @r0,#h'ff
mov @r0,h'00
mov @r0,h'ff
mov @r0,a
mov @r1,#h'00
mov @r1,#h'ff
mov @r1,h'00
mov @r1,h'ff
mov @r1,a
mov c,h'00
mov c,h'ff
mov h'00,c
mov h'ff,c
mov dptr,#h'00ff
mov dptr,#h'ff00
movc a,@a+dptr
movc a,@a+pc
movx a,@r0
movx a,@r1
movx a,@dptr
movx @r0,a
movx @r1,a
movx @dptr,a
mul ab
nop
orl a,#00
orl a,#h'ff
orl a,00
orl a,h'ff
orl a,@r0
orl a,@r1
orl a,r0
orl a,r1
orl a,r2
orl a,r3
orl a,r4
orl a,r5
orl a,r6
366
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

orl a,r7
orl h'00,a
orl h'ff,a
orl h'00,#00
orl h'00,#h'ff
orl h'ff,#00
orl h'ff,#h'ff
orl c,00
orl c,h'ff
orl c,/00
orl c,/h'ff
pop h'00
pop h'ff
push h'00
push h'ff
ret
reti
rl a
rlc a
rr a
rrc a
setb h'00
setb h'ff
setb c
rloop2: sjmp rloop2
subb a,#00
subb a,#h'ff
subb a,00
subb a,h'ff
subb a,@r0
subb a,@r1
subb a,r0
subb a,r1
subb a,r2
subb a,r3
subb a,r4
subb a,r5
subb a,r6
subb a,r7
swap a
xch a,@r0
xch a,@r1
xch a,r0
367
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

xch a,r1
xch a,r2
xch a,r3
xch a,r4
xch a,r5
xch a,r6
xch a,r7
xch a,h'00
xch a,h'ff
xchd a,@r0
xchd a,@r1
xrl a,#00
xrl a,#h'ff
xrl a,00
xrl a,h'ff
xrl a,@r0
xrl a,@r1
xrl a,r0
xrl a,r1
xrl a,r2
xrl a,r3
xrl a,r4
xrl a,r5
xrl a,r6
xrl a,r7
xrl h'00,a
xrl h'ff,a
xrl h'00,#00
xrl h'00,#h'ff
xrl h'ff,#00
xrl h'ff,#h'ff
acall stest
add a,#forward2
add a,#forward1
add a,00
add a,forward1
add a,@r0
add a,@r1
add a,r0
add a,r1
add a,r2
add a,r3
add a,r4
368
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

add a,r5
add a,r6
add a,r7
addc a,#forward2
addc a,#forward1
addc a,00
addc a,forward1
addc a,@r0
addc a,@r1
addc a,r0
addc a,r1
addc a,r2
addc a,r3
addc a,r4
addc a,r5
addc a,r6
addc a,r7
ajmp stest
anl a,#forward2
anl a,#forward1
anl a,00
anl a,forward1
anl a,@r0
anl a,@r1
anl a,r0
anl a,r1
anl a,r2
anl a,r3
anl a,r4
anl a,r5
anl a,r6
anl a,r7
anl forward2,a
anl forward1,a
anl forward2,#forward2
anl forward2,#forward1
anl forward1,#forward2
anl forward1,#forward1
anl c,00
anl c,forward1
anl c,/00
anl c,/forward1

369
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

rloop3: cjne a,forward2,rloop3


cjne a,forward1,rloop3
cjne a,#forward2,rloop3
cjne a,#forward1,rloop3
cjne r0,#forward2,rloop3
cjne r1,#forward1,rloop3
cjne r2,#forward2,rloop3
cjne r3,#forward1,rloop3
cjne r4,#forward2,rloop3
cjne r5,#forward1,rloop3
cjne r6,#forward2,rloop3
cjne r7,#forward1,rloop3
cjne @r0,#forward2,rloop3
cjne @r1,#forward1,rloop3
clr a
clr forward2
clr forward1
clr c
cpl a
cpl forward2
cpl forward1
cpl c
da a
dec a
dec r0
dec r1
dec r2
dec r3
dec r4
dec r5
dec r6
dec r7
dec forward2
dec forward1
dec @r0
dec @r1
div ab
loop2: djnz r0,loop2
djnz r1,loop2
djnz r2,loop2
djnz r3,loop2
djnz r4,loop2

370
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

djnz r5,loop2
djnz r6,loop2
djnz r7,loop2
djnz forward2,loop2
djnz forward1,loop2
inc a
inc r0
inc r1
inc r2
inc r3
inc r4
inc r5
inc r6
inc r7
inc forward2
inc forward1
inc @r0
inc @r1
inc dptr
loop3: jb forward2,loop3
jb forward1,loop3
jbc forward2,loop3
jbc forward1,loop3
jc loop3
jmp @a+dptr
jnb forward2,loop3
jnb forward1,loop3
jnc loop3
jnz loop3
jz loop3
lcall stest
ljmp stest
mov a,r0
mov a,r1
mov a,r2
mov a,r3
mov a,r4
mov a,r5
mov a,r6
mov a,r7
mov a,forward2
mov a,forward1

371
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

mov a,@r0
mov a,@r1
mov a,#forward2
mov a,#forward1
mov r0,#forward2
mov r0,#forward1
mov r0,forward2
mov r0,forward1
mov r0,a
mov r1,#forward2
mov r1,#forward1
mov r1,forward2
mov r1,forward1
mov r1,a
mov r2,#forward2
mov r2,#forward1
mov r2,forward2
mov r2,forward1
mov r2,a
mov r3,#forward2
mov r3,#forward1
mov r3,forward2
mov r3,forward1
mov r3,a
mov r4,#forward2
mov r4,#forward1
mov r4,forward2
mov r4,forward1
mov r4,a
mov r5,#forward2
mov r5,#forward1
mov r5,forward2
mov r5,forward1
mov r5,a
mov r6,#forward2
mov r6,#forward1
mov r6,forward2
mov r6,forward1
mov r6,a
mov r7,#forward2
mov r7,#forward1
mov r7,forward2

372
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

mov r7,forward1
mov r7,a
mov forward2,a
mov forward2,r0
mov forward2,r1
mov forward2,r2
mov forward2,r3
mov forward2,r4
mov forward2,r5
mov forward2,r6
mov forward2,r7
mov forward2,forward2
mov forward2,forward1
mov forward2,@r0
mov forward2,@r1
mov forward2,#forward2
mov forward2,#forward1
mov forward1,a
mov forward1,r0
mov forward1,r1
mov forward1,r2
mov forward1,r3
mov forward1,r4
mov forward1,r5
mov forward1,r6
mov forward1,r7
mov forward1,forward2
mov forward1,forward1
mov forward1,@r0
mov forward1,@r1
mov forward1,#forward2
mov forward1,#forward1
mov @r0,#forward2
mov @r0,#forward1
mov @r0,forward2
mov @r0,forward1
mov @r0,a
mov @r1,#forward2
mov @r1,#forward1
mov @r1,forward2
mov @r1,forward1
mov @r1,a

373
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

mov c,forward2
mov c,forward1
mov forward2,c
mov forward1,c
mov dptr,#forward2ff
mov dptr,#forward100
movc a,@a+dptr
movc a,@a+pc
movx a,@r0
movx a,@r1
movx a,@dptr
movx @r0,a
movx @r1,a
movx @dptr,a
mul ab
nop
orl a,#forward2
orl a,#forward1
orl a,00
orl a,forward1
orl a,@r0
orl a,@r1
orl a,r0
orl a,r1
orl a,r2
orl a,r3
orl a,r4
orl a,r5
orl a,r6
orl a,r7
orl forward2,a
orl forward1,a
orl forward2,#forward2
orl forward2,#forward1
orl forward1,#forward2
orl forward1,#forward1
orl c,00
orl c,forward1
orl c,/00
orl c,/forward1
pop forward2
pop forward1

374
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

push forward2
push forward1
ret
reti
rl a
rlc a
rr a
rrc a
setb forward2
setb forward1
setb c
rloop: sjmp rloop
subb a,#forward2
subb a,#forward1
subb a,00
subb a,forward1
subb a,@r0
subb a,@r1
subb a,r0
subb a,r1
subb a,r2
subb a,r3
subb a,r4
subb a,r5
subb a,r6
subb a,r7
swap a
xch a,@r0
xch a,@r1
xch a,r0
xch a,r1
xch a,r2
xch a,r3
xch a,r4
xch a,r5
xch a,r6
xch a,r7
xch a,forward2
xch a,forward1
xchd a,@r0
xchd a,@r1
xrl a,#forward2

375
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2

xrl a,#forward1
xrl a,00
xrl a,forward1
xrl a,@r0
xrl a,@r1
xrl a,r0
xrl a,r1
xrl a,r2
xrl a,r3
xrl a,r4
xrl a,r5
xrl a,r6
xrl a,r7
xrl forward2,a
xrl forward1,a
xrl forward2,#forward2
xrl forward2,#forward1
xrl forward1,#forward2
xrl forward1,#forward1
synctst:

farloop:
.equ forward1,h'ff
.equ forward2,h'00
.org h'4100 ;check out ajumps

fartest:
ajmp neartest
nop
neartest:
nop
.end

376
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX B

APPENDIX B: Summary of PIC Instruction Set


The following table summarizes the PIC16xx instructions

377
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX B

378
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX B

379
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX B

380
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C

APPENDIX C: Summary of ARM Instruction Set


The ARM instruction set we summarize here is the set of instructions that
ARM Cortex-M3 microcontrollers support.

Cortex-M3 instructions are always little-endian. Data memory accesses


are little endian but the processor can be configured to access data in a
big-endian format via a configuration pin which is sampled on reset. It is
not possible to change endianness following reset. Note that registers in
the System Control Space and accesses to any system peripherals are
always little-endian regardless of the configuration.

Cortex-M3 devices are debugged via a standard JTAG or Serial-Wire


Debug (SWD) connector. A simple, standardized external connector is
required to interface to the host system.

ARM instructions. Instructions in bold are the core ARM instructions.


Instructions in italics are provided by the Floating Point. Thumb
instructions are a 16-bit compressed form of the most commonly used
ARM.

Instruction Meaning Comments


ABS Absolute Value Floating Point 1
ACS Arc Cosine Floating Point 5
ADC Add with Carry -
ADC Thumb: Add with Carry Thumb
ADD Add -
ADD Thumb: Add Thumb
ADF Add Floating Point 1 3
ADR Get address of object (within 4K) This is an assembler
pseudo-instruction
ADRL Get address of object (beyond 4K) This is an assembler
pseudo-instruction
ALIGN Set the program counter to the next This is an assembler
word boundary pseudo-instruction
AND Logical AND -
AND Thumb: Logical AND Thumb
ASL Arithmetic Shift Left option, not
instruction
381
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C

Instruction Meaning Comments


ASN Arc Sine Floating Point 5
ASR Arithmetic Shift Right option, not
instruction.
ATN Arc Tangent Floating Point 5
B Branch -
B Thumb: Branch Thumb
BIC Bit Clear -
BIC Thumb: Bit Clear Thumb
BKPT Thumb: Breakpoint Thumb
BL Branch with Link -
BL Thumb: Long Branch with Link Thumb
BLX Branch with Link and Exchange Thumb
BX Thumb: Branch and Exchange Thumb
CDP Co-processor data operation -
CDP2 CDP, non-conditional ARMv5
CLZ Count Leading Zeros ARMv5
CMF Compare floating point value Floating Point 1 3
CMN Compare negated values -
CMN Thumb: Compare negated values Thumb
CMP Compare values -
CMP Thumb: Compare values Thumb
CNF Compare negated float point value Floating Point 1
COS Cosine Floating Point 5
DVF Divide Floating Point 1 3
EOR Exclusive-OR two values -
EOR Thumb: Logical Exclusive-OR Thumb
EQUx Define byte (B), halfword (W), word This is an
(D), string (S), or floating point (F). assembler pseudo-
instruction
EXP Exponent Floating Point 5
FABS VFP: Absolute VFP
FADD VFP: Addition VFP

382
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C

FCMP VFP: Compare VFP


Instruction Meaning Comments
FCVTDS VFP: Single to Double VFP
FCVTSD VFP: Double to Single VFP
FCPY VFP: Copy [like MVF] VFP
FDIV VFP: Division VFP
FDV Fast Divide Floating Point 1
FIX Convert floating value to an integer Floating Point 1 3
FLD VFP: Load VFP registers VFP
FLDMDB VFP: Load multiple VFP registers, VFP
decr. before
FLDMIA VFP: Load multiple VFP registers, VFP
incr. after
FLT Convert integer to a floating value Floating Point 1 3
FMAC VFP: Multiply with Accumulate VFP

FMDHR VFP: Transfer ARM register to upper VFP


half of Double
FMDLR VFP: Transfer ARM register to lower VFP
half of Double
FMRDH VFP: Transfer upper half of Double VFP
to ARM register
FMRDL VFP: Transfer lower half of Double VFP
to ARM register
FML Fast multiply Floating Point 1
FMSC VFP: Multiply with Negate and VFP
Accumulate
FMRS VFP: Transfer Single to ARM VFP
register
FMSR VFP: Transfer ARM register to VFP
Single
FMUL VFP: Multiply VFP
FMRX VFP: Transfer VFP system register VFP
to ARM register
FMSTAT VFP: Transfer FPSCR flags to VFP
CPSR

383
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C

Instruction Meaning Comments


FMXR VFP: Transfer ARM register to VFP VFP
system register
FNEG VFP: Copy Negative [like MVN] VFP
FNMAC VFP: Multiply with Deduct VFP
FNMSC VFP: Multiply with Negate and VFP
Deduct
FNMUL VFP: Negative Multiply VFP
FRD Fast reverse divide Floating Point 1
FSITO VFP: Signed Integer to Float VFP
FSQRT VFP: Square Root VFP
FST VFP: Save VFP registers VFP
FSTMDB VFP: Save multiple VFP registers, VFP
decr. before
FSTMIA VFP: Save multiple VFP registers, VFP
incr. after
FSUB VFP: Subtraction VFP
FTOSI VFP: Float to Signed Integer VFP
FTOUI VFP: Float to Unsigned Integer VFP
FUITO VFP: Unsigned Integer to Float VFP
LDC Load from memory to co-processor -
LDC2 LDC, non-conditional so more co- ARMv5
processor commands possible
LDF Load floating point value Floating Point 1 3
LDM Load multiple registers -
LDMIA Thumb: Load multiple registers Thumb
LDR Load register (32 bit) -
LDR Thumb: Load register (32 bits?) Thumb
LDRB Load byte (8 bit) into register -
LDRB Load byte (8 bit) into register Thumb
LDRH Load halfword (16 bit) into register StrongARM
LDRH Load halfwit (boo!) into register Thumb
LDRSB Load signed byte (sign + 7 bit) into StrongARM
register

384
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C

Instruction Meaning Comments


LDRSB Thumb: Load signed byte (sign + 7 Thumb
bit) into register
LDRSH Load signed halfword (sign + 15 bit) StrongARM
into register
LDRSH Thumb: Load signed halfword (sign Thumb
+ 15 bit) into register
LFM Load multiple floating point values Floating Point 1
LGN Logarithm to base e Floating Point 5
LOG Logarithm to base 10 Floating Point 5
LSL Logical Shift Left option, not
instruction.
LSR Logical Shift Right option, not
instruction.
MCR Coprocessor register transfer (ARM to
coprocessor)-
MCR2 MCR, non-conditional so more co- ARMv5
processor commands possible
MCRR MCR, with two registers transferred ARMv5TE
at one time
MLA Multiply with Accumulate -
MNF Move negated Floating Point 1
MOV Move value/register into a register -
MOV Move value/register into register Thumb
MRC Co-processor register transfer (co-processor to
ARM)
MRC2 MRC, non-conditional so more co- ARMv5
processor commands possible
MRRC MRC, with two registers transferred ARMv5TE
at one time
MRS Move status flags to a register ARM 6
MSR Move register content to status flags ARM 6
MUF Multiply Floating Point 1 3
MUL Multiply -
MUL Thumb: Multiply Thumb

385
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C

MVF Move value/float to float register Floating Point


MVN Move negated -
MVN Thumb: Move negated Thumb
NEG Thumb Negate Thumb
NOP Thumb: No Operation Thumb
NRM Normalise Floating Point 1
OPT Select assembly options pseudo-instruction
ORR Logical OR -
ORR Thumb: Logical OR Thumb
PLD PreLoaD ARMv5
POL Polar Angle Floating Point 5
POP Thumb: Pop registers from stack Thumb
POW Power Floating Point 5
PUSH Thumb: Push registers onto stack Thumb
QADD Add, saturating ARMv5E
QDADD Add, double saturating ARMv5E
QDSUB Subtract, double saturating ARMv5E
QSUB Subtact, saturating ARMv5E
RDF Reverse Divide Floating Point 1
RFC Read FP control register Floating Point 1 4
RFS Read FP status register Floating Point 1 3
RMF Remainder Floating Point 2 3
RND Round to integral value Floating Point 2 3
ROR Rotate Right option, not
nstruction
RPW Reverse Power Floating Point 5
RRX Rotate Right with extend option, not
instruction
RSB Reverse Subtract -
RSC Reverse Subtract with Carry -
RSF Reverse Subtract Floating Point 1
SBC Subtract with Carry -
SBC Thumb: Subtract with Carry Thumb
SFM Store Muliple Floating point values Floating Point 1

386
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C

Instruction Meaning Comments


SIN Sine Floating
Point
SMLA Signed Multiply with Accumulate of 16 bit * ARMv5E
16 bit values
SMLAL Signed Long (sign + 63 bit) Multiply with Strong ARM
Accumulate
SMLAL Signed Multiply with Accumulate of 16 bit * ARMv5E
16 bit values,
SMLAW Signed Multiply with Accumulate of 32 bit * ARMv5E
16 bit values
SMUL Signed Multiply of 16 bit * 16 bit ARMv5E
SMULL Signed Long (sign + 63 bit) Multiply Strong ARM
SMULW Signed Multiply of 32bit *16bit ARMv5E
SQT Square Root Floating
Point 2 3
STC Co-processor data transfer -
STC2 STC, non-conditional so more co-processor ARMv5
commands possible
STF Store floating point value Floating
Point
STM Store multiple registers -
STMIA Thumb: Store multiple registers Thumb
STR Store a register (32 bit) -
STR Thumb: Store register (32 bit?) Thumb
STRB Store a byte (8 bit) from a register -
STRB Thumb: Store byte (8 bit) Thumb
STRH Store a halfword (16 bit) from a register Strong ARM
STRH Thumb: Store halfword (16 bit) Thumb
STRSB Store a signed byte (sign + 7 bit) from a Strong ARM
register
STRSH Store a signed half-word (sign + 15 bit) from Strong ARM
a register
SUB Subtract -
SUB Thumb: Subtract Thumb

387
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C

Instruction Meaning Comments


SUF Subtract Floating Point
SWI Cause a SoftWare Interrupt -
SWI Thumb: SoftWare Interrupt Thumb
SWP Swap register with memory ARM 3
TAN Tangent Floating Point
5

TEQ Test Equivalence (notional EOR) -


TST Test bits (notional AND) -
TST Thumb: Test bits Thumb
UMLAL Unsigned Long (64 bit) Multiply with Strong ARM
Accumulate
UMULL Unsigned Long (64 bit) Multiply Strong ARM
URD Unnormalised round Floating Point
1

WFC Write FP control register Floating Point


14

WFS Write FP status register Floating Point


1

388
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX D

APPENDIX D: Structure of the HEX file


When compiling or assembling a source code for a microcontroller, HEX
file is created (with extension .hex). The contents of this file are loaded into
the program memory of the microcontroller, by a dedicated microcontroller
programmer (burner). HEX file is made with following structure

:BBAAAATTHHHHHHHH ............ HHCC

The following table depicts the data

Data Meaning Description


position
BB Record This is a two digit hexadecimal byte count representing
size the number of data bytes that will appear on the line.
The data which appear on the line is a maximum of 16
bytes. When there is more than 16 bytes, a new line is
started. So, the maximum which is shown in BB is '10h'.
AAAA Address This is a four digit hexadecimal address representing the
starting address of the data record. 1 word of the
program is 2 bytes.(Because it is 14 bits actually, 2 bits
of higher ranks are 0) So, as the address of the program
memory, it becomes a 1 bit shifted value.
For example, in case of program address '0001h', it is
represented as '0002h' in AAAA. Behind the 2nd line, it
begins from the head of the 16-byte integral multiple.
For example, when the address with record at the head is
'000Ch', it is represented in the same record to '000Fh'
and is represented at the new record from '0010h'.
:04000C008D018E01D3
:100010008F01900191019201930194019601970142
:08002000980199019A019B016E
:00000001FF
TT Record This is a two digit record type that will always be '00'
type except for the end-of-file record, which will be '01'.
Generally, ':00000001FF' is represented for the end-of-
file record.
HHHH Data byte This is a 2 digit hexadecimal data byte, presented in low-
byte/high-byte combinations. In case of '018C', it will be
'8C01'.

389
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX D

CC Checksum This is a two digit hexadecimal checksum that is the


two's complement of the sum of all preceding bytes in
the record. For example, ':040002008C018C0A', ecomes
'129h' when totaling all bytes. Only the low-byte is
effective. The 2's complement of '29h' is 'D7h'. This is
put to the end of record as the checksum. When checking
data, it totals all bytes of the record which excluded the
checksum and adds the result and a checksum. If the
result becomes zero, data is judged normal. 29h + D7h =
00h ( we ignores carry here)

390
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

GLOSSARIES

391
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

GLOSSARIES

ABEL. A design language for creating the logic to be implemented in a


simple programmable logic device. Short for Advanced Boolean
Expression Language. Programs created with ABEL are compiled into
the binary pattern necessary to create the PLD with a device programmer

ACPI: Advanced Configuration and Power Interface. A specification that


defines a new interface to the system board that enables the operating
system to implement operating-system-directed power management and
system configuration.

ADC: Analog-to-digital converter. A hardware device that reads an


analog signal--typically a voltage--compares it to a reference signal and
converts the resulting percentage to a digital value.

Address bus: A set of electrical lines connected to the processor and all
of the peripherals with which it communicates. The address bus is used
by the processor to select a specific memory location or register within a
particular peripheral. If the address bus contains n electrical lines, the
processor can uniquely address up to 2^n such locations.

Address Space. Address space is the amount of memory a CPU is


designed to access. It is limited by the number of bits (binary digits) the
CPU uses for addressing. The 8088 CPU provided a 20 bit Address Bus
and can access one Megabyte of Memory (2 to the 20th power).The
80386 and 80486 devices have 32 Address lines and can access more than
4 gigabytes of Memory (2 to the 32nd power).

ADSL: Asymmetric Digital Subscriber Line. A speed method for


transferring data over regular phone lines (copper wires).

AGP: Accelerated Graphics Port.

Analog Describes data represented by a continuous range of values.


API: Application programming interface. A set of routines that an
applications program uses to request and carry out lower-level services
performed by a computer operating system.

ARM A 32-bit RISC processor widely used in low-power embedded


applications. Short for Advanced RISC Machine.

392
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

ARM Thumb A 16-bit variant of the 32-bit ARM instruction set. ARM
processors that support the Thumb instruction set can be switched in and
out of "Thumb mode" via a bit in a register. Once in the Thumb mode, the
CPU fetches special 16-bit instructions from memory. The advantage of
these instructions is that they can be fetched more quickly across a
narrower data bus and consume less memory. Not all of the ARM's
capabilities are supported in Thumb mode, however

ASCII: American Standard Code for Information Interchange. The most


popular coding method used by small computers for converting letters,
numbers, punctuation, and control codes into digital form.

ASIC: Application-Specific Integrated Circuit. A piece of custom-


designed hardware on a single chip.

Assembler: A software development tool that translates human-readable


assembly language programs into machine-language instructions that the
processor can understand and execute.

Assembly Language: A human-readable form of a processor's instruction


set. Most processor-specific functions must be written in assembly
language.

Asynchronous communications: A communications scheme that


transmits data over a single wire, sending bits one at a time in sequence.
The timing of each bit is known by both transmitter and receiver. Each
transmitted data byte begins with a start bit that starts the receiver's
timing circuitry. Critical to the success of a synchronous communications
is that the data bits have well-defined widths.

BER: Bit Error Rate. A measure of the noise ration in digital signals.

Big-endian: A representation of a multi-byte value that has the most


significant byte of any multi-byte data field stored at the lowest memory
address, which is also the address of the larger field.

BIOS: Basic Input Output Services. Some basic routines stored in ROM
memory and provide instructions for system start-up and communication
with hardware devices. The BIOS also provides Basic I/O Services to the
Operating System and to Applications. BIOS routines are stored on a
ROM chip. In the XT type computer, the BIOS ROM was 8K bytes and
its address range started at FE000H (FE00:0000). The PC/AT used a 64K
byte BIOS ROM that started at address F0000H, and this has been used in
all Intel based hardware ever since.
393
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

Baud Rate (BPS): Bits per second. The number of bits transferred per
second in a data communications system. A measure of communication
speed.
Bitmap (BMP): Representation of characters or graphics by individual
pixels arranged in rows (horizontal) and columns (vertical). Each pixel
can be represented by either 1 bit (simple black and white) or up to 3 2
bits (high-definition color).

Bus Enumerator: In a Plug and Play system, a bus device driver that
detects devices located on a specific bus and loads information about
devices into the hardware tree.

BlueTooth: Bluetooth is a wireless networking technology, that connects


different adjacent devices, like cell phone, TV’s and computers (within
limited area, 10-100m).

C99: An abbreviation for a 1999 update to the international standard for


the C programming language. One of C99's most exciting enhancements
is built-in definition of signed and unsigned integer data types of 8, 16,
and 32 bits. They are typedef'd as uint8_t, int8_t, uint16_t, etc. in the
platform-specific library header <stdint.h>.

CAN Controller Area Network Is a bus standard, designed specifically


for automotive applications

Cache Memory A block of on-chip or off-chip fast access memory


locations, situated between the processor and main memory, used for
storing and retrieving copies of often used instructions, data, or
instructions and data.
CISC: Complex Instruction Set Computer. Describes the architecture of a
processor family. CISC processors generally feature variable-length
instructions, multiple addressing formats, and contain only a small
number of general-purpose registers. Intel's 80x86 family is the
quintessential example of CISC. Contrast with RISC.

CMSIS Cortex Microcontroller Software Interface Standard. A vendor-


independent hardware abstraction layer for the Cortex-Mx processors. It
enables consistent, scalable, and simple software interfaces to the
processor for interfacing peripherals, real-time operating systems, and
middleware,

394
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

Compiler A program that translates source code from a high-level


programming language, such as C/C++, to a lower level language, for
example, assembly language or machine code. A compiler is likely to
perform many or all of the following operations: lexical analysis,
preprocessing, parsing, semantic analysis, code generation, and code
optimization. μVision implements C/C++ compilers.

COP: Computer-Operating properly. The COP is just renaming for the


watch-dog-timer (WDT) in Motorola processors and microcontrollers.

CPLD: Complex Programmable Logic Device. Each CPLD typically


consists of several programmable logic blocks plus a matrix of
programmable interconnecting paths. CPLDs can be used to create larger
and more advanced logic circuits than PLDs, but are generally smaller
and less flexible than FPGAs.

CPU: Central Processing Unit. The part of a processor that executes


instructions.

CRC: Cyclic Redundancy Code. A particular type of checksum.

Checksum: A numerical check value generated from a larger set of data.

Compiler: A software development tool that translates high-level


language programs into the machine-language instructions that a
particular processor can understand and execute.

Cross-compiler: A compiler that runs on a different platform than the


one for which it produces object code. A cross-compiler runs on a host
computer and produces object code for the target.

Debugger A computer program to test software. Debuggers offer


sophisticated functions such as running a program step-by-step (single-
stepping), stopping, pausing the program to examine the current state at
some kind of event through breakpoints, and tracking the values of
variables.

Device Driver. An operating system enhancement program loaded during


boot up by CONFIG.SYS and remaining in memory. Such programs
perform communication functions between the computer and attached
hardware devices such as sound cards, CDROM drive, optical scanners,
local area networks and non standard hardware, not provided by the BIOS
or a BIOS Extension ROM.
395
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

DMA: Direct Memory Access. A technique for transferring data directly


between two peripherals (usually memory and an I/O device) with only
minimal intervention of the CPU.

DMAC: DMA Controller (e.g., the Intel 8237 chip).

DRAM: Dynamic Random-Access Memory. A type of RAM that


maintains its contents only as long as the data stored in the device is
refreshed at regular intervals. The refresh cycles are usually performed by
a peripheral called a DRAM controller.

DSP: Digital signal processor. A device that is similar to a


microprocessor, except that the internal CPU has been optimized for use
in applications involving discrete-time signal processing. In addition to
standard microprocessor instructions, DSPs usually support a set of
specialized instructions, like multiply-and-accumulate (MAC), to
perform common signal-processing computations quickly. A Harvard
architecture, featuring separate code and data memory spaces, is
commonly used to speed data throughput. Common DSP families are the
Texas Instruments 320Cxx and Motorola's 5600x series.

ECP: Extended capabilities parallel port. An asynchronous, 8-bit-wide


parallel channel defined by IEEE 12841944 that provides PC-to-
peripheral and peripheral to-PC data transfers.

EDO DRAM: Extended Data Output Dynamic Random Access Memory.


It is a type of DRAM that is faster than conventional DRAM. Unlike
conventional DRAM, which only allows one byte to be read at a time,
EDO DRAM can copy an entire block of memory to its internal cache.
While the processor is accessing this cache, the memory can collect a new
block to send.

EEPROM: Electrically Erasable, Programmable Read-Only Memory.


(Pronounced "Double-E"-PROM.) A type of ROM that can be erased
electronically.

EMI: Electromagnetic Interference.

EPROM: Erasable, Programmable Read-Only Memory. A type of ROM


that can be erased by exposing it to ultraviolet light. Once erased, an
EPROM can be reprogrammed with a device programmer.

Embedded System: A combination of computer hardware and software,


and perhaps additional mechanical or other parts, designed to perform
396
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

a dedicated function. In some cases, embedded systems are part of a


larger system or product, as is the case of an anti-lock braking system in a
car. Contrast with general-purpose computer.

Embedded Controller: The class of microcontrollers used to support


OEM-specific implementations, mainly in cars and mobile
communication environments.

Emulator: Short for In-Circuit Emulator (ICE). A debugging tool that


takes the place of (emulates) the processor on your target board.
Emulators frequently incorporate a special "bond-out" version of the
target processor that allows you to observe and record its internal state as
your program is executing.

Endianness: The way of representing bytes in computers. All processors


and communication protocols are either big-endian or little-endian.

ESD: Electrostatic Discharge or Electrostatic damage. The human body


may hold substantial electrostatic charge which may damage CMOS
integrated circuits (IC’s), when touched or handled without care.
However, most of recent IC’s are ESD protected internally.

EPP: Extended Parallel Port. An enhanced bi-directional parallel port.

FPGA: Field Programmable Gate Array. A type of logic chip, with


thousands of internal gates, that can be programmed. FPGAs are
especially popular for prototyping integrated circuit designs. However,
once the design is finalized, hard-wired chips called ASICs are often used
instead for their faster performance and lower cost.

Firmware: Embedded software that is stored as object code within a


ROM. This name is more common among the users of digital signal
processors.

Flash memory: A RAM-ROM hybrid that can be erased and rewritten


under software control. Such devices are divided into blocks, called
sectors, that are individually-erasable. Flash memory is common in
systems that require nonvolatile data storage at very low cost. In some
cases, a large flash memory may even be used instead of a disk-drive.

FTP: File Transfer Protocol.

GDI: Graphics Device Interface. A part of Windows operating system.


397
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

GDT: Global Descriptor Table. A method for memory addressing in 32-


bit microprocessors (like 80386).

GSM: Global system for mobile communications

HLA: High-level Assembly. A class of computer programming languages


which looks like high-level languages but have the capabilities of
assembly language. The C-language is sometimes considered as a HLA.

HTML: Hyper-text Mark-up Language. A standard language for internet


page design.

HTTP: Hyper-text transfer protocol.

I2C: Inter-Integrated Circuit. Pronounced "Eye Squared C" . An I2C bus


is an inexpensive type of chip interconnection that is popular on circuit
boards. Compare with 1-Wire and SPI.
ICE: In-Circuit Emulator. See emulator. A hardware device used to
debug software of an embedded system.

IDE: Integrated Device Electronics. A type of disk drive interface where


the controller electronics reside on the drive itself, eliminating the need
for a separate adapter card.

I/O: Input/Output. The interface between a processor and the external


world around it. For instance, switches are inputs and LEDs are outputs.
I/O device: A piece of hardware that interfaces between the processor
and the outside world. Common examples are switches and LEDs, serial
ports, and network controllers. Also called a peripheral.

I/O map: A table or diagram containing the name and address range of
each I/O device addressable by the processor within the I/O space. I/O
maps are a helpful aid in getting to know the target.

Instruction set An instruction set, or instruction set architecture (ISA), is


the part of the microcontroller architecture related to programming,
including the native data types, instructions, registers, addressing modes,
memory architecture, interrupt and exception handling, and external I/O.

Internet: A worldwide network of thousands of smaller computer


networks and millions of commercial, educational, government, and
personal computers. The Internet is like an electronic city with virtual
libraries, storefronts, business offices, art galleries, and so on.
398
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

Intranet: A network within an organization that uses Internet


technologies (such as the HTTP or FTP protocols). You can use an
intranet to move between objects, documents, pages, and other
destinations using hyperlinks.

IP: Internet Protocol. The way (protocol) of sending data over the
internet.

IRQ: Interrupt request. A method by which a device can request to be


serviced by the device's software driver. The system board uses a PIC to
monitor the priority of the requests from all devices. When a request
occurs, the microprocessor suspends the current operation and gives
control to the device driver associated with the interrupt number issued.
The lower the number-for example, IRQ3-the higher the priority of the
interrupt. Many devices only support raising requests of specific
numbers.

ISA Bus: Industry Standard Architecture Bus. A 16-bit expansion bus


that provides a buffered interface for devices on expansion cards in the
PC internal bus

ISI: Inter-symbol Interference.

ISR: Interrupt-service Routine.

JTAG: A standard for providing external test access to integrated circuits


serially, via a 5-pin external interface. JTAG is an acronym for a the Joint
Test Action Group, which developed the standard. The JTAG standard
has been adopted as an IEEE standard (IEEE 1149 Standard Test Access
Port and Boundary-Scan Architecture). JTAG ports have been very
widely embraced by processor manufacturers. Some debug monitors and
emulators leverage the capabilities inherent in JTAG.

Linker: A software development tool that accepts one or more object


files as input and outputs a relocatable program. The linker is thus run
after all of the source files have been compiled or assembled.

Little-endian: A representation of a multi-byte value that has the least


significant byte of any multi-byte data field stored at the lowest memory
address, which is also the address of the larger field. Contrast big-endian.

LAN: Local area network. A group of computers and devices dispersed


over a relatively limited area and connected by a communications link
399
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

that enables any device to interact with any other on the network.

Macro Defines a rule or pattern that specifies how a certain input


sequence should be mapped to an output sequence.

Mainframe. A very large computer with many users. Before PCs were
available, the term "mainframe" meant the cabinet containing the central
processor unit (CPU) of the large computer. Still commonly used in
enterprise contexts, mainframes can be accessed from Windows NT
through the COM Transaction Integrator (COMTI).

MAC: Multiply-and-accumulate. A special CPU instruction, common on


digital signal processors, that performs both a multiplication and an
addition in a single instruction cycle. The result of the multiplication is
typically added to a sum kept in a register. A multiply-and-accumulate
(MAC) instruction is helpful for speeding up the execution of the digital
filters and transforms required in signal processing applications.

Microcontroller: A microcontroller is very similar to a microprocessor.


The main difference is that a microcontroller is designed specifically for
use in embedded systems. Microcontrollers typically include a CPU,
memory (a small amount of RAM and/or ROM), and other peripherals on
the same chip. Common examples are the PIC and 8051, Intel's 80196,
and Motorola's 68HCxx series.

Microprocessor: An integrated circuit containing a general-purpose


CPU. The most common examples are Intel's 80x86 and Motorola's
680x0 families.

Monitor Program: A program for 8051 and C166 devices. It can be


loaded into your target microcontroller to aid in debugging and rapid
product development through rapid software downloading.

Multitasking: The execution of multiple software routines in pseudo-


parallel. Each routine represents a separate "thread of execution" and is
referred to as a task. The operating system is responsible for simulating
parallelism by parceling out the processor's time.

NVRAM: Non-Volatile Random-Access Memory. A type of RAM that


retains its data even when the system is powered down. NVRAM
frequently consists of an SRAM and a long-life battery.

400
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

Network processor: A device that is similar to a microprocessor, except


that it has been optimized for use in applications involving network
packet processing. There is no standard architecture, but many network
processors feature multiple CPUs running in parallel. In this
configuration, one central processor typically receives and handles
"control packets" while the others pass "data packets" through the system.

OTP: One-time programmable ROM. Any programmable device, like a


PROM, that can be programmed just once by the end user. This term is
used almost exclusively to refer to microcontrollers with on-chip PROM.

Opcode: A sequence of bits that is recognized by the processor as one of


the instructions in its instruction set.

Open Software: Third party software for which the source code is
available. Unfortunately, there is no clear definition for "open source
software" and no standard license agreement. Many companies are using
this term these days in far different ways. While the idea is similar to that
of free software (you can use, modify, and redistribute the software),
there is less emphasis on the right of the source code to be free.

Operating System (OS): A software which is responsible for deciding


which task should be using the processor at a given time, and for
controlling access to shared resources. The operating consists of a set of
function calls, or software interrupts, and a periodic clock tick.

Object code: A set of processor-readable opcodes and data. The output of


compilers, and assemblers, are files containing object code.

PC. Personal Computer.

PCA. Programmable Counter Array. See PIT.

PIC. Programmable Interrupt Controller (e.g., the Intel 8259 chip).

PIO. Parallel Input/Output (e.g., the Intel 8255 chip).

PIT. Programmable Interval Timer/Counter (e.g., the Intel 8243 chip).

PPI. Programmable Peripheral Interface (e.g., the Intel 8255 chip).


Protected Mode. A mode of operation for the 80286 and above CPUs,
which allows software running on them to access memory beyond 1 M
byte. Multi-tasking operating systems run in protected mode.

401
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

PWM: Pulse width modulation. A technique of digital modulation. Some


microcontrollers have PWM ports, that produce output pulse, whose duty
cycle is proportional to a certain digital signal.value.

Physical address: The actual address that is placed on the address bus
when accessing a memory location or register.

Plug-and-Play (PnP): Set of specifications and design methodology that


describe hardware and software changes to the PC and its peripherals that
automatically identify and arbitrate resource requirements among all
devices and buses on the system. Plug and Play specifies a set of API
elements that are used in addition to, not in place of, existing device
driver architecture.
Preemptive: An operating system is said to be preemptive if it allows the
running task to be suspended when a higher-priority task becomes ready.
Non-preemptive schedulers are easier to implement but less appropriate
for embedded systems, which must be responsive to external events.

Polling: A method of interfacing to a peripheral that involves repeatedly


reading a status register until the device has reached the awaited state.
Device drivers are either polling or interrupt-driven, with the latter being
more generally preferred.

Priority: The relative importance of one task compared to another.

Protocol stack: Any set of communication protocols, such as TCP/IP,


that consists of two or more layers of software and hardware.
It's called a stack because each layer builds on the functionality in the
layer below. For example, in TCP/IP parlance, the lowest layer is called
the physical layer. That's the where the rubber meets the road; or, more
accurately, the bits meet the communications hardware medium at the
network interface. Above that is the data link layer, which gives each
device on the network its unique address. These first two layers of the
TCP/IP protocol stack are typically implemented in hardware. Once the
networked devices have addresses, they can communicate. That's where
layer three, the network layer, comes in. The internet protocol (IP) is just
one of the protocols that exists at this level in a TCP/IP stack; TCP and
UDP are competing protocols at the transport layer. Three more layers of
software (session, presentation, and application) are defined above
those, thus completing the 7-layer OSI Reference Model.
When data is sent across the network, it generally begins at layer 5 or
above, travels down through the protocol stack on the sending system, out
402
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

onto the network, then back up the stack on the receiving system.
RAM: Random-Access Memory. A broad classification of memory
devices that includes all devices in which individual memory locations
may be read or written as required.

RISC: Reduced Instruction Set Computer. Describes the architecture of a


processor family. RISC processors generally feature fixed-length
opcodes, a load-store memory architecture, and a large number of
general-purpose registers and/or register windows. The MIPS processor
family is an excellent example. Contrast with CISC.

ROM: Read-Only Memory. A classification of memory devices in which


the memory locations may be read, but not written
Real Mode. A mode of operation of 80286 and above. It makes the CPU
operate like 8088, and restricts its memory addressing to 1MByte. DOS
and most application programs operate in real mode.

Simulation Is the imitation of a real thing or process. Some micro-


controller IDEs have simulation capabilities to create embedded
applications without using ‘real’ hardware.

Software interrupt: An interruption of a program that is initiated by a


software instruction. Software interrupts are commonly used to
implement breakpoints and operating system entry points. Unlike true
interrupts, they occur synchronously with respect to program execution.
In other words, software interrupts always occur at the beginning of an
instruction execution cycle

SPI: Serial Peripheral Interface. An inexpensive synchronous serial bus


for chip interconnection, which is popular in microcontroller applications.

SRAM: Static Random-Access Memory. A type of RAM that retains its


contents as long as the system is powered on. Data stored in an SRAM is
lost when the system is powered down or reset.

.Stack: An area of memory that contains a last-in-first-out (LIFO) queue


of storage for parameters, automatic variables, return addresses, and other
information that must be maintained across function calls.

SVG: Scalable vector Graphics. Representation of graphics by scalable


vectors.

SVGA: Super VGA. A video standard established by VESA to


403
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

provide high-resolution color display on IBM-compatible computers. The


most commonly implemented SVGA standard is 1024x768 pixels
resolution

S-Video: A video signal that separates the luminance and color (Y and C)
components of the signal for improved quality over composite video. The
type of video signal used in the Hi8 and S-VHS videotape formats. It
transmits luminance and color portions separately, using multiple wires,
thus avoiding the NTSC encoding process which reduces picture quality.

TAPI: Telephony Application Program Interface. A set of Win32 calls


that applications use to control modems and telephones by routing
application function calls to the appropriate service provider DLL.

TCP/IP: Transmission Control Protocol/Internet Protocol.

TDMA: Time-division multiple access

Thumb, Thumb2 An instruction set for ARM and Cortex devices.

Timer: A peripheral used to measure elapsed time, typically by counting


processor cycles or clock pulses.

Target: Another name for the embedded system. This term is usually
used during software development, to distinguish the embedded system
from the host with which it communicates.

Task: The central abstraction of an operating system. Each task maintain


its own copy of the CPU's instruction pointer and general-purpose
registers. Unlike processes, tasks share a common memory space and
must be careful to avoid overwriting each other's code, data, and stack.

Thread: Another name for a task. This name is more common in


operating systems that support processes. A task is simply a thread in a
single-process system.

UART: Universal Asynchronous Receiver/Transmitter. A module


composed of a single integrated circuit (e.g., the 8250 chip), which
contains both the receiving and transmitting circuits required for
asynchronous serial communication.

UML: Unified Modeling Language. A standardized visual notation for


communication about system specifications and design details.

404
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

UPS: Uninterruptible power supply. A device connected between a


computer and a power source that ensures that electrical flow to the
computer is not interrupted because of a blackout and, in most cases,
protects the computer against potentially damaging events such as power
surges and brownouts.

USB: Universal Serial Bus. A bi-directional, isochronous, dynamically


attachable serial interface for adding peripheral devices such as game
controllers, serial and parallel ports, and input devices on a single bus.

UTP: Unshielded twisted pair (wires).

VESA: Video Electronics Standards Association. The governing body


that establishes standards for the video and graphics portions of the
electronics industry.

Virtual Machine (VM). Software that mimics the performance of a


hardware device..

Virtual Mode. A mode of operation of 80386 and above CPUs that


extends memory addressing capacity up to 16TB (tera byte).

VPN: Virtual Private Network

VRAM: Video Random Access Memory.

VRML: Virtual reality modeling language.

WDT: Watchdog Timer: A hardware timer that is periodically reset by


software. If the software crashes or hangs, the watchdog timer will expire,
and the entire system will be reset automatically.

WAN: Wide area network. A communications network that connects


geographically separated areas.

WLAN: Wireless Local area network. A wireless communication


network that connects different adjacent computer devices.

WOSA: Windows Open System Architecture

Write-through (WT) In a write-through cache, data is written to main


memory at the same time as the cache is updated.
405
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary

WWW: World Wide Web. The World Wide Web is a system for
exploring the Internet by using hyperlinks.

WYSWYG: What you see is what you get. A class of devices and
software, that makes the printed matter looks like the original copy that
you edit on the screen of a PC.

XML: Extended Mark-up Language. A standardized language for


communication and system design.

406
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers References

REFERENCES

[1] Richard H. Barnett, The 8051 Family of Microcontrollers, Prentice-Hall, 1995 (yeah,
that's right, 1995

[2] K. AYALA, The 8051 Microcontroller: Architecture, Programming and Application, West
Publishing, 1999.

[3] M. Sergent, IBM PC Inside Out, McGraw Hill, 1986

[4] F. A. Lyn, Assembly Language Programming (for the MCS-51 family), 1990

[5] Jack G. Ganssle, The Art of Programming Embedded Systems, 1992.

[6] Kernighan & Richie, The C Programming Language (2nd Ed), Prentice-Hall, Inc. ISBN
0-13-110370-9
[7] Schultz, P TR C and the 8051: Programming and Multitasking
Prentice-Hall, Inc. ISBN 0-13-753815-4
[8] Dan Gookin, C for Dummies, ISBN 1-878058-78-9
[9] Herbert Schildt, C The Complete Reference, ISBN 0-07-882101-0
[10] Plum & Brodie, Efficient C, Plum Hall Inc. ISBN 0-911537-05-8
[11] C51 Compiler, Optimizing 8051 C Compiler and Library Reference
User's Guide, Keil Elektronik GmbH

[12] Z.Nakutis, M. Saunoris, “challenges of Embedded Systems Teaching in Electronics


Engineering.” ISSN 1392-1215, No.6 (102), 2010.

[13] Leif Uhsadel, markus Ullrich, Ingrid Verbauwhede and Bart Preneel,
“hardware/software Co-design of RSA on 8051” EWME, 9-11 MAY, 2012.

[14] Data Sheet (PDF). http://ww1.microchip.com/downloads/en/DeviceDoc/41239D.pdf


Microchip Technology, 2007.

[15] ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition, issue C.b,
Section A2.10, 24 July 2012

[16] "ARM Cortex-R Architecture" (PDF). ARM Holdings. October 2013.

[17] ARMv8-R Architecture". Retrieved 10 July 2015

337
Dr. Eng. Muhammad El-Saba
Introduction to Microcontrollers References

[18] C-Compilers for MCS51 MCU’s


C51
ttp://www.keilsoftware.com/home.htm
http://www.equinox-tech.com
Small C
http://www.newmicros.com/smallc51.html
SDCC (freeware 8051 C compiler)
http://www.geocoties.com/ResearchTriangle/Forum/1353/
MICRO-C
http://www.dun®eld.com/dks.htm
MICRO/C-51
htp://www.mcc-us.com/51tools.htm
[19] Pascal Compilers for MCS51 MCU’s
Pascal 51
http://www.grifo.com/SOFT/KSC/Pascal51.htm
Embedded Pascal
http://www/users.iafrica.com/r/ra/rainier/index.htm
[20] Basic Compilers for MCS51 MCU’s
BASCOM
http://www.x54all.nl/$mcselec/bascom.html
TINY BASIC
http://www.code.archive.aisnota.com/
BASIKIT
http://www.mdllabs.com/basikit.htm
BXC-51
http://www.mindspring.com/$tavve/8051/bxc51.html
BEC-51
http://www.windspring.com/$tavve/8051/bec51.html
[21] Useful site on 8051 software and hardware
http://www.cis.ohio-state.edu/hypertext/faq/usenet/microcontroller-
faq/8051/faq.html

338
Dr. Eng. Muhammad El-Saba
_________________________________________

ABOUT THE AUTHOR


__________________________________________

Muhammad H. El-SABA was born in Cairo,


Egypt. He obtained his Ph.D. in integrated
electronics from INSA-Lyon, France, in 1993.
He's been a lecturer, an associate professor and
full professor of electronic and communication
engineering (ECE) at the Engineering Faculty,
Ain-Shams University, in Cairo. Prof. EL-Saba
has been the HoD and the director of ECE
depts. at the Engineering & Petroleum College
in King Faisal University, Hadramout
University, Qassim University in KSA, and
Polytechnic institutes in Australia and South
Africa. He also occupied other political and
managerial positions in many countries allover
the world. During his scientific life-journey, Dr. EL-Saba has been interested
in the development of EDA Tools and implemented the device simulators
SIMULADTM and GOOD-SIMTM . The original tools, which he specifically
developed for VLSI devices & circuits, are currently adopted in the
electronic industry. He authored 31 text books (2 of which by international
publishers) and about 50 articles on modeling, simulation of semiconductor
devices (3 of which in IEEE Transactions), RFIC’s, microprocessors and
microcontrollers. He also prepared and animated several training courses in
different areas of industrial electronics, mobile communications, and VHDL.
His current interests include design and implementation of VLSI circuits &
SoC, with emphasis on communication devices and systems.

View publication stats

You might also like