Combined14 S 2
Combined14 S 2
Combined14 S 2
net/publication/349812349
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:
All content following this page was uploaded by Muhammad El-Saba on 14 June 2021.
Introduction to Microcontrollers
&
Embedded Systems
________________________________________________
i
Dr. Eng. Muhammad El-SABA
Introduction to Microprocessors INDEX
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 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.
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
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
1
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
2
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
Tuner IF Filter
Power Supply
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.
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.
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.
6
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
7
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
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).
9
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
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
11
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
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.
12
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
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.
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.
15
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.
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.
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
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
22
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
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
24
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
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
Eclipse
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
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:
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
30
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
1-10. PROBLEMS
3) Explain, how can you isolate low voltage microcontrollers from high
voltage loads that they are controlling.
31
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 1
32
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
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).
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.
32
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
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).
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
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.
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.
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
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.
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
TCON
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
Timer Flags Interrupt Signals
Fig. 2-9.The Timer control register.
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
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.
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
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.
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.
46
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
Fig. 2-11. Serial communication port of the 8051 microcontrollers.(in serial mode0)
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
Both SM0 and SM1 bits define the mode of serial port communication
according to the following table:
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
2SMODE f osc 1
BAUD RATE ( serial mod e 1) . .
32 12 256 (TH 1)
2SMODE
BAUD RATE (serial mod e 1) .Timer1 Frequency
32
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
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.
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.
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.
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.
53
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
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.
54
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
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.
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.
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.
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
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:
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.
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)
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.
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.
64
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
65
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
66
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
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
69
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
70
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 2
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
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
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-3) List and explain the significance and use of the Special Function
registers in the 8051 microcontroller.
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-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
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.
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.
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.
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.
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.
(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.
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.
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.
As shown, the SFR area contains so many 8-bit control registers. The
description of these registers is as follows:
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.
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.
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
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.
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.
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.
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
PIC instructions are little-endian. Since PIC data memory is 8-bits wide
and is only accessed in bytes, endianness is not relevant.
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
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
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:
The following core registers are also available on all 16-bit devices:
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.
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
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.
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.
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.
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.
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)
ARM has sixteen registers visible at any one time. They are named R0 to
R15. All are 32 bits wide.
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,
3-5. Summary
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.
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.
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.
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.
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.
3-6. PROBLEMS
3-3) Show how to connect an external 32kB code EPROM to the 8051
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
Opcode Operands
mnemonic Argument1 Argument2
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
Symbol Meaning
112
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4
114
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4
115
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4
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.
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:
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).
Table 4-5. The lookup table instructions that read program memoy.
119
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4
120
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4
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 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.
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)
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.
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.
Figure 4-10. Illustration of the stack POP operation of the 8051 microcontroller.
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.
125
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4
127
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4
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:
Here's the original 2 plus 2 problem and the addressing modes of each
instruction:
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
Example5.asm:
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:
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.
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
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.
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.
In µVision you may set a file specific option for C source files that
contain ASM/ENDASM sections as follows:
µ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 ();
#pragma asm
JMP $ ; endless loop
#pragma endasm
}
Example5.asm
extern void test ();
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
Examples9.asm
C51 SAMPLE.C ROM (SMALL)
#pragma ROM (SMALL)
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.
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).
Each of these instructions has several variants. For instance, the MOV
instruction may have one of the following formats:
4-8. PROBLEMS
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.
145
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 4
146
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5
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.
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.
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
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.
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.
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
The instruction set and may be grouped into the functional groups, shown
in the following figure:
150
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5
151
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5
152
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5
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:
154
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5
155
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5
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
157
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5
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).
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‘
movlw D'100'
movwf delcntr2
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
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.
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.
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
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
165
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 5
5-7. Summary
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.
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.
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.
• 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
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.
Actually, the ARM has many possible instruction word formats, as shown
in figure 6-2.
170
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
CMP R1, R2
LDREQ R3, [R4]
LDRNE R3, [R5]
171
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
All instructions can access r0-r14 directly. Most instructions also allow
use of the program counter (PC).
172
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
ADD,
{Rd,} Rn, Op2 Add N,Z,C,V
ADDS
ADD,
{Rd,} Rn, #imm12 Add N,Z,C,V
ADDW
AND,
{Rd,} Rn, Op2 Logical AND N,Z,C
ANDS
B label Branch -
BX Rm Branch indirect -
173
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
LDRB,
Rt, [Rn, #offset] Load Register with byte -
LDRBT
LDRH,
Rt, [Rn, #offset] Load Register with Halfword -
LDRHT
174
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
LDRSB,
Rt, [Rn, #offset] Load Register with Signed Byte -
LDRSBT
MOV,
Rd, Op2 Move N,Z,C
MOVS
MOVW,
Rd, #imm16 Move 16-bit constant N,Z,C
MOV
Move from Special Register to
MRS Rd, spec_reg general register
-
MUL,
{Rd,} Rn, Rm Multiply, 32-bit result N,Z
MULS
MVN,
Rd, Op2 Move NOT N,Z,C
MVNS
NOP - No Operation -
175
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
176
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
STRB,
Rt, [Rn, #offset] Store Register byte -
STRBT
STRH,
Rt, [Rn, #offset] Store Register Halfword -
STRHT
SUB,
{Rd,} Rn, #imm12 Subtract N,Z,C,V
SUBW
{Rd,} Rm {,ROR
SXTB Sign extend a byte -
#n}
{Rd,} Rm {,ROR
SXTH Sign extend a halfword -
#n}
177
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
{Rd,} Rm {,ROR
UXTB Zero extend a Byte -
#n}
{Rd,} Rm {,ROR
UXTH Zero extend a Halfword -
#n}
Table 6-2.
178
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
Table 6-3.
180
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
Table 6-4.
RRX Rotate Right with Extend ASR, LSL, LSR, ROR, RRX
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
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.
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.
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.
183
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
Table 6-6
Mnemonic Brief description Examples
ADC Add with Carry ADD, ADC, SUB, SBC, and RSB
184
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
SBC Subtract with Carry ADD, ADC, SUB, SBC, and RSB
B{cond} <expression>
Table 6-7.
IT If-Then IT
185
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
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.
SWI{cond} <expression>
188
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
189
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
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.
192
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
193
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
194
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
Writing programs using ARM machine code is possible but not practical.
Instead, we write programs using ARM assembly language.
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
195
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
or
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
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.
197
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
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.
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!"
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
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
201
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
202
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
203
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
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
205
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
6-5. Summary
206
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 6
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
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.
209
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
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.
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
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.
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
213
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
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.
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
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.
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.
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.
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:
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 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.
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.
221
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
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.
222
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
The following ANSI library routines are not included in the C51 library:
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:
i. Math Routines
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
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.
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.
229
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
230
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
231
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
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
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.
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.
235
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
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:
For example:
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.
238
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
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
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>
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
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
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:
struct tag {
unsigned bitfield-declarator-list;
}
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;
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);
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)
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;
}
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
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
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.
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\
Add the following line in the definition file for the MCU:
249
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
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.
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
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.
251
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
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);
}
*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 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.
*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.
254
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
255
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
#pragma directive.
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
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 following coding hints are very important, for all microcontroller
architectures.
260
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.
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;
262
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 7
263
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
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:
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.
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.
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
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.
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:
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
Fig. 8-2. Serial driver chips, the Maxim Max232 and the Dallas DS275.
269
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
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.
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.
VCC
0 Px.0
1 Px.1
:
:
:
: :
: :
9 Px.9
Lead-per-key
MC
Keypad
int
271
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
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
** *****************************************************************/
/** ***************************************************************
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 */
/*––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
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
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
** ––––––––––––––––––––––––––––––––––––––––––––––––––––
*/
}/*****************************************************/
/********************************************************************
4- KEYPAD.H
––––––––––––––––––––––––––––––––––––––––––––––––––––––
This file contains the keypad definitions
––––––––––––––––––––––––––––––––––––––––––––––––––––––
*/
#ifndef _KEYPAD_H_
#define _KEYPAD_H_
#include <system.h> /* define system constants */
/* Keypad arrangement
278
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
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_
/*******************************************************************
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
282
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
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.
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
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
#define SetValue 99
/* ***************************************************************
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 */
}
}//***************************************************************
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
} //***************************************************************
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.
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.
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
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.
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
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.
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).
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
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
mov a,r7
setb lcrs ;set lcd to data
clr lcrw ;set lcd to write
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
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
;**********************************************************
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
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
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
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.
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.
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:
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
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.
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
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.
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.
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.
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
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 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.
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.
319
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
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.
'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
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.
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
324
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
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
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.
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.
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.
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.
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.
333
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
334
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
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
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
339
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
8-14. PROBLEMS
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?
340
Prof. Dr. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 8
8-10) Repeat the above problem for a 24-key coded keypad, using only 8
pins and one interrupt input.
8-14) The following circuit may be used to connect any keypad to any
microcontroller, using only one pin (an interrupt pin).
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
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
343
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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.
/* ****************************************************
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();
}
}//***************************************************************
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
}
} //**************************************************************
;*************************************************************** *
; 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
;********************************************************** ******
; 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
348
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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
END „
350
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,
352
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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;
354
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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.
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:
Then the maximum voltage is when Rpc is at its minimum, 1K. Then
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
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
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
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
;********************************************************************
360
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
361
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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:
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)
;********************************************************************
;*****************************************************************
; Names (Constants)
;*****************************************************************
; Give names to pins to simplify code writing. This also makes it
; easy to change pin assignments later.
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)
366
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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 5) Finally, we return pin 2 (Read) to the high state. The next
conversion can be started immediately
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 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.
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
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.
372
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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 */
}
}
}//********************************************************
375
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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
#include c:\mc51\8051io.h
#include c:\mc51\8051reg.h
//****************************************************
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
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
offmsd()
{
if (buffer[3] == 0x3f) /* if msd = '0' then put blank unstead */
buffer[3] = 0x00;
}//*****************************************************
pause(j)
{
int i., j;
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.
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
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
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++) ;
}//******************************************************
}//******************************************************
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
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');
}//******************************************************/
389
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
}//******************************************************
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);
}//******************************************************
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('-');
}
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
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
394
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
395
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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
/*****************************************************************
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
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);
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
402
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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.
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.
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
407
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 9
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
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
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// 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
412
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
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
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:
413
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
414
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
415
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
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
Fig. 10-5. In-circuit programming of the AT89S8252, via the SPI port.
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
421
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
422
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.
68332: added separate Time Processing Unit (TPU) and some RAM. The
TPU can do things like off-line PWM processing.
424
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
425
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
426
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
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
428
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
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
430
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
431
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers CHAPTER 10
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
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
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
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
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 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".
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 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.
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.
(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.
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
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.
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.
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.
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.
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.
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.
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.
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
INC Rn (Rn)=(Rn) + 1
347
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A
DEC A (A)=(A) -1
DEC Rn (Rn)=(Rn) - 1
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
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.
The contents of the accumulator are ANDED with the contents of the
register and the result is stored back into the accumulator.
The contents of the accumulator are ANDED with the contents of the
direct location and the result is stored back into the accumulator.
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.
The contents of the accumulator are ANDED with the immediate data and
the result is stored back into the accumulator.
The contents of the accumulator are ANDED with the direct location and
the result is stored back into the direct location.
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
The contents of the accumulator are OR'ed with the contents of the
register and the result is stored back into the accumulator.
The contents of the accumulator are OR'ed with the contents of the direct
location and the result is stored back into the accumulator.
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.
The contents of the accumulator are OR'ed with the immediate data and
the result is stored back into the accumulator.
The contents of the accumulator are OR'ed with the direct location and
the result is stored back into the direct location.
The contents of the direct location are OR'ed with the immediate data and
the result is stored back into the direct location.
The contents of the accumulator are XOR'ed with the contents of the
register and the result is stored back into the accumulator.
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
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.
The contents of the accumulator are XOR'ed with the immediate data and
the result is stored back into the accumulator.
The contents of the accumulator are XOR'ed with the direct location and
the result is stored back into the direct location.
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
CPL A (A)=(/A)
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.
352
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A
The direct1 location is loaded with the contents of the direct2 location.
The direct location is loaded with the contents of the location pointed to
by Ri.
353
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Appendix A
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.
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.
This is just like the previous instruction, except that the external location
is loaded with the contents of the accumulator.
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
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.
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.
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.
The contents of the accumulator and the contents of a direct location are
swapped. Also handy.
The contents of the accumulator and the contents of the location pointed
to by Ri are swapped.
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.
CLR C (C)=0
SETB C (C)=1
CPL C (C)=(/C)
The carry flag is complemented. If it was a 0, it's now a 1, and vise versa.
The carry flag is AND'ed with the direct bit location and the result is
stored back into the carry.
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
The carry is OR'ed with the direct bit location and the result is stored
back into the carry.
The carry is OR'ed with the complement of the direct bit location and the
result is stored back into the carry.
The carry flag is loaded with the contents of the direct bit location.
The direct bit location is loaded with the contents of the carry.
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
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.
SJMP rel
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
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
JNC rel
Like the JC except the offset is added if the carry is 0, otherwise the next
instruction is executed.
JB 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.
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.
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.
Decrements the register and, if not zero, adds the offset to the PC.
Otherwise, the next instruction is executed. This is used for looping.
Decrements the contents of the direct location and, if not zero, adds the
offset. Otherwise, the next instruction is executed. Used for looping.
NOP
360
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX A2
.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
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
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
382
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C
383
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C
384
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C
385
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C
386
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C
387
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX C
388
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX D
389
Dr. Eng. Muhammad El-SABA
Introduction to Microcontroller APPENDIX D
390
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary
GLOSSARIES
391
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary
GLOSSARIES
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.
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
BER: Bit Error Rate. A measure of the noise ration in digital signals.
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.
394
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary
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.
IP: Internet Protocol. The way (protocol) of sending data over the
internet.
that enables any device to interact with any other on the network.
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).
400
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary
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.
401
Dr. Eng. Muhammad El-SABA
Introduction to Microcontrollers Glossary
Physical address: The actual address that is placed on the address bus
when accessing a memory location or register.
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.
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.
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.
404
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.
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.
[4] F. A. Lyn, Assembly Language Programming (for the MCS-51 family), 1990
[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
[13] Leif Uhsadel, markus Ullrich, Ingrid Verbauwhede and Bart Preneel,
“hardware/software Co-design of RSA on 8051” EWME, 9-11 MAY, 2012.
[15] ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition, issue C.b,
Section A2.10, 24 July 2012
337
Dr. Eng. Muhammad El-Saba
Introduction to Microcontrollers References
338
Dr. Eng. Muhammad El-Saba
_________________________________________