Skip to main content

Full text of "Embedded Programming"

See other formats


M 



■ ■■■JUUI* 



The 8051 
Microcontroller 





The 8051 Microcontroller 

ARCHITECTURE, PROGRAMMING, 
and APPLICATIONS 



Kenneth J. Ayala 

Western Carolina University 



WEST PUBLISHING COMPANY 

ST. PAUL ■ NEW YORK - LOS ANGELES ■ SAN FRANCISCO 



Copyediting: Technical Texts, Inc. 

Text and Cover Design: Roslyn Stendahl, Dapper Design 

Cover Image: Christopher Springmann, The Stock Market 

Composition: G & S Typesetters, Inc. 

Artwork: George Barile, Accurate Art 



COPYRIGHT © 1991 By WEST PUBLISHING COMPANY 

50 W. Kellogg Boulevard 
P.O. Box 64526 
St. Paul, MN 55164-0526 

All rights reserved 

Printed in the United States of America © 

98 97 96 95 94 93 92 91 8 7 6 5 4 3 2 10 

Library of Congress Cataloging-in-Publication Data 

Ayala, Kenneth J. 

The 8051 microcontroller : architecture, programming, 
and applications / Kenneth J. Ayala. 
p. cm. 
Includes index. 
ISBN 0-314-77278-2 (soft) 

1. intet 8051 (Computer) 2. Digital control systems. 
I. Title. 

QA76.8.I27A93 1991 

004.165— dc20 90-12928 

CIP 



-D> 



To John Jamison of VMI and 

John Peatman of Georgia Tech, 

both of whom made this book possible 




Contents 



1 MICROPROCESSORS AND MICROCONTROLLERS 1 

Introduction 1 

Microprocessors and Microcontrollers 2 

Microprocessors 2 

Microcontrollers 3 

Comparing Microprocessors and Microcontrollers 4 
The 280 and the 8051 4 
A Microcontroller Survey 5 

Four-Bit Microcontroller 5 

Eight-Bit Microcontrollers 6 

Sixteen-Bit Microcontrollers 7 

Thirty-Two Bit Microcontrollers 8 
Development Systems for Microcontrollers 9 
Summary 9 
Questions 10 

2 THE 8051 ARCHITECTURE 11 

Introduction 11 

8051 Microcontroller Hardware 11 

The 8051 Oscillator and Clock 16 

Program Counter and Data Pointer 17 

A and B CPU Registers 17 

Flags and the Program Status Word (PSW) 18 

Internal Memory 19 

Internal RAM 19 

The Stack and the Stack Pointer 19 

Special Function Registers 21 

Internal ROM 22 
Input/Output Pins, Ports, and Circuits 22 

Port 23 

Port 1 25 



VII 



ViH CONTENTS 



Port 2 25 

Port 3 25 
External Memory 26 

Connecting External Memory 26 
Counter and Timers 28 

Timer Counter Interrupts 29 

Timing 30 

Timer Modes of Operation 30 

Timer Mode 30 

Timer Mode 1 30 

Timer Mode 2 31 

Timer Mode 3 32 

Counting 32 
Serial Data Input/Output 32 

Serial Data Interrupts 32 

Data Transmission 34 

Data Reception 34 

Serial Data Transmission Modes 34 

Serial Data Mode O-Shift Register Mode 34 

Serial Data Mode 1 -Standard UART 35 

Mode 1 Baud Rates 36 

Serial Data Mode 3 37 
Interrupts 37 

Timer Flag Interrupt 39 

Serial Port Interrupt 39 

External Interrupts 39 

Reset 40 

Interrupt Control 40 

Interrupt Enable/Disable 40 

Interrupt Priority 41 

Interrupt Destinations 41 

Software Generated Interrupts 41 
Summary 41 
Questions 42 



MOVING DATA 44 

Introduction 44 

Addressing Modes 45 
Immediate Addressing Mode 45 
Register Addressing Mode 45 
Direct Addressing Mode 47 
Indirect Addressing Mode 49 

External Data Moves 50 

Code Memory Read-Only Data Moves 51 

PUSH and POP Opcodes 52 

Data Exchanges 53 

Example Programs 54 

Summary 56 

Problems 57 



CONTENTS ix 



LOGICAL OPERATIONS 59 
Introduction 59 
Byte-Level Logical Operations 60 
Bit-Level Logical Operations 62 

Internal RAM Bit Addresses 62 

SFR Bit Addresses 62 

Bit-Level Boolean Operations 63 
Rotate and Swap Operations 66 
Example Programs 68 
Summary 69 
Problems 70 



ARITHMETIC OPERATIONS 71 
Introduction 71 
Flags 72 

Instructions Affecting Flags 72 
Incrementing and Decrementing 73 
Addition 74 

Unsigned and Signed Addition 74 

Signed Addition 75 

Multiple-Byte Signed Arithmetic 76 
Subtraction 77 

Unsigned and Signed Subtraction 78 

Unsigned Subtraction 78 

Signed Subtraction 78 
Multiplication and Division 80 

Multiplication 80 

Division 80 
Decimal Arithmetic 81 
Example Programs 82 
Summary 84 
Problems 85 



JUMP AND CALL OPCODES 86 
Introduction 86 
The Jump and Call Program Range 87 

Relative Range 87 

Short Absolute Range 88 

Long Absolute Range 88 
Jumps 89 

Bit Jumps 89 

Byte Jumps 90 

Unconditional Jumps 90 
Calls and Subroutines 92 

Subroutines 92 

Calls and the Stack 92 



CONTENTS 



Calls and Returns 93 
Interrupts and Returns 94 
Example Problems 95 
Summary 97 
Problems 98 



AN 8051 MICROCONTROLLER DESIGN 100 
Introduction 100 
A Microcontroller Specification 101 
A Microcontroller Design 102 

External Memory and Memory Space Decoding 102 

Reset and Clock Circuits 102 

Expanding I/O 103 

Memory-Mapped I/O 104 

Part Speed 106 

Production Concerns 106 
Testing the Design 107 

Crystal Test 107 

ROM Test 107 

RAM Test 108 
Timing Subroutines 110 

Time Delays 110 

Pure Software Time Delay 111 

Software Polled Timer 112 

Pure Hardware Delay 114 
Lookup Tables for the 8051 117 

PC as a Base Address 118 

DPTR as a Base Address 120 
Serial Data Transmission 121 

Character Transmission Using a Time Delay 123 

Character Transmission by Polling 124 

Interrupt-Driven Character Transmission 125 

Receiving Serial Data 126 

Polling for Received Data 126 

Interrupt-Driven Data Reception 127 
Summary 128 
Problems 129 



8 APPLICATIONS 131 
Introduction 131 
Keyboards 132 

Human Factors 132 

Key Switch Factors 132 

Key Configurations 133 

Programs for Keyboards 134 

A Scanning Program for Small Keyboards 136 

Interrupt-Driven Programs for Small Keyboards 139 



CONTENTS Xi 



Program for a Large Matrix Keyboard 147 
Displays 151 

Seven-Segment Numeric Display 151 

Intelligent LCD Display 155 
Pulse Measurement 158 

Measuring Frequency 158 

Pulse Width Measurement 161 
D/A and A/D Conversions 162 

D/A Conversions 163 

A/D Conversion 165 
Multiple Interrupts 166 

Hardware Circuits for Multiple Interrupts 173 
Putting it all Together 177 
Summary 181 
Problems 182 



SERIAL DATA COMMUNICATION 1 85 

Introduction 185 

Network Configurations 186 

8051 Data Communication Modes 189 
Mode 0: Shift Register Mode 189 
Mode 1 : Standard 8-Bit UART Mode 192 
Modes 2 and 3: Multiprocessor 197 

Summary 202 

Problems 202 



Appendix A 8051 Operational Code Mneumonics 203 

Appendix B How to Use the Assembler 212 

Appendix C How to Use the Simulator 220 

Appendix D The 8255 Programmable I/O Port 233 

Appendix E Control Registers 236 
Index 238 




Preface 



The microprocessor has been with us for some fifteen years now, growing from an awkward 
4-bit child to a robust 32-bit adult. Soon, 64- and then 128-bit wizards will appear to 
crunch numbers, spreadsheets, and, CAD CAM. The engineering community became 
aware of, and enamored with, the 8-bit microprocessors of the middle to late I970's. The 
bit size, cost, and power of these early CPUs were particularly useful for specific tasks 
involving data gathering, machine control, human interaction, and many other applica- 
tions that granted a limited intelligence to machines and appliances. 

The personal computer that was spawned by the 8-bit units predictably became faster 
by increasing data word size and more complex by the addition of operating system hard- 
ware. This process evolved complex CPUs that are poorly suited to dedicated applications 
and more applicable to the generic realm of the computer scientist and system program- 
mer. Engineering applications, however, did not change; these applications continue to 
be best served by 8-bit CPUs with limited memory size and I/O power. Cost per unit 
also continues to dominate processing considerations. Using an expensive 32-bit micro- 
processor to perform functions that can be as efficiently served by an inexpensive 8-bit 
microcontroller will doom the 32-bit product to failure in any competitive marketplace. 

Many designers continue to use the older families of 8-bit microprocessors. The 
8085, 6502, 6800, and Z80 are familiar friends to those of us who had our first successes 
with these radical new computers. We know their faults and idiosyncrasies; we have, quite 
literally, tons of application software written for them. We are reluctant to abandon this 
investment in time and money. 

New technology makes possible, however, a better type of small computer — one with 
not only the CPU on the chip, but RAM, ROM, Timers, UARTS, Ports, and other com- 
mon peripheral I/O functions also. The microprocessor has become the microcontroller. 

Some manufacturers, hoping to capitalize on our software investment, have brought 
out families of microcontrollers that are software compatible with the older micro- 
processors. Others, wishing to optimize the instruction set and architecture to improve 
speed and reduce code size, produced totally new designs that had little in common with 
their earlier microprocessors. Both of these trends continue. 



This book has been written for a diverse audience. It is meant for use primarily by 
those who work in the area of the electronic design and assembly language programming 
of small, dedicated computers. 

An extensive knowledge of electronics is not required to program the microcontroller. 
Many practitioners in disciplines not normally associated with computer electronics- 
transportation. HVAC, mechanisms, medicine, and manufacturing processes of all types — 
can benefit from a knowledge of how these "smart chips" work and how they can be used 
to improve their particular product. 

Persons quite skilled in the application of classical microprocessors, as well as novice 
users who have a basic understanding of computer operation but little actual experience, 
should all find this book useful. The seasoned professional can read Chapter 2 with some 
care, glance at the mnemonics in Chapters 3 through 6, and inspect the applications in 
Chapters 7, 8, and 9. The student may wish to quickly read Chapter 2, study the mnemonics 
and program examples carefully in Chapters 3 through 6, and then exercise the example 
programs in Chapters 7, 8, and 9 to see how it all works. 

The text is suitable for a one- or two-semester course in microcontrollers. A two 
semester course sequence could involve the study of Chapters 1 to 6 in the first semester 
and Chapters 7.8, and 9 in the second semester in conjunction with several involved stu- 
dent programs. A one-semester course might stop with Chapter 7 and use many short 
student assignments drawn from the problems at the end of each chapter. The only pre- 
requisite would be introductory topics concerning the basic organization and operation 
of any digital computer and a working knowledge of using a PC compatible personal 
computer. 

No matter what the interest level, I hope all groups will enjoy using the software that 
has been included on a floppy disk as part of the text. It is my belief that one should not 
have to buy unique hardware evaluation boards, or other hardware-specific items, in order 
to "try out" a new microcontroller. I also believe that it is important to get to the job of 
writing code as easily and as quickly as possible. The time spent learning to use the hard- 
ware board, board monitor, board communication software, and other boring overhead is 
time taken from learning to write code for the microcontroller. 

The programs included on the disk, an 8051 assembler named A5I , and a simulator, 
named S5I . were both written by David Akey of PseudoCorp. Newport News, Virginia. 
PseudoCorp has provided us all with a software development environment that is not only 
easy to use but one that we can uniquely configure for our own special purposes. Details 
on the assembler and simulator are provided in the proper appendixes; use them as early as 
possible in your studies. Many points that are awkward to explain verbally become clear 
when you see them work in the simulator windows! Further information on products 
developed by PseudoCorp follows this Preface. 

I have purposefully not included a great deal of hardware-specific information with 
the text. If your studies include building working systems that interface digital logic to the 
microcontroller, you will become very aware of the need for precise understanding of 
the electrical loading and timing requirements of an operating microcontroller. These 
details are best discussed in the manufacturer's data book(s) for the microcontroller and 
any associated memories and interface logic. Timing and loading considerations are not 
trivial; an experienced designer is required to configure a system that will work reliably. 
Hopefully, many readers will be from outside the area of electronic design and are mainly 
concerned with the essentials of programming and interfacing a microcontroller. For these 
users, I would recommend the purchase of complete boards that have the electrical design 
completed and clear directions as to how to interface common I/O circuits. 



Many people have played a part in writing this book. Special thanks go to all of the 
following people: 

The reviewers of the early, really rough, drafts of the text: 

Richard Barnett, Purdue University 

Richard Castellucis, Southern College of Technology 

Jerry Cockrell, Indiana State University 

James Grover, University of Akron 

Chris Conant, Broome Community College-New York 

Alan Cocchetto, Alfred State College- New York 

for their thoughtful criticisms and words of encouragement. 

Cecil A. Moore, Staff Applications Engineer for Intel Corporation in Chandler, 
Arizona, whose meticulous comments have greatly improved the technical accuracy 
and readability of the text. 

Tom Tucker of West Publishing for his willingness to experiment. 

Anne, my wife, for many years of patience and understanding. 

My students, past and present, who have taught me much more than I have taught 
them. 

Finally, let me thank you, the reader. I would be very grateful if any errors of omission or 
commission are gently pointed out to me by letter or telephone. Thank you for your help. 

Kenneth J. Ayala 

Western Carolina University 

Cullowhee, North Carolina 




Microprocessors 
and Microcontrollers 



Chapter Outline 

Introduction 

Microprocessors and Microcontrollers 

The Z80 and the 8051 

A Microcontroller Survey 



Development Systems 
for Microcontrollers 

Summary 



Introduction 



The past two decades have seen the introduction of a technology that has radically changed 
the way in which we analyze and control the world around us. Born of parallel develop- 
ments in computer architecture and integrated circuit fabrication, the microprocessor, or 
"computer on a chip," first became a commercial reality in 1971 with the introduction of 
the 4-bit 4004 by a small, unknown company by the name of Intel Corporation. Other, 
more well-established, semiconductor firms soon followed Intel's pioneering technology 
so that by the late 1970s one could choose from a half dozen or so microprocessor types. 

The 1970s also saw the growth of the number of personal computer users from a 
handful of hobbyists and "hackers" to millions of business, industrial, governmental, 
defense, educational, and private users now enjoying the advantages of inexpensive 
computing. 

A by-product of microprocessor development was the microcontroller. The same fab- 
rication techniques and programming concepts that make possible the general-purpose 
microprocessor also yielded the microcontroller. 

Microcontrollers are not as well known to the general public, or even the technical 
community, as are the more glamorous microprocessors. The public is, however, very 
well aware that "something" is responsible for all of the smart VCRs, clock radios, wash- 



CHAPTER ONE 



ers and dryers, video games, telephones, microwaves, TVs, automobiles, toys, vending 
machines, copiers, elevators, irons, and a myriad of other articles that have suddenly be- 
come intelligent and "programmable." Companies are also aware that being competitive 
in this age of the microchip requires their products, or the machinery they use to make 
those products, to have some "smarts." 

The purpose of this chapter is to introduce the concept of a microcontroller and sur- 
vey a representative group. The remainder of the book will study one of the most popular 
types, the 8051, in detail. 

Microprocessors and Microcontrollers 

Microprocessors and microcontrollers stem from the same basic idea, are made by the 
same people, and are sold to the same types of system designers and programmers. What 
is the difference between the two? 

Microprocessors 

A microprocessor, as the term has come to be known, is a general -purpose digital com- 
puter central processing unit (CPU). Although popularly known as a "computer on a 
chip," the microprocessor is in no sense a complete digital computer. 

Figure 1 . 1 shows a block diagram of a microprocessor CPU, which contains an arith- 
metic and logic unit (ALU), a program counter (PC), a Stack pointer (SP), some working 
registers, a clock timing circuit, and interrupt circuits. 

To make a complete microcomputer, one must add memory, usually read-only pro- 
gram memory (ROM) and random-access data memory (RAM), memory decoders, an 
oscillator, and a number of input/output (I/O) devices, such as parallel and serial data 
ports. Additionally, special-purpose devices, such as interrupt handlers, or counters, may 



FIGURE 1.1 A Block Diagram of a Microprocessor 



















Arithmetic 

and 
Logic Unit 












Accumulator 




Working Register(s) 


















Program Counter 




Stack Pointer 
























Clock 
Circuit 




Interrupt 
Circuits 























MICROPROCESSORS AND MICROCONTROLLERS 3 

be added to relieve the CPU from time-consuming counting or timing chores. Equipping 
the microcomputer with a mass storage device, commonly a floppy disk drive, and I/O 
peripherals, such as a keyboard and a CRT display, yields a small computer that can be 
applied to a range of general-purpose software applications. 

The key term in describing the design of the microprocessor is "general-purpose." 
The hardware design of a microprocessor CPU is arranged so that a small, or very large, 
system can be configured around the CPU as the application demands. The internal CPU 
architecture, as well as the resultant machine level code that operates that architecture, is 
comprehensive but as flexible as possible. 

The prime use of a microprocessor is to fetch data, perform extensive calculations on 
that data, and store those calculations in a mass storage device or display the results for 
human use. The programs used by the microprocessor are stored in the mass storage de- 
vice and loaded into RAM as the user directs. A few microprocessor programs are stored 
in ROM. The ROM-based programs are primarily small fixed programs that operate pe- 
ripherals and other fixed devices that are connected to the system. The design of the mi- 
croprocessor is driven by the desire to make it as expandable as possible, in the expecta- 
tion of commercial success in the marketplace. 

Microcontrollers 

Figure 1 .2 shows the block diagram of a typical microcontroller, which is a true computer 
on a chip. The design incorporates all of the features found in a microprocessor CPU: 
ALU, PC, SP, and registers. It also has added the other features needed to make a com- 
plete computer: ROM, RAM, parallel I/O, serial I/O, counters, and a clock circuit. 

Like the microprocessor, a microcontroller is a general-purpose device, but one 
which is meant to fetch data, perform limited calculations on that data, and control its 



FIGURE 1.2 A Block Diagram of a Microcontroller 



















ALU 




Timer/Counter 




I/O 
Port 
















Accumulator 




Internal 
ROM 










Register(s) 




I/O 
Port 












Internal 
RAM 












Interrupt 
Circuits 












Clock 
Circuit 












Stack Pointer 
























Program Counter 















CHAPTER ONE 



environment based on those calculations. The prime use of a microcontroller is to control 
the operation of a machine using a fixed program that is stored in ROM and that does not 
change over the lifetime of the system. 

The design approach of the microcontroller mirrors that of the microprocessor: make 
a single design that can be used in as many applications as possible in order to sell, hope- 
fully, as many as possible. The microprocessor design accomplishes this goal by having a 
very flexible and extensive repertoire of multi-byte instructions. These instructions work 
in a hardware configuration that enables large amounts of memory and I/O to be con- 
nected to address and data bus pins on the integrated circuit package. Much of the activity 
in the microprocessor has to do with moving code and data words to and from external 
memory to the CPU. The architecture features working registers that can be programmed 
to take part in the memory access process, and the instruction set is aimed at expediting 
this activity in order to improve throughput. The pins that connect the microprocessor to 
external memory are unique, each having a single function. Data is handled in byte, or 
larger, sizes. 

The microcontroller design uses a much more limited set of single- and double-byte 
instructions that are used to move code and data from internal memory to the ALU. Many 
instructions are coupled with pins on the integrated circuit package; the pins are "pro- 
grammable" — that is, capable of having several different functions depending upon the 
wishes of the programmer. 

The microcontroller is concerned with getting data from and to its own pins; the ar- 
chitecture and instruction set are optimized to handle data in bit and byte size. 

Comparing Microprocessors and Microcontrollers 

The contrast between a microcontroller and a microprocessor is best exemplified by 
the fact that most microprocessors have many operational codes (opcodes) for moving 
data from external memory to the CPU; microcontrollers may have one, or two. Micro- 
processors may have one or two types of bit-handling instructions; microcontrollers will 
have many. 

To summarize, the microprocessor is concerned with rapid movement of code and 
data from external addresses to the chip; the microcontroller is concerned with rapid 
movement of bits within the chip. The microcontroller can function as a computer with the 
addition of no external digital parts; the microprocessor must have many additional parts 
to be operational. 



The Z80 and the 8051 



To see the differences in concept between a microprocessor and a microcontroller, in the 
following table we will examine the pin configurations, architecture, and instruction sets 
for a very popular 8-bit microprocessor, the Zilog Z80, and an equally ubiquitous micro- 
controller, the 8-bit Intel 8051: 

Z80 8051 

Pin Configurations 

Total pins 40 40 

Address pins 16 (fixed) 16 

Data pins 8 (fixed) 8 

Interrupt pins 2 (fixed) 2 

I/O pins 32 

Continued 



MICROPROCESSORS AND MICROCONTROLLERS 



Z80 8051 

Architecture 

8-bit registers 20 34 

16-bit registers 4 2 

Stack size 64K 128 

Internal ROM 4K bytes 

Internal RAM 128 bytes 

External memory 64K 128K bytes 

Flags 6 4 

Timers 2 

Parallel port 4 

Serial port 1 

Instruction Sets 
(types/variations) 

External moves 4/14 2/6 

Block moves 2/4 

Bit manipulate 4/4 12/12 

Jump on bit 3/3 

Stack 3/15 2/2 

Single byte 203 49 

Multi-byte 490 62 

Note that the point here is not to show that one design is "better" than the other; the 
two designs are intended to be used for different purposes and in different ways. For ex- 
ample, the Z80 has a very rich instruction set. The penalty that is paid for this abundance 
is the number of multi-byte instructions needed, some 71 percent of the total number. 
Each byte of a multi-byte instruction must be fetched from program memory, and each 
fetch takes time; this results in longer program byte counts and slower execution time 
versus single-byte instructions. The 8051 has a 62 percent multi-byte instruction content; 
the 8051 program is more compact and will run faster to accomplish similar tasks. 

The disadvantage of using a "lean" instruction set as in the 8051 is increased pro- 
grammer effort (expense) to write code; this disadvantage can be overcome when writing 
large programs by the use of high-level languages such as BASIC and C, both of which 
are popular with 8051 system developers. The price paid for reducing programmer time 
(there is always a price) is the size of the program generated. 



A Microcontroller Survey 



Markets for microcontrollers can run into millions of units per application. At these vol- 
umes the microcontroller is a commodity item and must be optimized so that cost is at a 
minimum. Semiconductor manufacturers have produced a mind-numbing array of designs 
that would seem to meet almost any need. Some of the chips listed in this section are no 
longer in regular production, most are current, and a few are best termed "smokeware": 
the dreams of an aggressive marketing department. 

Four-Bit Microcontrollers 

In a commodity chip, expense is represented more by the volume of the package and the 
number of pins it has than the amount of silicon inside. To minimize pin count and pack- 
age size, it is necessary that the basic data word-bit count be held to a minimum, while 
still enabling useful intelligence to be implemented. 



CHAPTER OWE 



Although 4 hits, in this era of 64-bit "tnaximicros," may seem somewhat ludicrous, 
one must recall that the original 4004 was a 4-bit device, and all else followed. Indeed, in 
terms of production numbers, the 4-bit microcontroller is today the most popular micro 
made. The following table lists representative models from major manufacturers* data 
books. Many of these designs have been licensed to other vendors. 









RAM 


ROM 




Manufacturer : Model 


Pins: I/O 


Counters 


(bytes) 


(bytes) 


Other Features 


Hitachi :HMCS40 


28:10 


— 


32 


512 


10-bit ROM 


National :COP420 


28:23 


1 


64 


IK 


Serial bit I/O 


OKI:MSM6411 


16:11 


— 


32 


IK 




TI:TMS 1000 


28 : 23 


— 


64 


IK 


LED display 


Toshiba :TLCS47 


42:35 


2 


128 


2K 


Serial bit I/O 



These 4-bit microcontrollers are generally intended for use in large volumes as true 
1 -chip computers; expanding externa! memory, while possible, would negate the cost ad- 
vantage desired. Typical applications consist of appliances and toys; worldwide volumes 
run into the tens of millions. 

Eight-Bit Microcontrollers 

Eight-bit microcontrollers represent a transition zone between the dedicated, high volume, 
4-bit microcontrollers, and the high performance, 16- and 32-bit units that will conclude 
this chapter. 

Eight bits has proven to be a very useful word size for small computing tasks. Ca- 
pable of 256 decimal values, or quarter-percent resolution, the 1 -byte word is adequate for 
many control and monitoring applications. Serial ASCII data is also stored in byte sizes, 
making 8 bits the natural choice for data communications. Most integrated circuit memo- 
ries and many logic functions are arranged in an 8-bit configuration that interfaces easily 
to data buses of 8 bits. 

Application volumes for 8-bit microcontrollers may be as high as the 4-bit models, or 
they may be very low. Application sophistication can also range from simple appliance 
control to high-speed machine control and data collection. For these reasons, the micro- 
controller vendors have established extensive "families" of similar models. All feature 
a common language, but differ in the amount of internal ROM, RAM. and other cost- 
sensitive features. Often the memory can be expanded to include off-chip ROM and 
RAM; in some cases, the microcontroller has no on-board ROM at all, or the ROM is an 
Electrically Reprogrammable Read Only Memory (EPROM). 

The purpose of this diversity is to offer the designer a menu of similar devices that can 
solve almost any problem. The ROMless or EPROM versions can be used by the designer 
to prototype the application, and then the designer can order the ROM version in large 
quantities from the factory. Many times the ROM version is never used. The designer 
makes the ROMless or EPROM design sufficiently general so that one configuration may 
be used many times, or because production volumes never justify the cost of a factory 
ROM implementation. As a further enticement for the buyer, some families have members 
with fewer external pins to shrink the package and the cost; others have special features 
such as analog-to-digital (A/D) and digital-to-analog (D/A) converters on the chip. 

The 8-bit arena is crowded with capable and cleverly designed contenders; this is the 
growth segment of the market and the manufacturers are responding vigorously to the 
marketplace. The following table lists the generic family name for each chip, but keep 



MICROPROCESSORS AND MICROCONTROLLERS 



in mind that ROMless, EPROM, and reduced pin-count members of the family are also 
available. Each entry in the table has many variations; the total number of configurations 
available exceeds a total of eighty types for the eleven model numbers listed. 



Manufacturer : Model Pins : I/O 

Intel: 8048 40:27 

Intel: 8051 40:32 

National :COP820 28:24 

Motorola: 6805 28:20 

Motorola :68HC 11 52:40 



Rockwell: 6500/1 40:32 

Signetics:87C552 68:48 

TI:TMS7500 40:32 

TI:TMS370C050 68:55 



Zilog:Z8 40:32 

Zilog:Z8820 44:40 



RAM ROM 

Counters (bytes) (bytes) 

64 IK 



1 



128 4K 



64 
64 
256 



IK 
IK 

8K 



64 2K 

256 8K 

128 2K 

256 4K 



128 2K 

272 8K 



Other Features 

External memory 

to8K 
External memory to 

128K; serial port 
Serial bit I/O 

Serial ports; A/D; 
watch dog timer 
(WDT) 

Serial port; A/D; WDT 
External memory 

to64K 
External memory to 

112K; A/D; serial 

ports; WDT 
External memory to 

124K; serial port 
External memory to 

128K; serial port 



£>— CAUTION 



Not all of the pins can be used for general-purpose I/O and addressing external memory at the 
same time. The sales literature should be read with some care to see how many of the pins have 
more than one function. Inspection of the table shows that the designers made tradeoffs: ex- 
ternal memory addressing for extra on-chip functions. Generally, the ability to expand memory 
off of the chip implies that a ROMless family member is available for use in limited production 
numbers where the expense of factory programming can be avoided. Lack of this feature 
implies that the chip is meant for high production volumes where the expense of factory- 
programmed parts can be amortized over a large number of devices. 

Sixteen-Bit Microcontrollers 

Eight-bit microcontrollers can be used in a variety of applications that involve limited cal- 
culations and relatively simple control strategies. As the requirement for faster response 
and more sophisticated calculations grows, the 8-bit designs begin to hit a limit inherent 
with byte-wide data words. One solution is to increase clock speeds; another is to increase 
the size of the data word. Sixteen-bit microcontrollers have evolved to solve high-speed 
control problems of the type that might typically be confronted in the control of ser- 
vomechanisms, such as robot arms, or for digital signal processing (DSP) applications. 
The designs become much more focused on these types of real-time problems; some 
generality is lost, but the vendors still try to hit as many marketing targets as they can. The 
following table lists only three contenders. Intel has recently begun vigorously marketing 



iln* XO'U. |;unilv OMu-r vendors ;irc expected lo appear as this market segment grows in 

tmptMUUHC. 

RAM ROM 

Manufacturer: Model Pins: I/O Counters (bytes) (bytes) Other Features 

Hitachi : H8/532 84:65 5 IK 32K External memory to 

I megabyte; serial 
port; A/D; pulse 
width modulation 

Intel: 8096 68:40 2 232 8K External memory to 

64K; serial port; 
A/D; WDT; pulse 
width modulation 

National :HPCI6164 68:52 4 512 16K External memory to 

64K; serial port; 
A/D; WDT; pulse 
width modulation 

The pulse width modulation (PWM) output is useful for controlling motor speed; it 
can be done using software in the 8-bit units with the usual loss of time for other tasks. 

The 16- (and 32-) bit controllers have also been designed to take advantage of high- 
level programming languages in the expectation that very little assembly language pro- 
gramming will be done when employing these controllers in sophisticated applications. 



Thirty-Two Bit Microcontrollers 

Crossing the boundary from 16 to 32 bits involves more than merely doubling the word 
size of the computer. Software boundaries that separate dedicated programs from super- 
visory programs are also breached. Thirty two bit designs target robotics, highly intelli- 
gent instrumentation, avionics, image processing, telecommunications, automobiles, and 
other environments that feature application programs running under an operating system. 
The line between microcomputers and microcontrollers becomes very fine here. 

The design emphasis now switches from on-chip features, such as RAM, ROM, 
timers, and serial ports, to high-speed computation features. The following table provides 
a general list of the capability of the Intel 80960: 

HARDWARE FEATURES SOFTWARE FEATURES 

132-pin ceramic package Efficient procedure calls 

20 megahertz clock Fault-handling capability 

32-bit bus Trace events 

Floating-point unit Global registers 

512-byte instruction cache Efficient interrupt vectors 

Interrupt control Versatile addressing 

All of the functions needed for I/O, data communications, and timing and counting are 
done by adding other specialized chips. 

This manufacturer has dubbed all of its microcontrollers "embedded controllers," 
a term that seems to describe the function of the 32-bit 80960 very well. 



MICROPROCESSORS AND MICROCONTROLLERS 



Development Systems 
for Microcontrollers 



Summary 



What is needed to be able to apply a microcontroller to your product? That is, what pack- 
age of hardware and software will allow the microcontroller to be programmed and con- 
nected to your application? A package commonly called a "development system" is 
required. 

First, trained personnel must be available either on your technical staff or as consul- 
tants. One person who is versed in digital hardware and computer software is the mini- 
mum number. 

Second, a device capable of programming EPROMs must be available to test the 
prototype device. Many of the microcontroller families discussed have a ROMIess ver- 
sion, an EPROM version, or an Electrically Erasable and Programmable Read Only Mem- 
ory (EEPROM) version that lets the designer debug the hardware and software prototype 
before committing to full-scale production. Many inexpensive EPROM programmers are 
sold that plug into a slot of most popular personal computers. More expensive, and more 
versatile, dedicated programmers are also available. An alternative to EPROMs are vendor- 
supplied prototype cards that allow code to be down loaded from a host computer, and the 
program run from RAM for debugging purposes. An EPROM will eventually have to be 
programmed for the production version of the microcontroller. 

Finally, software is needed, along with a personal computer to host it. The minimum 
software package consists of a machine language assembler, which can be supplied by the 
microcontroller vendor or bought from independent developers. More expensive software 
mainly consisting of high-level language compilers and debuggers is also available. 

A minimum development system, then, consists of a personal computer, a plug-in 
EPROM programmer, and a public-brand assembler. A more extensive system would con- 
sist of vendor-supplied dedicated computer systems with attendant high-level software 
packages and in-circuit emulators for hardware and software debugging. In 1990 dollars, 
the cost for the range of solutions outlined here is from $1000 to $10,000. 



The fundamental differences between microprocessors and microcontrollers are: 

n Microprocessors are intended to be general-purpose digital computers while micro- 
controllers are intended to be special -purpose digital controllers. 

n Microprocessors contain a CPU, memory addressing circuits, and interrupt han- 
dling circuits. Microcontrollers have these features as well as timers, parallel and 
serial I/O, and internal RAM and ROM. 

° Microcontroller models vary in data size from 4 to 32 bits. Four-bit units are pro- 
duced in huge volumes for very simple applications, and 8-bit units are the most 
versatile. Sixteen- and 32-bit units are used in high-speed control and signal pro- 
cessing applications. 

° Many models feature programmable pins that allow external memory to be added 
with the loss of I/O capability. 



10 CHAPTER ONE 



Questions 

1 . Name four major differences between a microprocessor and a microcontroller. 

2. The 8051 has 40 pins on a Dual Inline Package (DIP) package, yet the comparison with 
the Z80 microprocessor totals 58 pins. Explain this difference. 

3. Name 20 items that have a built-in microcontroller. 

4. Name 10 items that should have a built-in microcontroller. 

5. Name the most unusual application of a microcontroller that you have seen actually 
for sale. 

6. Name the most likely bit size for each of the following products. 

Modem 

Printer 

Toaster 

Automobile engine control 

Robot arm 

Small ASCII data terminal 

Chess player 

House thermostat 

7. Explain why ROMIess versions of microcontrollers exist. 

8. Name two ways to speed up digital data processing. 

9. List three essential items needed to make up a development system for programming 
microcontrollers. 

10. Search the literature and determine whether any manufacturer has announced a 64-bit 
microcontroller. 




The 8051 Architecture 



Chapter Outline 

Introduction 

8051 Microcontroller Hardware 

External Memory 

Counters and Timers 



Serial Data Input/Output 

Interrupts 

Summary 



Introduction 



The first task faced when learning to use a new computer is to become familiar with the 
capability of the machine. The features of the computer are best learned by studying the 
internal hardware design, also called the architecture of the device, to determine the type, 
number, and size of the registers and other circuitry. 

The hardware is manipulated by an accompanying set of program instructions, or 
software, which is usually studied next. Once familiar with the hardware and software, the 
system designer can then apply the microcontroller to the problems at hand. 

A natural question during this process is "What do I do with all this stuff?" Similar to 
attempting to write a poem in a foreign language before you have a vocabulary and rules 
of grammar, writing meaningful programs is not possible until you have become ac- 
quainted with both the hardware and the software of a computer. 

This chapter provides a broad overview of the architecture of the 805 1 . In subsequent 
chapters, we will cover in greater detail the interaction between the hardware and the 
software. 



8051 Microcontroller Hardware 



11 



The 805 1 microcontroller actually includes a whole family of microcontrollers that have 
numbers ranging from 8031 to 8751 and are available in N-Channel Metal Oxide Silicon 
(NMOS) and Complementary Metal Oxide Silicon (CMOS) construction in a variety of 



12 



CHAPTER TWO 



FIGURE 2.1a 8051 Block Diagram 































u 




O 

r 

o 






Arithmetic 

and 
Logic Unit 








Special- 
Function 
Registers 
RAM 






— I/O 








— A0-A7 
















— D0-D7 












— 








































A 




B 


8-Bit Data and 
Address Bus 




-C 
—1 




o 

Q_ 


— I/O 




1 




V r 




















ROM 
















PC 




DPTR 
DPH 
DPL 












o 




CM 

O 

Q- 






















I/O 
_ A8-A15 






























































to 




o 

0_ 


I/O 


EA — 


System 

Timing 

System 

Interrupts 
Timers 

Data Buffers 

Memory Control 




Byte/Bit 
Addresses 




Special- 
Function 
Registers 




— Interrupt 

— Counter 
™~ Serial Data 


ALE — 
PSEN — 






Register 
Bank 3 


IE 




— RD-WR 


XTAL1 — 












XTAL2 — 


IP 




RESET — 


PCON 






Register 
Bank 2 




Vcc — 


SBUF 




GND — 


SCON 






TCON 






1 




Register 
Bank 1 




1 
1 


TMOD 




TLO 




THO 




Register 
BankO 




1 


TL1 




\ 


THl 










1 
1 








Internal 


RAM 


Structure 



















package types. An enhanced version of the 805 1 , the 8052, also exists with its own family 
of variations and even includes one member that can be programmed in BASIC. This gal- 
axy of parts, the result of desires by the manufacturers to leave no market niche unfilled, 
would require many chapters to cover. In this chapter, we will study a "generic" 8051, 
housed in a 40-pin DIP, and direct the investigation of a particular type to the data books. 
The block diagram of the 8051 in Figure 2.1a shows all of the features unique to micro- 
controllers: 

Internal ROM and RAM 

I/O ports with programmable pins 

Timers and counters 

Serial data communication 



THE 8051 ARCHITECTURE 



13 



FIGURE 2.1b 8051 Programming Model 



Register 

Bank 





8 1 EO* 



A 
Register 



8 | FO' 



B 
Register 



Math Registers 



30 


General- 
Purpose 
Area 


2F 
20 


Bit 

Address 

Area 


IF 
18 


Register 

Bank 

3 


17 
10 


Register 

Bank 

2 


OF 
08 


Register 

Bank 

1 


07 


R7 


06 


R6 


05 


R5 


04 


R4 


03 


R3 


02 


R2 


01 


Rl 


00 


RO 



Byte 
Addresses 



Internal 
RAM 



7F 



00 



8 | B8' 



IP 
Register 



8 | A8' 



(E 
Register 



8 | 89 



TMOD 
Register 



8 1 88' 



TCON 
Register 



Interrupt Registers 



Timer Control Registers 



8C 



THO 
Counter 



8A 



TLO 
Counter 



8D 



TH1 
Counter 



86 



TL1 
Counter 



Timer/Counter Registers 



98' 



SCON 
Register 



8 | 99 



SBUF 
Register 



87 



PCON 
Register 



DO' 



PSW 
Register 



Serial Data Registers 



Flags 



8 1 81 



Stack 
Pointer 



Bit Addresses for this RAM Area Only 



8 | 83 | 8 | 82" 



Data Pointer 
DPH I DPL 



8 | 80' 



PortO 
Latch 



8 | 90' 



Port 1 
Latch 



Number of 
Bits 



Direct Byte Address 
Indicates Bit Addressable 



FFF 



16 | No Address 




Program Counter 












8 | AO' 




8 | BO* 


Port 2 
Latch 


Port 3 

Latch 



000 



Internal 
ROM 



14 CHAPTER TWO 



The figure also shows the usual CPU components: program counter, ALU, working regis- 
ters, and clock circuits.' 

The 805 1 architecture consists of these specific features: 

Eight-bit CPU with registers A (the accumulator) and B 

Sixteen-bit program counter (PC) and data pointer (DPTR) 

Eight-bit program status word (PSW) 

Eight-bit stack pointer (SP) 

Internal ROM or EPROM (875 1 ) of (803 1 ) to 4K (805 1 ) 

Internal RAM of 128 bytes: 

Four register banks, each containing eight registers 

Sixteen bytes, which may be addressed at the bit level 

Eighty bytes of general-purpose data memory 
Thirty-two input/output pins arranged as four 8-bit ports: P0-P3 
Two 16-bit timer/counters: TO and Tl 
Full duplex serial data receiver/transmitter: SBUF 
Control registers: TCON, TMOD, SCON, PCON, IP, and IE 
Two external and three internal interrupt sources 
Oscillator and clock circuits 

The programming model of the 8051 in Figure 2.1b shows the 8051 as a collection of 
8- and 16-bit registers and 8-bit memory locations. These registers and memory locations 
can be made to operate using the software instructions that are incorporated as part of the 
design. The program instructions have to do with the control of the registers and digital 
data paths that are physically contained inside the 8051 , as well as memory locations that 
are physically located outside the 8051 . 

The model is complicated by the number of special-purpose registers that must be 
present to make a microcomputer a microcontroller. A cursory inspection of the model is 
recommended for the first-time viewer; return to the model as needed while progressing 
through the "remainder of the text. 

Most of the registers have a specific function; those that do occupy an individual 
block with a symbolic name, such as A or THO or PC. Others, which are generally indis- 
tinguishable from each other, are grouped in a larger block, such as internal ROM or 
RAM memory. 

Each register, with the exception of the program counter, has an internal 1-byte ad- 
dress assigned to it. Some registers (marked with an asterisk * in Figure 2.1b) are both 
byte and bit addressable. That is, the entire byte of data at such register addresses may be 
read or altered, or individual bits may be read or altered. Software instructions are gener- 
ally able to specify a register by its address, its symbolic name, or both. 

A pinout of the 8051 packaged in a 40-pin DIP is shown in Figure 2.2 with the full 
and abbreviated names of the signals for each pin. It is important to note that many of the 



1 Knowledge of the details of circuit operation that cannot be affected by any instruction or external data, while 
intellectually stimulating, tends to confuse the student new to the 805 1 . For this reason, this text will concentrate 
on the essential features of the 805 1 ; the more advanced student may wish to refer to manufacturers' data books 
for additional information. 



THE 8051 ARCHITECTURE 



15 



FIGURE 2.2 8051 DIP Pin Assignments 



Port 1 Bit 
Port 1 Bit 1 
Port 1 Bit 2 
Port 1 Bit 3 
Portl Bit 4 
Port 1 Bit 5 

Port 1 Bit 6 
Port 1 Bit 7 

Reset Input 

Port 3 Bit 
{Receive Data) 

Port 3 Bit 1 
(XM IT Data) 

Port 3 Bit 2 
(Interrupt 0) 

Port 3 Bit 3 
(Interrupt 1) 

Port 3 Bit 4 
(Timer Input) 

Port 3 Bit 5 
(Timer 1 Input) 

Port 3 Bit 6 
(Write Strobe) 

Port 3 Bit 7 
(Read Strobe) 

Crystal Input 2 

Crystal Input 1 

Ground 



1 


P1.0 ^~ 


-^ Vcc 40 


2 


Pl.l 


(ADO)PO.O 39 


3 


PI. 2 


(ADl)PO.l 38 


4 


P1.3 


(AD2)P0.2 37 


5 


PI. 4 


(AD3)P0.3 36 


6 


PI. 5 


(AD4)P0.4 35 


7 


PI. 6 


(AD5)P0.5 34 


8 


PI. 7 


(AD6)P0.6 33 


9 


RST 


(AD7)P0.7 32 


10 


P3.0{RXD) 


(VppVEA 31 


11 


P3.KTXD) 


(PROG)ALE 30 


12 


P3.2(INTO) 


PSEN 29 


13 


P3.30NT1) 


(A15)P2.7 28 


14 


P3.4(T0) 


(A14)P2.6 27 


15 


P3.5CT1) 


(A13)P2.5 26 


16 


P3.6(WR) 


(A12)P2.4 25 


17 


P3.7(RD) 


(A1DP2.3 24 


18 


XTAL2 


(A10JP2.2 23 


19 


XTAL1 


(A9JP2.1 22 


20 


Vss 


(A81P2.0 21 



+ 5V 

Port Bit 
(Address/Data 0) 

Port Bit 1 
(Address/Data 1) 

Port Bit 2 
(Address/Data 2) 

PortO Bit 3 
(Address/Data 3) 

PortO Bit 4 
(Address/Data 4) 

Port Bit 5 
(Address/Data 5) 

Port Bit 6 
(Address/Data 6) 

PortO Bit 7 
{Address/Data 7) 

External Enable 

(EPROM Programming Voltage) 

Address Latch Enable 
(EPROM Program Pulse) 

Program Store Enable 

Port 2 Bit 7 
(Address 15) 

Port 2 Bit 6 
(Address 14) 

Port 2 Bit 5 
(Address 13) 

Port 2 Bit 4 
(Address 12) 

Port 2 Bit 3 
(Address 11) 

Port 2 Bit 2 
(Address 10) 

Port 2 Bit 1 
(Address 9) 

Port 2 Bit 
(Address 8) 



Note: Alternate functions are shown below the port name (in parentheses). Pin num- 
bers and pin names are shown inside the DIP package. 



16 



CHAPTER TWO 



pins are used for more than one function (the alternate functions are shown in parentheses 
in Figure 2.2). Not all of the possible 8051 features may be used at the same time. 

Programming instructions or physical pin connections determine the use of any multi- 
function pins. For example, port 3 bit (abbreviated P3.0) may be used as a general- 
purpose I/O pin, or as an input (RXD) to SBUF, the serial data receiver register. The 
system designer decides which of these two functions is to be used and designs the hard- 
ware and software affecting that pin accordingly. 

The 8051 Oscillator and Clock 

The heart of the 805 1 is the circuitry that generates the clock pulses by which all internal 
operations are synchronized. Pins XTAL1 and XTAL2 are provided for connecting a reso- 
nant network to form an oscillator. Typically, a quartz crystal and capacitors are em- 
ployed, as shown in Figure 2.3. The crystal frequency is the basic internal clock fre- 
quency of the microcontroller. The manufacturers make available 8051 designs that can 
run at specified maximum and minimum frequencies, typically 1 megahertz to 16 mega- 
hertz. Minimum frequencies imply that some interna] memories are dynamic and must 
always operate above a minimum frequency, or data will be lost. 

Communication needs often dictate the frequency of the oscillator due to the require- 
ment that internal counters must divide the basic clock rate to yield standard communica- 
tion bit per second (baud) rates. If the basic clock frequency is not divisible without a 
remainder, then the resulting communication frequency is not standard. 



FIGURE 2.3 Oscillator Circuit and Timing 

ci 

■il lh 



T 



Crystal ^^ 

or I I 

Ceramic Resonator 



■lr 



tt 



I 



C2 



18XTAL2 



8051 DIP 



19XTAL1 



Crystal or Ceramic Resonator Oscillator Circuit 



Oscillator 
Frequency 

f 



P2 PI P2 PI P2 PI P2 PI P2 PI P2 PI P2 

TrumrLTLTijuijijijinj 



State 1 



State 2 



State 3 



State 4 



State 5 



State 6 



One Machine Cycle 



Address Latch 
Enable (ALE) 



8051 Timing 



THE 8051 ARCHITECTURE 17 

Ceramic resonators may be used as a low-cost alternative to crystal resonators. How- 
ever, decreases in frequency stability and accuracy make the ceramic resonator a poor 
choice if high-speed serial data communication with other systems, or critical timing, is to 
be done. 

The oscillator formed by the crystal, capacitors, and an on-chip inverter generates a 
pulse train at the frequency of the crystal, as shown in Figure 2.3. 

The clock frequency, /, establishes the smallest interval of time within the micro- 
controller, called the pulse, P, time. The smallest interval of time to accomplish any 
simple instruction, or part of a complex instruction, however, is the machine cycle. The 
machine cycle is itself made up of six states. A state is the basic time interval for discrete 
operations of the microcontroller such as fetching an opcode byte, decoding an opcode, 
executing an opcode, or writing a data byte. Two oscillator pulses define each state. 

Program instructions may require one, two, or four machine cycles to be executed, 
depending on the type of instruction. Instructions are fetched and executed by the micro- 
controller automatically, beginning with the instruction located at ROM memory address 
OOOOh at the time the microcontroller is first reset. 

To calculate the time any particular instruction will take to be executed, find the num- 
ber of cycles, C, from the list in Appendix A. The time to execute that instruction is then 
found by multiplying C by 12 and dividing the product by the crystal frequency: 

C x 12d 
Tmst = 



crystal frequency 



For example, if the crystal frequency is 16 megahertz, then the time to execute an ADD 
A, Rl one-cycle instruction is .75 microseconds. A 12 megahertz crystal yields the con- 
venient time of one microsecond per cycle. An 1 1 .0592 megahertz crystal, while seem- 
ingly an odd value, yields a cycle frequency of 921.6 kilohertz, which can be divided 
evenly by the standard communication baud rates of 19200, 9600, 4800, 2400, 1200, and 
300 hertz. 

Program Counter and Data Pointer 

The 8051 contains two 16-bit registers: the program counter (PC) and the data pointer 
(DPTR). Each is used to hold the address of a byte in memory. 

Program instruction bytes are fetched from locations in memory that are addressed by 
the PC. Program ROM may be on the chip at addresses OOOOh to OFFFh, external to the 
chip for addresses that exceed OFFFh, or totally external for all addresses from OOOOh to 
FFFFh. The PC is automatically incremented after every instruction byte is fetched and 
may also be altered by certain instructions. The PC is the only register that does not have 
an internal address. 

The DPTR register is made up of two 8-bit registers, named DPH and DPL, that are 
used to furnish memory addresses for internal and external code access and external data 
access. The DPTR is under the control of program instructions and can be specified by its 
16-bit name, DPTR, or by each individual byte name, DPH and DPL. DPTR does not 
have a single internal address; DPH and DPL are each assigned an address. 

A and B CPU Registers 

The 8051 contains 34 general-purpose, or working, registers. Two of these, registers A 
and B, comprise the mathematical core of the 8051 central processing unit (CPU). The 
other 32 are arranged as part of internal RAM in four banks, B0-B3, of eight registers 
each, named R0 to R7. 



18 



CHAPTER TWO 



The A (accumulator) register is the most versatile of the two CPU registers and is 
used for many operations, including addition, subtraction, integer multiplication and divi- 
sion, and Boolean bit manipulations. The A register is also used for all data transfers be- 
tween the 805 1 and any external memory. The B register is used with the A register for 
multiplication and division operations and has no other function other than as a location 
where data may be stored. 

Flags and the Program Status Word (PSW) 

Flags are I -bit registers provided to store the results of certain program instructions. Other 
instructions can test the condition of the flags and make decisions based upon the flag 
states. In order that the flags may be conveniently addressed, they are grouped inside the 
program status word (PSW) and the power control (PCON) registers. 

The 805 1 has four math flags that respond automatically to the outcomes of math 
operations and three general-purpose user flags that can be set to I or cleared to by the 
programmer as desired. The math flags include carry (C), auxiliary carry (AC), overflow 
(OV), and parity (P). User flags are named F0, GFO, and GF1; they are general-purpose 
flags that may be used by the programmer to record some event in the program. Note that 
all of the flags can be set and cleared by the programmer at will. The math flags, however, 
are also affected by math operations. 

The program status word is shown in Figure 2.4. The PSW contains the math flags, 
user program flag F0, and the register select bits that identify which of the four general- 
purpose register banks is currently in use by the program. The remaining two user flags, 
GFO and GFl , are stored in PCON, which is shown in Figure 2. 1 3. 



FIGURE 2.4 PSW Program Status Word Register 



7 


6 


5 


4 


3 


2 


1 





CY 


AC 


F0 


RSI 


RSO 


OV 


— 


p 



THE PROGRAM STATUS WORD (PSW) SPECIAL FUNCTION REGISTER 

Bit Symbol Function 

Carry flag; used in arithmetic, JUMP, ROTATE, and BOOLEAN instructions 

Auxiliary carry flag; used for BCD arithmetic 

User flag 

Register bank select bit 1 

Register bank select bit 



Select register bank 
Select register bank 1 
Select register bank 2 
Select register bank 3 



7 


CY 


6 


AC 


5 


F0 


4 


RS1 


3 


RSO 



OV 



RS1 


RSO 











1 


1 





1 


1 



Overflow flag; used in arithmetic instructions 

Reserved for future use 

Parity flag; shows parity of register A: 1 = Odd Parity 



Bit addressable as PSW.O to PSW. 7 



THE 8051 ARCHITECTURE 19 

Detailed descriptions of the math flag operations will be discussed in chapters that 
cover the opcodes that affect the flags. The user flags can be set or cleared using data move 
instructions covered in Chapter 3. 

Internal Memory 

A functioning computer must have memory for program code bytes, commonly in ROM, 
and RAM memory for variable data that can be altered as the program runs. The 805 1 has 
internal RAM and ROM memory for these functions. Additional memory can be added 
externally using suitable circuits. 

Unlike microcontrollers with Von Neumann architectures, which can use a single 
memory address for either program code or data, but not for both, the 805 1 has a Harvard 
architecture, which uses the same address, in different memories, for code and data. In- 
ternal circuitry accesses the correct memory based upon the nature of the operation in 
progress. 

Internal RAM 

The 128-byte internal RAM, which is shown generally in Figure 2.1 and in detail in Fig- 
ure 2.5, is organized into three distinct areas: 

1. Thirty-two bytes from address OOh to IFh that make up 32 working registers or- 
ganized as four banks of eight registers each. The four register banks are num- 
bered to 3 and are made up of eight registers named R0 to R7. Each register 
can be addressed by name (when its bank is selected) or by its RAM address. 
Thus R0 of bank 3 is RO (if bank 3 is currently selected) or address 1 8h (whether 
bank 3 is selected or not). Bits RSO and RSI in the PSW determine which bank 
of registers is currently in use at any time when the program is running. Register 
banks not selected can be used as general -purpose RAM. Bank is selected 
upon reset. 

2. A /w'f-addres sable area of 16 bytes occupies RAM byte addresses 20h to 2Fh, 
forming a total of 128 addressable bits. An addressable bit may be specified by 
its bit address of OOh to 7Fh, or 8 bits may form any byte address from 20h to 
2Fh. Thus, for example, bit address 4Fh is also bit 7 of byte address 29h. Ad- 
dressable bits are useful when the program need only remember a binary event 
(switch on, light off, etc.). Internal RAM is in short supply as it is, so why use a 
byte when a bit will do? 

3. A general -purpose RAM area above the bit area, from 30h to 7Fh, addressable 
as bytes. 

The Stack and the Stack Pointer 

The stack refers to an area of internal RAM that is used in conjunction with certain op- 
codes to store and retrieve data quickly. The 8-bit stack pointer (SP) register is used by the 
8051 to hold an internal RAM address that is called the "top of the stack." The address 
held in the SP register is the location in internal RAM where the last byte of data was 
stored by a stack operation. 

When data is to be placed on the stack, the SP increments before storing data on the 
stack so that the stack grows up as data is stored. As data is retrieved from the stack, the 
byte is read from the stack, and then the SP decrements to point to the next available byte 
of stored data. 



20 



CHAPTER TWO 



FIGURE 2.5 Internal RAM Organization 



00 



IF 


R7 


IE 


R6 


ID 


R5 


1C 


R4 


IB 


R3 


1A 


R2 


19 


Rl 


18 


RO 


17 


R7 


16 


R6 


15 


R5 


14 


R4 


13 


R3 


12 


R2 


11 


Rl 


10 


RO 


OF 


R7 


OE 


R6 


OD 


R5 


OC 


R4 


OB 


R3 


OA 


R2 


09 


Rl 


08 


RO 


07 


R7 


06 


R6 


05 


R5 


04 


R4 


03 


R3 


02 


R2 


01 


Rl 


00 


RO 



Working 
Registers 



2F 


7F 


78 


2E 


77 


70 


2D 


6F 


68 


2C 


67 


60 


2B 


5F 


58 


2A 


57 


50 


29 


4F 


48 


28 


47 


40 


27 


3F 


38 


26 


37 


30 


25 


2F 


28 


24 


27 


20 


23 


IF 


18 


22 


17 


10 


21 


OF 


08 


20 


07 


00 



Bit Addressable 



7F 



General Purpose 



Note: Byte addresses are shown to the left; bit addresses registers are shown inside 
a location. 



Operation of the stack and the SP is shown in Figure 2.6. The SP is set to 07h when 
the 8051 is reset and can be changed to any internal RAM address by the programmer. 

The stack is limited in height to the size of the internal RAM. The stack has the poten- 
tial (if the programmer is not careful to limit its growth) to overwrite valuable data in the 
register banks, bit-addressable RAM, and scratch-pad RAM areas. The programmer is 
responsible for making sure the stack does not grow beyond pre-defined bounds! 

The stack is normally placed high in internal RAM, by an appropriate choice of the 
number placed in the SP register, to avoid conflict with the register, bit, and scratch-pad 
internal RAM areas. 



THE 8051 ARCHITECTURE 21 



FIGURE 2.6 Stack Operation 



SP = 0A 



Store Data 



Address OA 



Get Data 



SP = OA 



SP = 09 



Store Data 



Address 09 



Get Data 



SP = 09 



SP = 08 



Store Data 



Address 08 



Get Data 



SP = 08 



SP = 07 



Address 07 



SP = 07 



Storing Data on the Stack 
(Increment then store) 



Internal RAM 
(Get then decrement) 



Getting Data From the Stack 



Special Function Registers 

The 805 1 operations that do not use the internal 1 28-byte RAM addresses from OOh to 7Fh 
are done by a group of specific internal registers, each called a special-function register 
(SFR), which may be addressed much like internal RAM, using addresses from 80h 
toFFh. 

Some SFRs (marked with an asterisk * in Figure 2. lb) are also bit addressable, as is 
the case for the bit area of RAM. This feature allows the programmer to change only what 
needs to be altered, leaving the remaining bits in that SFR unchanged. 

Not all of the addresses from 80h to FFh are used for SFRs, and attempting to use an 
address that is not defined, or "empty," results in unpredictable results. In Figure 2. lb, 
the SFR addresses are shown in the upper right corner of each block. The SFR names and 
equivalent internal RAM addresses are given in the following table: 

INTERNAL RAM 
ADDRESS (HEX) 



NAME 


FUNCTION 


ADI 


A 


Accumulator 


0E0 


B 


Arithmetic 


0F0 


DPH 


Addressing external memory 


83 


DPL 


Addressing external memory 


82 


IE 


Interrupt enable control 


0A8 


IP 


Interrupt priority 


0B8 


P0 


Input/output port latch 


80 


P1 


Input/output port latch 


90 


P2 


Input/output port latch 


A0 


P3 


Input/output port latch 


0B0 


PCON 


Power control 


87 


PSW 


Program status word 


0D0 


SCON 


Serial port control 


98 


SBUF 


Serial port data buffer 


99 



Continued 



22 



CHAPTER TWO 







INTERNAL RAM 


NAME 


FUNCTION 


ADDRESS (HEX) 


SP 


Stack pointer 


81 


TMOD 


Timer/counter mode control 


89 


TCON 


Timer/counter control 


88 


TLO 


Timer low byte 


8A 


THO 


Timer high byte 


8C 


TL1 


Timer 1 low byte 


8B 


TH1 


Timer 1 high byte 


8D 



Continued 



Note that the PC is not part of the SFR and has no internal RAM address. 

SFRs are named in certain opcodes by their functional names, such as A or THO, and 
are referenced by other opcodes by their addresses, such as OEOh or 8Ch. Note that any 
address used in the program must start with a number; thus address EOh for the A SFR 
begins with 0. Failure to use this number convention will result in an assembler error 
when the program is assembled. 

Internal ROM 

The 8051 is organized so that data memory and program code memory can be in two 
entirely different physical memory entities. Each has the same address ranges. 

The structure of the internal RAM has been discussed previously. A corresponding 
block of internal program code, contained in an internal ROM, occupies code address 
space OOOOh to OFFFh. The PC is ordinarily used to address program code bytes from 
addresses OOOOh to FFFFh. Program addresses higher than OFFFh, which exceed the inter- 
nal ROM capacity, will cause the 8051 to automatically fetch code bytes from external 
program memory. Code bytes can also be fetched exclusively from an external memory, 
addresses OOOOh to FFFFh, by connecting the external access pin (EA pin 31 on the DIP) 
to ground. The PC does not care where the code is; the circuit designer decides whether 
the code is found totally in internal ROM, totally in external ROM, or in a combination of 
internal and external ROM. 



Input/Output Pins, Ports, and Circuits 



One major feature of a microcontroller is the versatility built into the input/output (I/O) 
circuits that connect the 8051 to the outside world. As noted in Chapter 1 , microprocessor 
designs must add additional chips to interface with externa! circuitry; this ability is built 
into the microcontroller. 

To be commercially viable, the 8051 had to incorporate as many functions as were 
technically and economically feasible. The main constraint that limits numerous functions 
is the number of pins available to the 805 1 circuit designers. The DIP has 40 pins, and the 
success of the design in the marketplace was determined by the flexibility built into the use 
of these pins. 

For this reason, 24 of the pins may each be used for one of two entirely different 
functions, yielding a total pin configuration of 64. The function a pin performs at any 
given instant depends, first, upon what is physically connected to it and, then, upon what 
software commands are used to "program" the pin. Both of these factors are under the 
complete control of the 8051 programmer and circuit designer. 



THE 8051 ARCHITECTURE 



23 



Given this pin flexibility, the 8051 may be applied simply as a single component with 
I/O only, or it may be expanded to include additional memory, parallel ports, and serial 
data communication by using the alternate pin assignments. The key to programming an 
alternate pin function is the port pin circuitry shown in Figure 2.7. 

Each port has a D-type output latch for each pin. The SFR for each port is made up 
of these eight latches, which can be addressed at the SFR address for that port. For in- 
stance, the eight latches for port are addressed at location 80h; port pin 3 is bit 2 of the 
P0 SFR. The port latches should not be confused with the port pins; the data on the latches 
does not have to be the same as that on the pins. 

The two data paths are shown in Figure 2.7 by the circuits that read the latch or pin 
data using two entirely separate buffers. The top buffer is enabled when latch data is read, 
and the lower buffer, when the pin state is read. The status of each latch may be read from 
a latch buffer, while an input buffer is connected directly to each pin so that the pin status 
may be read independently of the latch state. 

Different opcodes access the latch or pin states as appropriate. Port operations are 
determined by the manner in which the 8051 is connected to external circuitry. 

Programmable port pins have completely different alternate functions. The configura- 
tion of the control circuitry between the output latch and the port pin determines the nature 
of any particular port pin function. An inspection of Figure 2.7 reveals that only port 1 
cannot have alternate functions; ports 0, 2, and 3 can be programmed. 

The ports are not capable of driving loads that require currents in the tens of milli- 
amperes (mA). As previously mentioned, the 8051 has many family members, and many 
are fabricated in varying technologies. An example range of logic-level currents, volt- 
ages, and total device power requirements is given in the following table: 



Parameter 


v oh 


loh 


v ol 


<d 


v i( 


In 


v ih 


l.h 


Pt 


CMOS 


2.4 V 


-60 M A 


.45 V 


1.6 mA 


,9 V 


|10/iA| 


1.9 V 


|10/iA| 


50 mW 


NMOS 


2.4V 


-80 /aA 


.45 V 


1.6 mA 


,8 V 


-800 jaA 


2.0 V 


10 ^A 


800 mW 



These figures tell us that driving more than two LSTTL inputs degrades the noise 
immunity of the ports and that careful attention must be paid to buffering the ports when 
they must drive currents in excess of those listed. Again, one must refer to the manufac- 
turers' data books when designing a "real" application. 



PortO 

Port pins may serve as inputs, outputs, or, when used together, as a bi-directional low- 
order address and data bus for external memory. For example, when a pin is to be used as 
an input, a 1 must be written to the corresponding port latch by the program, thus turn- 
ing both of the output transistors off, which in turn causes the pin to "float" in a high- 
impedance state, and the pin is essentially connected to the input buffer. 

When used as an output, the pin latches that are programmed to a will turn on the 
lower FET, grounding the pin. All latches that are programmed to a 1 still float; thus, 
external pullup resistors will be needed to supply a logic high when using port as an 
output. 

When port is used as an address bus to external memory, internal control signals 
switch the address lines to the gates of the Field Effect Transistories (FETs). A logic 1 on 
an address bit will turn the upper FET on and the lower FET off to provide a logic high at 
the pin. When the address bit is a zero, the lower FET is on and the upper FET off to 



FIGURE 2.7 Port Pin Circuits 



Vcc 



Read Latch Bit 



Internal Bus 
Write to Latch 



Read Pin Data 
Read Latch Data 



Internal Bus 
Write to Latch 



Read Pin Data 

Control Signals 

Address 

Read Latch Bit 



Internal Bus 
Write to Latch 



Read Pin Data 
Alternate Output 

Read Latch Bit 



Internal Bus 
Write to Latch 



Read Pin Data 
Alternate Input 




D Q 
CL Q 



Enhancement- 
Mode I 



Control 
Logic 



PortSFR Latch 




Two Oscillator 
Periods 



?FET [ 



Vcc 



Q 

CL Q 



Internal 
FET 

Pullup 



PortSFR Latch 



9 




D Q 

CL q 



Vcc 



Control 

Logic 



lJV 



Port SFR Latch 




IS 



Depletion - 
Mode FET 



Internal FET Pullup 



Pin 
O.X 



Port Pin Configuration 



lal — 

,p Sr . f PirT 

tf 2 



Port 1 Pin Configuration 



Internal 

FET 
Pullup 



Pin 
2.X 



Port 2 Pin Configuration 




Port 3 Pin Configuration 



THE 8051 ARCHITECTURE 25 

provide a logic low at the pin. After the address has been formed and latched into external 
circuits by the Address Latch Enable (ALE) pulse, the bus is turned around to become a 
data bus. Port now reads data from the external memory and must be configured as an 
input, so a logic 1 is automatically written by internal control logic to all port latches. 

Portl 

Port 1 pins have no dual functions. Therefore, the output latch is connected directly to the 
gate of the lower FET, which has an FET circuit labeled "Internal FET Pullup" as an 
active pullup load. 

Used as an input, a 1 is written to the latch, turning the lower FET off; the pin and the 
input to the pin buffer are pulled high by the FET load. An external circuit can overcome 
the high impedance pullup and drive the pin low to input a or leave the input high for a 1 . 

If used as an output, the latches containing a 1 can drive the input of an external 
circuit high through the pullup. If a is written to the latch, the lower FET is on, the 
pullup is off, and the pin can drive the input of the external circuit low. 

To aid in speeding up switching times when the pin is used as an output, the internal 
FET pullup has another FET in parallel with it. The second FET is turned on for two 
oscillator time periods during a low-to-high transition on the pin, as shown in Figure 2.7. 
This arrangement provides a low impedance path to the positive voltage supply to help 
reduce rise times in charging any parasitic capacitances in the external circuitry. 

Port 2 

Port 2 may be used as an input/output port similar in operation to port 1 . The alternate use 
of port 2 is to supply a high-order address byte in conjunction with the port low-order 
byte to address external memory. 

Port 2 pins are momentarily changed by the address control signals when supplying 
the high byte of a 16-bit address. Port 2 latches remain stable when external memory is 
addressed, as they do not have to be turned around (set to 1) for data input as is the case 
for port 0. 

Port 3 

Port 3 is an input/output port similar to port 1. The input and output functions can be 
programmed under the control of the P3 latches or under the control of various other spe- 
cial function registers. The port 3 alternate uses are shown in the following table: 



PIN 




ALTERNATE USE 




SFR 


P3.0- 


-RXD 


Serial data input 




SBUF 


P3.1- 


-TXD 


Serial data output 




SBUF 


P3.2- 


-INTO 


External interrupt 




TCON.1 


P3.3- 


-INT1 


External interrupt 1 




TCON.3 


P3.4- 


-TO 


External timer input 




TMOD 


P3.5- 


-T1 


External timer 1 input 




TMOD 


P3.6- 


-WR 


External memory write 


pulse 


— 


P3.7- 


-RD 


External memory read pulse 


— 



Unlike ports and 2, which can have external addressing functions and change all 
eight port bits when in alternate use, each pin of port 3 may be individually programmed 
to be used either as I/O or as one of the alternate functions. 



26 CHAPTER TWO 



External Memory 



The system designer is not limited by the amount of internal RAM and ROM available 
on chip. Two separate external memory spaces are made available by the 16-bit PC and 
DPTR and by different control pins for enabling external ROM and RAM chips. Internal 
control circuitry accesses the correct physical memory, depending upon the machine cycle 
state and the opcode being executed. 

There are several reasons for adding external memory, particularly program memory, 
when applying the 8051 in a system. When the project is in the prototype stage, the 
expense — in time and money — of having a masked internal ROM made for each program 
"try" is prohibitive. To alleviate this problem, the manufacturers make available an 
EPROM version, the 8751 , which has 4K of on-chip EPROM that may be programmed 
and erased as needed as the program is developed. The resulting circuit board layout will 
be identical to one that uses a factory-programmed 805 1 . The only drawbacks to the 875 1 
are the specialized EPROM programmers that must be used to program the non-standard 
40-pin part, and the limit of "only" 4096 bytes of program code. 

The 8751 solution works well if the program will fit into 4K bytes. Unfortunately, 
many times, particularly if the program is written in a high-level language, the program 
size exceeds 4K bytes, and an external program memory is needed. Again, the manufac- 
turers provide a version for the job, the ROMless 8031. The EA pin is grounded when 
using the 8031 , and all program code is contained in an external EPROM that may be as 
large as 64K bytes and that can be programmed using standard EPROM programmers. 

External RAM, which is accessed by the DPTR, may also be needed when 128 bytes 
of internal data storage is not sufficient. Externa! RAM, up to 64K bytes, may also be 
added to any chip in the 8051 family. 

Connecting External Memory 

Figure 2.8 shows the connections between an 8031 and an external memory configuration 
consisting of I6K bytes of EPROM and 8K bytes of static RAM. The 805 1 accesses exter- 
nal RAM whenever certain program instructions are executed. External ROM is accessed 
whenever the EA (external access) pin is connected to ground or when the PC contains an 
address higher than the last address in the internal 4K bytes ROM (OFFFh). 8051 designs 
can thus use internal and external ROM automatically; the 8031 , having no internal ROM, 
must have EA grounded. 

Figure 2.9 shows the timing associated with an external memory access cycle. Dur- 
ing any memory access cycle, port is time multiplexed. That is, it first provides the 
lower byte of the 16-bit memory address, then acts as a bidirectional data bus to write or 
read a byte of memory data. Port 2 provides the high byte of the memory address during 
the entire memory read/write cycle. 

The lower address byte from port must be latched into an external register to save 
the byte. Address byte save is accomplished by the ALE clock pulse that provides the 
correct timing for the '373 type data latch. The port pins then become free to serve as a 
data bus. 

If the memory access is for a byte of program code in the ROM , the PSEN (program 
store enable) pin will go low to enable the R OM t o place a byte of program code on the 
data bus. If the access is for a RAM byte, the WR (write) or RD (read) pins will go low, 
enabling data to flow between the RAM and the data bus. 

The ROM may be expanded to 64K by using a 27512 type EPROM and connecting 
the remaining port 2 upper address lines AI4-A15 to the chip. 

At this time the largest static RAMs available are 32K in size; RAM can be expanded 
to 64K by using two 32K RAMs that are connected through address A14 of port 2. The 



FIGURE 2.8 

EA 



External Memory Connections 



■H 



31 



o 

a. 



8031 



o 

CL 




FIGURE 2.9 External Memory Timing 

3d 



PortO 



Port 2 



ALE Pulse 



PSEN Pulse 



-A7 I 



X 



D0-D7 | 



X 



IX 



A8-A15 



X 



i^H 



Latch Address 



External Memory Addressing 




PSEN 

Enable ROM 
Reading ROM Using PSEN I 



Read Pulse 



Write Pulse 




RD 
Enable Read 




WR 
Enable Write 



Accessing RAM Using RD or WR 



28 



CHAPTER TWO 



FIGURE 2.10 TCON and TMOD Function Registers 



7 


6 


5 


4 


3 


2 


1 





TF1 


TR1 


TFO 


TRO 


IE1 


IT1 


IEO 


ITO 



THE TIMER CONTROL (TCON) SPECIAL FUNCTION REGISTER 

Bit Symbol Function 

Timer 1 Overflow flag. Set when timer rolls from all ones to zero. Cleared when processor 
vectors to execute interrupt service routine located at program address 001 Bh. 



TF1 



TR1 



TFO 



TRO 



IE1 



IT1 



IEO 



Timer 1 run control bit. Set to 1 by program to enable timer to count; cleared to by 
program to halt timer. Does not reset timer. 

Timer Overflow flag. Set when timer rolls from all ones to zero. Cleared when processor 
vectors to execute interrupt service routine located at program address OOOBh. 

Timer run control bit. Set to 1 by program to enable timer to count; cleared to by 
program to halt timer. Does not reset timer. 

External interrupt 1 edge flag. Set to 1 when a high to low edge signal is received on port 3 
pin 3.3 (INTO. Cleared when processor vectors to interrupt service routine 
located at program address 0013h. Not related to timer operations. 

External interrupt 1 signal type control bit. Set to 1 by program to enable external interrupt 1 
to be triggered by a falling edge signal. Set to by program to enable a low level 
signal on external interrupt 1 to generate an interrupt. 

External interrupt edge flag. Set to 1 when a high to low edge signal is received on port 3 
pin 3.2 (INTO). Cleared when processor vectors to interrupt service routine located at 
program address 0003h. Not related to timer operations. 

Continued 



first 32K RAM (0O00h-7FFFh) can then be enabled when A15 of port 2 is low, and the 
second 32K RAM (8000h-FFFFh) when A15 is high, by using an inverter. 

Note that the WR and RD signals are alternate uses for port 3 pins 16 and 17. Also, 
port is used for the lower address byte and data; port 2 is used for upper address bits. The 
use of external memory consumes many of the port pins, leaving only port 1 and parts of 
port 3 for general I/O. 



Counters and Timers 



Many microcontroller applications require the counting of external events, such as the 
frequency of a pulse train, or the generation of precise internal time delays between com- 
puter actions. Both of these tasks can be accomplished using software techniques, but 
software loops for counting or timing keep the processor occupied so that other, perhaps 
more important, functions are not done. To relieve the processor of this burden, two 16-bit 
up counters, named TO and Tl , are provided for the general use of the programmer. Each 
counter may be programmed to count internal clock pulses, acting as a timer, or pro- 
grammed to count external pulses as a counter. 



THE 8051 ARCHITECTURE 



29 



Bit 





Symbol 

ITO 



Function 

External interrupt signal type control bit. Set to 1 by program to enable external interrupt 
to be triggered by a falling edge signal. Set to by program to enable a low level 
signal on external interrupt to generate an interrupt. 



Bit addressable as TCON.O to TCON.7 



7 


6 


5 


4 


3 


2 


1 





Gate 


C/T 


Ml 


MO 


Gate 


C/T 


Ml 


MO 




Timer 1 


][ 


Timer 


■ 



THE TIMER MODE CONTROL (TMOD) SPECIAL FUNCTION REGISTER 



Bit Symbol 

7/3 Gate 



6/2 



5/1 



C/T 



M1 



4/0 MO 



Function 

OR gate enable bit which controls RUN/STOP of timer 1 10. Set to 1 by program to enable 
timer to run if bit TR1 /0 in TCON is set and signal on external interrupt INT1 /0 pin is 
high. Cleared to by program to enable timer to run if bit TR1 /0 in TCON is set. 

Set to 1 by program to make timer 1/0 act as a counter by counting pulses from external 
input pins 3.5 (T1) or 3.4 (TO). Cleared to by program to make timer act as a timer 
by counting internal frequency. 

Timer/counter operating mode select bit 1 . Set/cleared by program to select mode. 

Timer/counter operating mode select bit 0. Set/cleared by program to select mode. 



Ml 





1 
1 



MO 



1 



1 



Mode 



1 

2 

3 



TMOD is not bit addressable 



The counters are divided into two 8-bit registers called the timer low (TLO, TL 1 ) and 
high (THO, TH1) bytes. All counter action is controlled by bit states in the timer mode 
control register (TMOD), the timer/counter control register (TCON), and certain program 
instructions. 

TMOD is dedicated solely to the two timers and can be considered to be two duplicate 
4-bit registers, each of which controls the action of one of the timers. TCON has control 
bits and flags for the timers in the upper nibble, and control bits and flags for the external 
interrupts in the lower nibble. Figure 2. 10 shows the bit assignments for TMOD and TCON. 

Timer Counter Interrupts 

The counters have been included on the chip to relieve the processor of timing and count- 
ing chores. When the program wishes to count a certain number of internal pulses or 
external events, a number is placed in one of the counters. The number represents the 
maximum count less the desired count, plus one. The counter increments from the initial 
number to the maximum and then rolls over to zero on the final pulse and also sets a timer 
flag. The flag condition may be tested by an instruction to tell the program that the count 
has been accomplished, or the flag may be used to interrupt the program. 



30 CHAPTER TWO 



FIGURE 2.1 1 Timer/Counter Control Logic 

Timer 



Oscillator 
Frequency 



Gate Bit In TMOD 
INTl/0 Input Pin 



+ 12d 




CfT = (TMOD Timer Operation) 



Counter 



Tl/0 Input Pin 



J 



C/T = 1 fTMOD Counter Operation) 



TRl/OBitlnTCON 




-^- To Timer Stages 



Timing 

If a counter is programmed to be a timer, it will count the internal clock frequency of the 
8051 oscillator divided by 12d. As an example, if the crystal frequency is 6.0 megahertz, 
then the timer clock will have a frequency of 500 kilohertz. 

The resultant timer clock is gated to the timer by means of the circuit shown in Figure 
2.1 1. In order for oscillator clock pulses to reach the timer, the C/T bit in the TMOD 
register must be set to (timer operation). Bit TRX in the TCON register must be set to 1 
(timer run), and the gate bit in the TMOD register must be 0, or external pin INTX must 
be a 1 . In other words, the counter is configured as a timer, then the timer pulses are gated 
to the counter by the run bit and the gate bit or the external input bits INTX. 

Timer Modes of Operation 

The timers may operate in any one of four modes that are determined by the mode bits, 
M I and M0, in the TMOD register. Figure 2.12 shows the four timer modes. 

Timer Mode 

Setting timer X mode bits to 00b in the TMOD register results in using the THX register 
as an 8-bit counter and TLX as a 5-bit counter; the pulse input is divided by 32d in TL so 
that TH counts the original oscillator frequency reduced by a total 384d. As an example, 
the 6 megahertz oscillator frequency would result in a final frequency to TH of 15625 
hertz. The timer flag is set whenever THX goes from FFh to OOh, or in .0164 seconds for 
a 6 megahertz crystal if THX starts at OOh. 

Timer Mode 1 

Mode l is similar to mode except TLX is configured as a full 8-bit counter when the 
mode bits are set to 01b in TMOD. The timer flag would be set in .1311 seconds using 
a 6 megahertz crystal. 



THE 8051 ARCHITECTURE 31 



FIGURE 2.12 Timer 1 and Timer Operation Modes 



Pulse 

Input 

(Figure 2. 11) 



TLX 5 Bits 



THX8Bits 



TFX 



■*" Interrupt 



Timer Mode 13 - Bit Timer/Counter 



Pulse 

Input 

(Figure 2.11) 



TLX 8 Bits 



THX8Bits 



TFX 



-^- Interrupt 



Timer Mode 1 16 -Bit Timer/Counter 



Pulse 

Input 

{Figure 2.11) 



TLX 8 Bits 




THX8Bits 



TFX 



♦- Interrupt 



Reload TLX 



Timer Mode 2 Auto- Reload of TL from TH 



Pulse 

Input 

(Figure 2. 11) 



TL0 8Bits 



TFO 



■^- Interrupt 





r 


TH0 8Bits 




TF1 












TR1 Rit _ 


Timer Mode 3 Two fl 


-Bit Timers Using Ti 


merO 






In TCON 





Timer Mode 2 

Setting the mode bits to 10b in TMOD configures the timer to use only the TLX counter as 
an 8-bit counter. THX is used to hold a value that is loaded into TLX every time TLX 
overflows from FFh to OOh. The timer flag is also set when TLX overflows. 

This mode exhibits an auto-reload feature: TLX will count up from the number in 
THX, overflow, and be initialized again with the contents of THX. For example, placing 



32 CHAPTER TWO 



9Ch in THX will result in a delay of exactly .0002 seconds before the overflow flag is set 
if a 6 megahertz crystal is used. 

Timer Mode 3 

Timers and 1 may be programmed to be in mode 0, 1, or 2 independently of a similar 
mode for the other timer. This is not true for mode 3; the timers do not operate indepen- 
dently if mode 3 is chosen for timer 0. Placing timer 1 in mode 3 causes it to stop count- 
ing; the control bit TR1 and the timer 1 flag TFI are then used by timer 0. 

Timer in mode 3 becomes two completely separate 8-bit counters. TL0 is controlled 
by the gate arrangement of Figure 2. 1 1 and sets timer flag TF0 whenever it overflows from 
FFh to OOh. TH0 receives the timer clock (the oscillator divided by 12) under the control 
of TR1 only and sets the TFI flag when it overflows. 

Timer 1 may still be used in modes 0, 1 , and 2, while timer is in mode 3 with one 
important exception: No interrupts will be generated by timer 1 while timer is using the 
TFI overflow flag. Switching timer I to mode 3 will stop it (and hold whatever count is in 
timer I). Timer 1 can be used for baud rate generation for the serial port, or any other 
mode 0, 1 , or 2 function that does not depend upon an interrupt (or any other use of the 
TFI flag) for proper operation. 

Counting 

The only difference between counting and timing is the source of the clock pulses to the 
counters. When used as a timer, the clock pulses are sourced from the oscillator through 
the divide-by- 1 2d circuit. When used as a counter, pin TO (P3.4) supplies pulses to 
counter 0, and pin T 1 (P3.5) to counter 1 . The C/T bit in TMOD must be set to 1 to enable 
pulses from the TX pin to reach the control circuit shown in Figure 2. 11. 

The input pulse on TX is sampled during P2 of state 5 every machine cycle. A change 
on the input from high to low between samples will increment the counter. Each high and 
low state of the input pulse must thus be held constant for at least one machine cycle to 
ensure reliable counting. Since this takes 24 pulses, the maximum input frequency that 
can be accurately counted is the oscillator frequency divided by 24. For our 6 megahertz 
crystal, the calculation yields a maximum external frequency of 250 kilohertz. 



Serial Data Input/Output 



Computers must be able to communicate with other computers in modern multiprocessor 
distributed systems. One cost-effective way to communicate is to send and receive data 
bits serially. The 8051 has a serial data communication circuit that uses register SBUF to 
hold data. Register SCON controls data communication, register PCON controls data 
rates, and pins RXD (P3.0) and TXD (P3.1) connect to the serial data network. 

SBUF is physically two registers. One is write only and is used to hold data to be 
transmitted out of the 8051 via TXD. The other is read only and holds received data from 
external sources via RXD. Both mutually exclusive registers use address 99h. 

There are four programmable modes for serial data communication that are chosen by 
setting the SMX bits in SCON. Baud rates are determined by the mode chosen. Figure 2. 13 
shows the bit assignments for SCON and PCON. 

Serial Data Interrupts 

Serial data communication is a relatively slow process, occupying many milliseconds per 
data byte to accomplish. In order not to tie up valuable processor time, serial data flags are 



FIGURE 2.13 SCON and PCON Function Registers 



7 


6 


5 


4 


3 


2 


1 





SMO 


SMI 


SM2 


REN 


TB8 


RB8 


Tl 


Rl 



THE SERIAL PORT CONTROL (SCON) SPECIAL FUNCTION REGISTER 

Bit Symbol Function 

Serial port mode bit 0. Set/cleared by program to select mode. 



SMO 
SM1 



SM2 



4 


REN 


3 


TB8 


2 


RB8 



Tl 



Rl 



Serial port mode bit 1 . Set/cleared by program to select mode. 

SMO SM 1 Mode Description 

Shift register; baud = f/12 

1 1 8-bit UART; baud - variable 

1 2 9-bit UART; baud = f/32 or f/64 
1 1 3 9-bit UART; baud = variable 

Multiprocessor communications bit. Set/cteared by program to enable multiprocessor 

communications in modes 2 and 3. When set to 1 an interrupt is generated if bit 9 of 
the received data is a 1 ; no interrupt is generated if bit 9 is a 0. If set to 1 for mode 1 , 
no interrupt will be generated unless a valid stop bit is received. Clear to if mode 
is in use. 

Receive enable bit. Set to 1 to enable reception; cleared to to dissable reception. 

Transmitted bit 8. Set/cleared by program in modes 2 and 3. 

Received bit 8. Bit 8 of received data in modes 2 and 3; stop bit in mode 1. Not used in 
mode 0. 

Transmit interrupt flag. Set to one at the end of bit 7 time in mode 0, and at the beginning 
of the stop bit for other modes. Must be cleared by the program. 

Receive interrupt flag. Set to one at the end of bit 7 time in mode 0, and halfway through 
the stop bit for other modes. Must be cleared by the program. 

Bit addressable as SCON.O to SCON. 7 



7 


6 


5 


4 


3 


2 


1 





SMOD 


— 


— 


— 


GF1 


GFO 


PO 


1DL 



THE POWER MODE CONTROL (PCON) SPECIAL FUNCTION REGISTER 

Bit Symbol Function 

7 SMOD Serial baud rate modify bit. Set to 1 by program to double baud rate using timer 1 for 

modes 1, 2, and 3. Cleared to by program to use timer 1 baud rate. 

Not implemented. 

General purpose user flag bit 1. Set/cleared by program. 

General purpose user flag bit 0. Set/cleared by program. 

Power down bit. Set to 1 by program to enter power down configuration for CHMOS 
processors. 

Idle mode bit. Set to 1 by program to enter idle mode configuration for CHMOS 
processors. PCON is not bit addressable. 



6-4 


— 


3 


GF1 


2 


GFO 


1 


PD 



IDL 



34 CHAPTER TWO 



included in SCON to aid in efficient data transmission and reception. Notice that data 
transmission is under the complete control of the program, but reception of data is unpre- 
dictable and at random times that are beyond the control of the program. 

The serial data flags in SCON, TI and RI, are set whenever a data byte is transmitted 
(TI) or received (RI). These flags are ORed together to produce an interrupt to the pro- 
gram. The program must read these flags to determine which caused the interrupt and then 
clear the flag. This is unlike the timer flags that are cleared automatically; it is the respon- 
sibility of the programmer to write routines that handle the serial data flags. 

Data Transmission 

Transmission of serial data bits begins anytime data is written to SBUF. TI is set to a 1 
when the data has been transmitted and signifies that SBUF is empty (for transmission 
purposes) and that another data byte can be sent. If the program fails to wait for the TI flag 
and overwrites SBUF while a previous data byte is in the process of being transmitted, the 
results will be unpredictable (a polite term for "garbage out"). 

Data Reception 

Reception of serial data will begin if the receive enable bit (REN) in SCON is set to 1 for 
all modes. In addition, for mode only, RI must be cleared to also. Receiver interrupt 
flag RI is set after data has been received in all modes. Setting REN is the only direct 
program control that limits the reception of unexpected data; the requirement that RI also 
be for mode prevents the reception of new data until the program has dealt with the old 
data and reset RI. 

Reception can begin in modes 1 , 2, and 3 if RI is set when the serial stream of bits 
begins. RI must have been reset by the program before the last bit is received or the 
incoming data will be lost. Incoming data is not transferred to SBUF until the last data bit 
has been received so that the previous transmission can be read from SBUF while new 
data is being received. 

Serial Data Transmission Modes 

The 805 1 designers have included four modes of serial data transmission that enable data 
communication to be done in a variety of ways and a multitude of baud rates. Modes are 
selected by the programmer by setting the mode bits SMO and SM 1 in SCON. Baud rates 
are fixed for mode and variable, using timer 1 and the serial baud rate modify bit (SMOD) 
in PCON, for modes 1, 2, and 3. 

Serial Data Mode — Shift Register Mode 

Setting bits SMO and SMI in SCON to 00b configures SBUF to receive or transmit eight 
data bits using pin RXD for both functions. Pin TXD is connected to the internal shift 
frequency pulse source to supply shift pulses to external circuits. The shift frequency, or 
baud rate, is fixed at 1/12 of the oscillator frequency, the same rate used by the timers 
when in the timer configuration. The TXD shift clock is a square wave that is low for 
machine cycle states S3-S4-S5 and high for S6-S1-S2. Figure 2.14 shows the timing 
for mode shift register data transmission. 

When transmitting, data is shifted out of RXD; the data changes on the falling edge 
of S6P2, or one clock pulse after the rising edge of the output TXD shift clock. The sys- 
tem designer must design the external circuitry that receives this transmitted data to re- 
ceive the data reliably based on this timing. 



THE 8051 ARCHITECTURE 35 



FIGURE 2.14 Shift Register Mode Timing 



Shift Data Out 
S6P2 



I I I I 



RXD Data Out 



TXD Clock 



RXD Data In 



DO Dl D2 D3 I D4 D5 D6 D7 External Data Bits Shifted Out 



Ii2l3l4l5l6l7l8 



"nifTLiirujrujnijrLijnj^ 

!l l 2 1 3 U \b ~6 1 7 l{ 



I I 

S3P1 | S6P1 | 



DO 



Dl 



D2 



D3 



D4 



I I 



External Data Bits Shifted In 



D5 



D6 



D7 



S5P2 

Shift Data In 



Received data conies in on pin RXD and should be synchronized with the shift clock 
produced at TXD. Data is sampled on the falling edge of S5P2 and shifted in to SBUF on 
the rising edge of the shift clock. 

Mode is intended not for data communication between computers, but as a high- 
speed serial data-collection method using discrete logic to achieve high data rates. The 
baud rate used in mode will be much higher than standard for any reasonable oscillator 
frequency; for a 6 megahertz crystal, the shift rate will be 500 kilohertz. 

Serial Data Mode 1— Standard UART 

When SMO and SMI are set to 01b, SBUF becomes a 10-bit full-duplex receiver/ 
transmitter that may receive and transmit data at the same time. Pin RXD receives all data, 
and pin TXD transmits all data. Figure 2. 15 shows the format of a data word. 

Transmitted data is sent as a start bit, eight data bits (Least Significant Bit, LSB, 
first), and a stop bit. Interrupt flag TI is set once all ten bits have been sent. Each bit 
interval is the inverse of the baud rate frequency, and each bit is maintained high or low 
over that interval. 

Received data is obtained in the same order; reception is triggered by the falling edge 
of the start bit and continues if the stop bit is true (0 level) halfway through the start bit 
interval. This is an anti-noise measure; if the reception circuit is triggered by noise on the 
transmission line, the check for a low after half a bit interval should limit false data 
reception. 

Data bits are shifted into the receiver at the programmed baud rate, and the data word 
will be loaded to SBUF if the following conditions are true: RI must be 0, and mode bit 
SM2 is or the stop bit is 1 (the normal state of stop bits). RI set to implies that the 
program has read the previous data byte and is ready to receive the next; a normal stop bit 
will then complete the transfer of data to SBUF regardless of the state of SM2. SM2 set 
to enables the reception of a byte with any stop bit state, a condition which is of limited 
use in this mode, but very useful in modes 2 and 3. SM2 set to 1 forces reception of only 
"good" stop bits, an anti-noise safeguard. 

Of the original ten bits, the start bit is discarded, the eight data bits go to SBUF, and 
the stop bit is saved in bit RB8 of SCON. RI is set to 1 , indicating a new data byte has 
been received. 



36 CHAPTER TWO 



FIGURE 2.1 5 Standard UART Data Word 

Receiver Samples Data in Center of Bit Time 



tdle State 



L A I I I 1^1 



Idle State 



I 1 I 2 | 3 I 4 f 5 t 6 I 7 

L L I I J L L_ 

Start Bit ^ _ Data Bits 



1 



Minimum Of 
One Stop Bit 



Bit Time = — 
f 



If RI is found to be set at the end of the reception, indicating that the previously 
received data byte has not been read by the program, or if the other conditions listed are 
not true, the new data will not be loaded and will be lost. 

Mode 1 Baud Rates 

Timer I is used to generate the baud rate for mode 1 by using the overflow flag of the timer 
to determine the baud frequency. Typically, timer 1 is used in timer mode 2 as an autoload 
8-bit timer that generates the baud frequency: 



7 SMOD 
tk„.^ = X 



l haud 



32d 



oscillator frequency 
12d x [256d - (TH1)] 



SMOD is the control bit in PCON and can be or 1 , which raises the 2 in the equation to a 
value of 1 or 2. 

If timer 1 is not run in timer mode 2, then the baud rate is 



'haud 



(SMOD 



32d 



x (timer 1 overflow frequency) 



and timer I can be run using the internal clock or as a counter that receives clock pulses 
from any external source via pin Tl . 

The oscillator frequency is chosen to help generate both standard and nonstandard 
baud rates. If standard baud rates are desired, then an 1 1 .0592 megahertz crystal could be 
selected. To get a standard rate of 9600 hertz then, the setting of TH1 may be found as 
follows: 



TH1 = 256d - 

if SMOD is cleared to 0. 



2° 11.0592 x 10* 
32d 12 x 9600d 



= 253.0000d - OFDh 



Serial Data Mode 2 — Multiprocessor Mode 

Mode 2 is similar to mode 1 except 1 1 bits are transmitted: a start bit, nine data bits, and a 
stop bit, as shown in Figure 2.16. The ninth data bit is gotten from bit TB8 in SCON 
during transmit and stored in bit RB8 of SCON when data is received. Both the start and 
stop bits are discarded. 

The baud rate is programmed as follows: 



' haud 2 



I SMOD 



64d 



x oscillator frequency 



THE 8051 ARCHITECTURE 37 



FIGURE 2.16 Multiprocessor Data Word 

Receiver Samples Data in Center of Bit Time 



Idle State 



II I UJ_L1J 



Idle State 



r t J 1 1 1 

|l|2|3l4|5|6|7J8J9 
J I I J J L I I L — 



Start Bit 



Data Bits 



Minimum Of 
One Stop Bit 



Bit Time = — 
f 



Here, as in the case for mode 0, the baud rate is much higher than standard communica- 
tion rates. This high data rate is needed in many mu I ti -processor applications. Data can be 
collected quickly from an extensive network of communicating microcontrollers if high 
baud rates are employed. 

The conditions for setting RI for mode 2 are similar to mode 1 : RI must be before 
the last bit is received, and SM2 must be or the ninth data bit must be a 1 . Setting RI 
based upon the state of SM2 in the receiving 805 1 and the state of bit 9 in the transmitted 
message makes multiprocessing possible by enabling some receivers to be interrupted by 
certain messages, while other receivers ignore those messages. Only those 805 Ts that 
have SM2 set to will be interrupted by received data which has the ninth data bit set to 0; 
those with SM2 set to 1 will not be interrupted by messages with data bit 9 at 0. All re- 
ceivers will be interrupted by data words that have the ninth data bit set to 1; the state of 
SM2 will not block reception of such messages. 

This scheme allows the transmitting computer to "talk" to selected receiving comput- 
ers without interrupting other receiving computers. Receiving computers can be com- 
manded by the "talker" to "listen" or "deafen" by transmitting coded byte(s) with the 
ninth data bit set to 1 . The 1 in data bit 9 interrupts all receivers, instructing those that are 
programmed to respond to the coded byte(s) to program the state of SM2 in their respec- 
tive SCON registers. Selected listeners then respond to the bit 9 set to messages, while 
all other receivers ignore these messages. The talker can change the mix of listeners by 
transmitting bit 9 set to 1 messages that instruct new listeners to set SM2 to 0, while others 
are instructed to set SM2 to 1 . 

Serial Data Mode 3 

Mode 3 is identical to mode 2 except that the baud rate is determined exactly as in mode 1 , 
using Timer 1 to generate communication frequencies. 



Interrupts 



A computer program has only two ways to determine the conditions that exist in internal 
and external circuits. One method uses software instructions that jump on the states of 
flags and port pins. The second responds to hardware signals, called interrupts, that force 
the program to call a sub-routine. Software techniques use up processor time that could be 
devoted to other tasks; interrupts take processor time only when action by the program 
is needed. Most applications of microcontrollers involve responding to events quickly 
enough to control the environment that generates the events (generically termed "real- 



FIGURE 2.17 IE and IP Function Registers 



7 


6 


5 


4 


3 


2 


1 





EA 


— 


ET2 


ES 


ET1 


EX1 


ETO 


EXO 



THE INTERRUPT ENABLE (IE) SPECIAL FUNCTION REGISTER 

Bit Symbol Function 

Enable interrupts bit. Cleared to by program to disable all interrupts; set to 1 to permit 
individual interrupts to be enabled by their enable bits. 



EA 



ET2 
ES 

ET1 

EX1 

ETO 

EXO 



Not implemented. 

Reserved for future use. 

Enable serial port interrupt. Set to 1 by program to enable serial port interrupt; cleared 
to to disable serial port interrupt. 

Enable timer 1 overflow interrupt. Set to 1 by program to enable timer 1 overflow 
interrupt; cleared to to disable timer 1 overflow interrupt. 



Enable external interrupt 1. Set to 1 by program to enable INT1 interrupt; cleared to to 
disable INT1 interrupt. 

Enable timer overflow interrupt. Set to 1 by program to enable timer overflow interrupt; 
cleared to to disable timer overflow interrupt. 



Enable external interrupt 0. Set to 1 by program to enable INTO interrupt; cleared to to 
disable INTO interrupt. 

Bit addressable as IE.0 to IE. 7 



7 


6 


5 


4 


3 


2 


1 





— 


— 


PT2 


PS 


PT1 


PX1 


PTO 


PXO 



THE INTERRUPT PRIORITY (IP) SPECIAL FUNCTION REGISTER 

Bit Symbol Function 

Not implemented. 

Not implemented. 
Reserved for future use. 

Priority of serial port interrupt. Set/cleared by program. 
Priority of timer 1 overflow interrupt. Set/cleared by program. 
Priority of external interrupt 1 . Set/cleared by program. 
Priority of timer overflow interrupt. Set/cleared by program. 
Priority of external interrupt 0. Set/cleared by program. 
Note: Priority may be 1 (highest) or (lowest) 
Bit addressable as IPO to IP.7 



7 


— 


6 


— 


5 


PT2 


4 


PS 


3 


PT1 


2 


PX1 


1 


PTO 





PXO 



THE 8051 ARCHITECTURE 39 

time programming"). Interrupts are often the only way in which real-time programming 
can be done successfully. 

Interrupts may be generated by internal chip operations or provided by external 
sources. Any interrupt can cause the 8051 to perform a hardware call to an interrupt- 
handling subroutine that is located at a predetermined (by the 8051 designers) absolute 
address in program memory. 

Five interrupts are provided in the 8051. Three of these are generated automatically 
by internal operations: timer flag 0, timer flag 1 , and the serial port interrupt (RI or TI). 
Two interrupts are triggered by external signals provided by circuitry that is connected to 
pins INTO and INT1 (port pins P3.2 and P3.3). 

All interrupt functions are under the control of the program. The programmer is able 
to alter control bits in the interrupt enable register (IE), the interrupt priority register (IP), 
and the timer control register (TCON). The program can block all or any combination of 
the interrupts from acting on the program by suitably setting or clearing bits in these regis- 
ters. The IE and IP registers are shown in Figure 2. 17. 

After the interrupt has been handled by the interrupt subroutine, which is placed by 
the programmer at the interrupt location in program memory, the interrupted program 
must resume operation at the instruction where the interrupt took place. Program resump- 
tion is done by storing the interrupted PC address on the stack in RAM before changing 
the PC to the interrupt address in ROM. The PC address will be restored from the stack 
after an RETI instruction is executed at the end of the interrupt subroutine. 

Timer Flag Interrupt 

When a timer/counter overflows, the corresponding timer flag, TF0 or TF1, is set to I. 
The flag is cleared to when the resulting interrupt generates a program call to the appro- 
priate timer subroutine in memory. 

Serial Port Interrupt 

If a data byte is received, an interrupt bit, RI, is set to 1 in the SCON register. When a data 
byte has been transmitted an interrupt bit, TI, is set in SCON. These are ORed together to 
provide a single interrupt to the processor: the serial port interrupt. These bits are not 
cleared when the interrupt-generated program call is made by the processor. The program 
that handles serial data communication must reset RI or TI to to enable the next data 
communication operation. 

External Interrupts 



Pins INTO and INT1 are used by external circuitry. Inputs on these pins can set the inter- 
rupt flags IE0 and IE 1 in the TCON register to I by two different methods. The IEX flags 
may be set when the INTX pin signal rea ches a low level, or the flags may be set when a 
high-to-low transition takes place on the INTX pin. Bits IT0 and IT1 in TCON program 
the INTX pins for low-level interrupt when set to and program the INTX pins for transi- 
tion interrupt when set to I . 

Flags IEX will be reset when a transition-generated interrupt is accepted by the pro- 
cessor and the interrupt subroutine is accessed. It is the responsibility of the system de- 
signer and programmer to reset any level-generated external interrupts when they are 
serviced by the program. The external circuit must remove the low level before an RETI is 
executed. Failure to remove the low will result in an immediate interrupt after RETI, from 
the same source. 



40 



CHAPTER TWO 



Reset 

A reset can be considered to be the ultimate interrupt because the program may not block 
the action of the voltage on the RST pin. This type of interrupt is often called "non- 
maskable," since no combination of bits in any register can stop, or mask the reset action. 
Unlike other interrupts, the PC is not stored for later program resumption; a reset is an 
absolute command to jump to program address OOOOh and commence running from there. 
Whenever a high level is applied to the RST pin, the 8051 enters a reset condition. 
After the RST pin is brought low, the internal registers will have the values shown in the 
following table: 



REGISTER 


VALUE(HEX) 


PC 


oooo 


DPTR 


0000 


A 


00 


B 


00 


SP 


07 


PSW 


00 


PO-3 


FF 


IP 


XXXOOOOOb 


IE 


OXXOOOOOb 


TCON 


00 


TMOD 


00 


THO 


00 


TLO 


00 


TH1 


00 


TL1 


00 


SCON 


00 


SBUF 


XX 


PCON 


OXXXXXXXb 



Internal RAM is not changed by a reset; however, the states of the internal RAM 
when power is first applied to the 805 1 are random. Register bank is selected upon reset 
as all bits in PSW are 0. 

Interrupt Control 

The program must be able, at critical times, to inhibit the action of some or all of the 
interrupts so that crucial operations can be finished. The IE register holds the program- 
mable bits that can enable or disable all the interrupts as a group, or if the group is en- 
abled, each individual interrupt source can be enabled or disabled. 

Often, it is desirable to be able to set priorities among competing interrupts that may 
conceivably occur simultaneously. The IP register bits may be set by the program to assign 
priorities among the various interrupt sources so that more important interrupts can be 
serviced first should two or more interrupts occur at the same time. 



Interrupt Enable/Disable 

Bits in the EI register are set to 1 if the corresponding interrupt source is to be enabled and 
set to to disable the interrupt source. Bit EA is a master, or "global," bit that can enable 
or disable all of the interrupts. 



Summary 



THE 8051 ARCHITECTURE 41 

Interrupt Priority 

Register IP bits determine if any interrupt is to have a high or low priority. Bits set to l 
give the accompanying interrupt a high priority while a assigns a low priority. Interrupts 
with a high priority can interrupt another interrupt with a lower priority; the low priority 
interrupt continues after the higher is finished. 

If two interrupts with the same priority occur at the same time, then they have the 
following ranking: 

1. IE0 

2. TFO 

3. IE1 

4. TF1 

5. Serial - RI OR TI 

The serial interrupt could be given the highest priority by setting the PS bit in IP to I , and 
all others to 0. 

Interrupt Destinations 

Each interrupt source causes the program to do a hardware call to one of the dedicated 
addresses in program memory. It is the responsibility of the programmer to place a routine 
at the address that will service the interrupt. 

The interrupt saves the PC of the program, which is running at the time the interrupt 
is serviced on the stack in internal RAM. A call is then done to the appropriate memory 
location. These locations are shown in the following table: 



INTERRUPT 


ADD 


IE0 


0003 


TFO 


000B 


IE1 


0013 


TF1 


001 B 


SERIAL 


0023 



A RETI instruction at the end of" the routine restores the PC to its place in the inter- 
rupted program and resets the interrupt logic so that another interrupt can be serviced. 
Interrupts that occur but are ignored due to any blocking condition (IE bit not set or a 
higher priority interrupt already in process) must persist until they are serviced, or they 
will be tost. This requirement applies primarily to the level- activated INTX interrupts. 

Software Generated Interrupts 

When any interrupt flag is set to I by any means, an interrupt is generated unless blocked. 
This means that the program itself can cause interrupts of any kind to be generated simply 
by setting the desired interrupt flag to 1 using a program instruction. 



The internal hardware configuration of the 8051 registers and control circuits have been 
examined at the functional block diagram level. The 805 1 may be considered to be a col- 
lection of RAM, ROM, and addressable registers that have some unique functions. 



42 CHAPTER TWO 



Register 


Bit 


A 


8 


B 


8 


PC 


16 


DPTR 


16 


SP 


8 


PSW 


8 


P0-P3 


8 


THO/TLO 


8/8 


TH1/TL1 


8/8 


TCON 


8 


TMOD 


8 


SBUF 


8 


SCON 


8 


PC ON 


8 


IE 


8 


IP 


8 



SPECIAL-FUNCTION REGISTERS 

Primary Function Bit Addressable 

Math, data manipulation Y 

Math Y 

Addressing program bytes N 

Addressing code and external data N 
Addressing internal RAM stack data N 

Processor status Y 

Store I/O port data Y 

Timer/counter N 

Timer/counter 1 N 

Timer /counter control Y 

Timer/counter control N 

Serial port data N 

Serial port control Y 

Serial port control, user flags N 

Interrupt enable control Y 

Interrupt priority control Y 

DATA AND PROGRAM MEMORY 

Internal Bytes Function 

RAM 128 R0-R7 registers, data storage, stack 

ROM 4K Program storage 

External Bytes Function 

RAM 64K Data storage 

ROM 64K Program storage 

EXTERNAL CONNECTION PINS 

Function 

Port pins 36 I/O, external memory, interrupts 

Oscillator 2 Clock 

Power 2 

Questions 

Find the following using the information provided in Chapter 2. 

1. Size of the interna! RAM. 

2. Internal ROM size in the 8031. 

3. Execution time of a single byte instruction for a 6 megahertz crystal. 

4. The 16-bit data addressing registers and their functions. 

5. Registers that can do division. 

6. The flags that are stored in the PSW. 

7. Which register holds the serial data interrupt bits TI and RI. 

8. Address of the stack when the 805 1 is reset. 

9. Number of register banks and their addresses. 

10. Ports used for external memory access. 

11. The bits that determine timer modes and the register that holds these bits. 



THE 8051 ARCHITECTURE 43 

12. Address of a subroutine that handles a timer 1 interrupt. 

13. Why a low-address byte latch for external memory is needed. 

14. How an I/O pin can be both an input and output. 

15. Which port has no alternate functions. 

16. The maximum pulse rate that can be counted on pin Tl if the oscillator frequency is 
6 megahertz. 

17. Which bits in which registers must be set to give the serial data interrupt the highest 
priority. 

18. The baud rate for the serial port in mode for a 6 megahertz crystal. 

19. The largest possible time delay for a timer in mode 1 if a 6 megahertz crystal is used. 

20. The setting of TH1, in timer mode 2, to generate a baud rate of 1200 if the serial port is 
in mode 1 and an 1 1 .059 megahertz crystal is in use. Find the setting for both values of 
SMOD. 

21. The address of the PCON special -function register. 

22. The time it will take a timer in mode I to overflow if initially set to 03AEh with a 
6 megahertz crystal. 

23. Which bits in which registers must be set to 1 to have timer count input pulses on pin 
TO in timer mode 0. 

24. The register containing GF0 and GF1 . 

25. The signal that reads external ROM. 

26. When used in multiprocessing, which bit in which register is used by a transmitting 
8051 to signal receiving 805 Ts that an interrupt should be generated. 

27. The two conditions under which program opcodes are fetched from external, rather than 
internal, memory. 



28. Which bits in which register(s) must be set to make INTO level activated, and INT1 edge 
triggered. 



29. The address of the interrupt program for the INTO level-generated interrupt. 

30, The bit address of bit 4 of RAM byte 2Ah. 




Moving Data 



Chapter Outline 

Introduction 
Addressing Modes 
External Data Moves 
PUSH and POP Opcodes 



Data Exchanges 
Example Programs 
Summary 



Introduction 



A computer typically spends more time moving data from one location to another than it 
spends on any other operation. It is not surprising, therefore, to find that more instructions 
are provided for moving data than for any other type of operation. 

Data is stored at a source address and moved (actually, the data is copied) to a desti- 
nation address. The ways by which these addresses are specified are called the addressing 
modes. The 8051 mnemonics are written with the destination address named first, fol- 
lowed by the source address. 

A detailed study of the operational codes (opcodes) of the 805 1 begins in this chapter. 
Although there are 28 distinct mnemonics that copy data from a source to a destination, 
they may be divided into the following three main types: 

1. MOV destination, source 

2. PUSH source or POP destination 

3. XCH destination, source 

The following four addressing modes are used to access data: 

1. Immediate addressing mode 

2. Register addressing mode 



44 



MOVING DATA 45 

3. Direct addressing mode 

4. Indirect addressing mode 

The MOV opcodes involve data transfers within the 805 1 memory. This memory is 
divided into the following four distinct physical parts: 

1. Internal RAM 

2. Internal special -function registers 

3. External RAM 

4. Internal and external ROM 

Finally, the following five types of opcodes are used to move data: 

1. MOV 

2. MOVX 

3. MOVC 

4. PUSH and POP 

5. XCH 



Addressing Modes 



The way in which the data sources or destination addresses are specified in the mnemonic 
that moves that data determines the addressing mode. Figure 3.1 diagrams the four ad- 
dressing modes: immediate, register, direct, and indirect. 

Immediate Addressing Mode 

The simplest way to get data to a destination is to make the source of the data part of the 
opcode. The data source is then immediately available as part of the instruction itself. 

When the 8051 executes an immediate data move, the program counter is automat- 
ically incremented to point to the byte(s) following the opcode byte in the program mem- 
ory. Whatever data is found there is copied to the destination address. 

The mnemonic for immediate data is the pound sign (#). Occasionally, in the rush to 
meet a deadline, one forgets to use the # for immediate data. The resulting opcode is 
often a legal command that is assembled with no objections by the assembler. This omis- 
sion guarantees that the rush will continue. 

Register Addressing Mode 

Certain register names may be used as part of the opcode mnemonic as sources or destina- 
tions of data. Registers A, DPTR, and R0 to R7 may be named as part of the opcode 
mnemonic. Other registers in the 8051 may be addressed using the direct addressing 
mode. Some assemblers can equate many of the direct addresses to the register name (as is 
the case with the assembler discussed in this text) so that register names may be used in 
lieu of register addresses. Remember that the registers used in the opcode as R0 to R7 are 
the ones that are currently chosen by the bank-select bits, RSO and RSI in the PSW. 

The following table shows all possible MOV opcodes using immediate and register 
addressing modes: 



46 



CHAPTER THREE 



Mnemonic 

MOV A,#n 
MOV A.Rr 
MOV Rr,A 
MOV Rr,#n 
MOV DPTR,#nn 



Operation 

Copy the immediate data byte n to the A register 

Copy data from register Rr to register A 

Copy data from register A to register Rr 

Copy the immediate data byte n to register Rr 

Copy the immediate 16-bit number nn to the DPTR register 



FIGURE 3.1 Addressing Modes 



Opcode (#n) 


Next Byte(s) 



Instruction Data 

Immediate Addressing Mode 



Data 
Register Addressing Mode 



Data 
Direct Addressing Mode 



Source Only 















Instruction 





















Source 

Or 

Destination 















Instruction 





















Source 

Or 

Destination 





(fflDnl 
































ROOrRl 















Data 
Indirect Addressing Mode 



Source 

Or 

Destination 



Address 



MOVING DATA 47 

A data MOV does not alter the contents of the data source address. A copy of the data 
is made from the source and moved to the destination address. The contents of the destina- 
tion address are replaced by the source address contents. The following table shows ex- 
amples of MOV opcodes with immediate and register addressing modes: 

Mnemonic Operation 

MOV A,#OFlh Move the immediate data byte Flh to the A register 

MOV A,R0 Copy the data in register RO to register A 

MOV DPTR,#OABCDh Move the immediate data bytes ABCDh to the DPTR 

MOV R5,A Copy the data in register A to register R5 

MOV R3,# ICh Move the immediate data byte ICh to register R3 



CAUTION 



It is impossible to have immediate data as a destination. 

All numbers must start with a decimal number (0-9), or the assembler assumes the number is 
a label. 

Register-to-register moves using the register addressing mode occur between registers A and 
RO to R7. 

Direct Addressing Mode 

AH 128 bytes of internal RAM and the SFRs may be addressed directly using the single- 
byte address assigned to each RAM location and each special-function register. 

Internal RAM uses addresses from 00 to 7Fh to address each byte. The SFR addresses 
exist from 80h to FFh at the following locations: 

SFR ADDRESS (HEX) 



A 


0E0 


B 


0F0 


DPL 


82 


DPH 


83 


IE 


0A8 


IP 


0B8 


P0 


80 


PI 


90 


P2 


0A0 


P3 


0B0 


PC ON 


87 


PSW 


0D0 


SBUF 


99 


SCON 


98 


SP 


81 


TCON 


88 


TMOD 


89 


THO 


8C 


TLO 


8A 


TH1 


8D 


TL1 


8B 



Note the use of a leading for all numbers that begin with an alphabetic (alpha) character. 

RAM addresses 00 to lFh are also the locations assigned to the four banks of eight 

working registers, R0 to R7. This assignment means that R2 of register bank can be 



48 



CHAPTER THREE 



addressed in the register mode as R2 or in the direct mode as 02h. The direct addresses of 
the working registers are as follows: 



BANK 


ADDRESS 


BANK 


ADDRESS 


REGISTER 


(HEX) 


REGISTER 


(HEX) 


RO 


00 


2 


RO 


10 


R1 


01 


2 


R1 


11 


R2 


02 


2 


R2 


12 


' R3 


03 


2 


R3 


13 


R4 


04 


2 


R4 


14 


R5 


05 


2 


R5 


15 


R6 


06 


2 


R6 


16 


R7 


07 


2 


R7 


17 


1 RO 


08 


3 


RO 


18 


1 R1 


09 


3 


R1 


19 


1 R2 


OA 


3 


R2 


1A 


1 R3 


OB 


3 


R3 


1B 


1 R4 


OC 


3 


R4 


1C 


1 R5 


OD 


3 


R5 


ID 


1 R6 


OE 


3 


R6 


1E 


1 R7 


OF 


3 


R7 


1F 



Only one bank of working registers is active at any given time. The PSW special- 
function register holds the bank-select bits, RSO and RS 1 , which determine which register 
bank is in use. 

When the 805 1 is reset, RSO and RS 1 are set to 00b to select the working registers in 
bank 0, located from OOh to 07h in internal RAM. Reset also sets SP to 07h, and the stack 
will grow up as it is used. This growing stack will overwrite the register banks above bank 
0. Be sure to set the SP to a number above those of any working registers the program 
may use. 

The programmer may choose any other bank by setting RSO and RSI as desired; this 
bank change is often done to "save" one bank and choose another when servicing an 
interrupt or using a subroutine. 

The moves made possible using direct, immediate, and register addressing modes are 
as follows: 



Mnemonic 

MOV A,add 
MOV add,A 
MOV Rr,add 
MOV add,Rr 
MOV add,#n 
MOVaddI,add2 



Operation 

Copy data from direct address add to register A 
Copy data from register A to direct address add 
Copy data from direct address add to register Rr 
Copy data from register Rr to direct address add 
Copy immediate data byte n to direct address add 
Copy data from direct address add2 to direct address addl 



The following table shows examples of MOV opcodes using direct, immediate, and 
register addressing modes: 



Mnemonic 

MOV A,80h 
MOV 80h,A 
MOV 3Ah,#3Ah 
MOV R0,12h 



Operation 

Copy data from the port pins to register A 
Copy data from register A to the port latch 
Copy immediate data byte 3Ah to RAM location 3Ah 
Copy data from RAM location I2h to register R0 



MOVING DATA 



49 



MOV 8Ch,R7 
MOV 5Ch,A 
MOV 0A8h.77h 



Copy data from register R7 to timer high byte 
Copy data from register A to RAM location 5Ch 
Copy data from RAM location 77h to IE register 



CAUTION 



MOV instructions that refer to direct addresses above 7Fh that are not SFRs will result in errors. 
The SFRs are physically on the chip; all other addresses above 7Fh do not physically exist. 

Moving data to a port changes the port latch; moving data from a port gets data from the 
port pins. 

Moving data from a direct address to itself is not predictable and could lead to errors. 

Indirect Addressing Mode 

For all the addressing modes covered to this point, the source or destination of the data is an 
absolute number or a name. Inspection of the opcode reveals exactly what are the addresses 
of the destination and source. For example, the opcode MOV A,R7 says that the A regis- 
ter will get a copy of whatever data is in register R7; MOV 33h,#32h moves the hex 
number 32 to hex RAM address 33. 

The indirect addressing mode uses a register to hold the actual address that will 
finally be used in the data move; the register itself is not the address, but rather the number 
in the register. Indirect addressing for MOV opcodes uses register RO or Rl , often called 
"data pointers," to hold the address of one of the data locations, which could be a RAM 
or an SFR address. The number that is in the pointing register (Rp) cannot be known un- 
less the history of the register is known. The mnemonic symbol used for indirect address- 
ing is the "at" sign, which is printed as @. 

The moves made possible using immediate, direct, register and indirect addressing 
modes are as follows: 



Mnemonic 

MOV @Rp,#n 
MOV @Rp,add 
MOV @Rp,A 
MOV add,@Rp 
MOV A,@Rp 



Operation 

Copy the immediate byte n to the address in Rp 
Copy the contents of add to the address in Rp 
Copy the data in A to the address in Rp 
Copy the contents of the address in Rp to add 
Copy the contents of the address in Rp to A 



The following table shows examples of MOV opcodes, using immediate, register, 
direct, and indirect modes 



Mnemonic 

MOV A,@RO 
MOV @Rl,#35h 
MOV add,@R0 
MOV@Rl,A 
MOV @R0,80h 



Operation 

Copy the contents of the address in RO to the A register 

Copy the number 35h to the address in Rl 

Copy the contents of the address in RO to add 

Copy the contents of A to the address in Rl 

Copy the contents of the port pins to the address in RO 



CAUTION 



The number in register Rp must be a RAM or an SFR address. 
Only registers RO or R1 may be used for indirect addressing. 



50 CHAPTER THREE 



FIGURE 3.2 External Addressing using MOVX and MOVC 



r~ 


8051 




















» 
Read 


Write 




MOVX @ Rp 




Read ' Write 




Read 




A Register 


Data 

External 
RAM 




Data 

Internal 

and 

External 

ROM 








ROOrRl 




1 MOVX @ DPTR 








DPTR 






MOVC A, @A + DPTR 






DPTR + A 










MOVC A, @A + PC 
















PC + A 








J 










L 













External Data Moves 



As discussed in Chapter 2, it is possible to expand RAM and ROM memory space by 
adding external memory chips to the 805 1 microcontroller. The external memory can be 
as large as 64K bytes for each of the RAM and ROM memory areas. Opcodes that access 
this external memory always use indirect addressing to specify the external memory. 

Figure 3.2 shows that registers RO, Rl, and the aptly named DPTR can be used to 
hold the address of the data byte in external RAM. RO and Rl are limited to external 
RAM address ranges of OOh to OFFh, while the DPTR register can address the maxi- 
mum RAM space of OOOOh to OFFFFh. 

An X is added to the MOV mnemonics to serve as a reminder that the data move is 
external to the 8051, as shown in the following table. 



Mnemonic 

MOVX A,@Rp 
MOVXA,@DPTR 
MOVX @Rp,A 
MOVX @DPTR,A 



Operation 

Copy the contents of the external address in Rp to A 
Copy the contents of the external address in DPTR to A 
Copy data from A to the externa! address in Rp 
Copy data from A to the external address in DPTR 



The following table shows examples of external moves using register and indirect 
addressing modes: 



Mnemonic 

MOVX @DPTR,A 
MOVX @R0,A 



Operation 

Copy data from A to the 16-bit address in DPTR 
Copy data from A to the 8-bit address in RO 



MOVING DATA 51 



MOVX A,@R1 Copy data from the 8-bit address in Rl to A 

MOVX A,@DPTR Copy data from the 16-bit address in DPTR to A 



£>— CAUTION 



All external data moves must involve the A register. 

Rp can address 256 bytes; DPTR can address 64K bytes. 

MOVX is normally used with external RAM or I/O addresses. 

Note that there are two sets of RAM addresses between 00 and OFFh: one internal and one 
external to the 8051. 



Code Memory Read-Only Data Moves 

Data moves between RAM locations and 8051 registers are made by using MOV and 
MOVX opcodes. The data is usually of a temporary or "scratch pad" nature and disap- 
pears when the system is powered down. 

There are times when access to a preprogrammed mass of data is needed, such as 
when using tables of predefined bytes. This data must be permanent to be of repeated use 
and is stored in the program ROM using assembler directives that store programmed data 
anywhere in ROM that the programmer wishes. 

Access to this data is made possible by using indirect addressing and the A register in 
conjunction with either the PC or the DPTR, as shown in Figure 3.2. In both cases, the 
number in register A is added to the pointing register to form the address in ROM where 
the desired data is to be found. The data is then fetched from the ROM address so formed 
and placed in the A register. The original data in A is lost, and the addressed data takes 
its place. 

As shown in the following table, the letter C is added to the MOV mnemonic to high- 
light the use of the opcodes for moving data from the source address in the Code ROM to 
the A register in the 805 1 : 

Mnemonic Operation 

MOVC A,@A + DPTR Copy the code byte, found at the ROM address formed by 

adding A and the DPTR, to A 
MOVC A,@A + PC Copy the code byte, found at the ROM address formed by 

adding A and the PC, to A 

Note that the DPTR and the PC are not changed; the A register contains the ROM byte 
found at the address formed. 

The following table shows examples of code ROM moves using register and indirect 
addressing modes: 

Mnemonic Operation 

MOV DPTR,#I234h Copy the immediate number 1234h to the DPTR 

MOV A,#56h Copy the immediate number 56h to A 

MOVC A,@A+DPTR Copy the contents of address 128Ah to A 
MOVC A,@A+PC Copies the contents of address 4059h to A if the PC 

contained 4000h and A contained 58h when the opcode 

is executed. 



52 



CHAPTER THREE 



CAUTION 



The PC is incremented by one (to point to the next instruction) before it is added to A to form 
the final address of the code byte. 

All data is moved from the code memory to the A register. 

MOVC is normally used with internal or external ROM and can address 4K of internal or 64K 
bytes of external code. 



PUSH and POP Opcodes 



The PUSH and POP opcodes specify the direct address of the data. The data moves 
between an area of internal RAM, known as the stack, and the specified direct address. 
The stack pointer special-function register (SP) contains the address in RAM where data 
from the source address will be PUSHed, or where data to be POPed to the destination 
address is found. The SP register actually is used in the indirect addressing mode but 
is not named in the mnemonic. It is implied that the SP holds the indirect address when- 
ever PUSHing or POPing. Figure 3.3 shows the operation of the stack pointer as data is 
PUSHed or POPed to the stack area in internal RAM. 

A PUSH opcode copies data from the source address to the stack. SP is incremented 
by one before the data is copied to the internal RAM location contained in SP so that the 
data is stored from low addresses to high addresses in the internal RAM. The stack grows 
up in memory as it is PUSHed. Excessive PUSHing can make the stack exceed 7Fh (the 
top of internal RAM), after which point data is lost. 

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

The PUSH and POP opcodes behave as explained in the following table: 

Mnemonic Operation 

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

contained in SP 
POP add Copy the data from the internal RAM address contained in SP to add; 

decrement the SP 



FIGURE 3.3 PUSH and POP the Stack 







— Push Y — *- 

— PushX — *- 








SP + 2 


Y 


— PopY- 


♦ 


SP + 1 


X 


— Pop X - 


1 


SP 








Increment Before 
PUSHing 




Internal 
RAM 





SP 



SP - 1 



SP -2 



Decrement After 
POPing 



MOVING DATA 53 

The SP register is set to 07h when the 8051 is reset, which is the same direct address 
in internal RAM as register R7 in bank 0. The first PUSH opcode would write data to R0 
of bank 1 . The SP should be initialized by the programmer to point to an internal RAM 
address above the highest address likely to be used by the program. 

The following table shows examples of PUSH and POP opcodes: 

Mnemonic Operation 

MOV 81h,#30h Copy the immediate data 30h to the SP 

MOV R0, #0ACh Copy the immediate data ACh to R0 

PUSH OOh SP = 31h; address 31h contains the number ACh 

PUSH OOh SP = 32h; address 32h contains the number ACh 

POP 01 h SP = 3 In; register Rl now contains the number ACh 

POP 80h SP = 30h; port latch now contains the number ACh 



CAUTION 



When the SP reaches FFh it "rolls over" to OOh (R0). 

RAM ends at address 7Fh; PUSHes above 7Fh result in errors. 

The SP is usually set at addresses above the register banks. 

The SP may be PUSHed and POPed to the stack. 

Note that direct addresses, not register names, must be used for most registers. The stack 
mnemonics have no way of knowing which bank is in use. 



Data Exchanges 



MOV, PUSH, and POP opcodes all involve copying the data found in the source address to 
the destination address; the original data in the source is not changed. Exchange instruc- 
tions actually move data in two directions: from source to destination and from destination 
to source. All addressing modes except immediate may be used in the XCH (exchange) 
opcodes: 

Mnemonic Operation 

XCH A,Rr Exchange data bytes between register Rr and A 

XCH A, add Exchange data bytes between add and A 

XCH A,@Rp Exchange data bytes between A and address in Rp 

XCHD A,@Rp Exchange lower nibble between A and address in Rp 

Exchanges between A and any port location copy the data on the port pins to A, while 
the data in A is copied to the port latch. Register A is used for so many instructions that 
the XCH opcode provides a very convenient way to "save" the contents of A without the 
necessity of using a PUSH opcode and then a POP opcode. 

The following table shows examples of data moves using exchange opcodes: 

Mnemonic Operation 

XCH A,R7 Exchange bytes between register A and register R7 

XCH A,0F0h Exchange bytes between register A and register B 

XCH A,@R1 Exchange bytes between register A and address in Rl 

XCHD A,@R1 Exchange lower nibble in A and the address in Rl 



54 CHAPTER THREE 



CAUTION 



All exchanges are internal to the 8051 . 

All exchanges use register A. 

When using XCHD, the upper nibble of A and the upper nibble of the address location in Rp do 
not change. 

This section concludes the listing of the various data moving instructions; the remain- 
ing sections will concentrate on using these opcodes to write short programs. 



Example Programs 

Programming is at once a skill and an art. Just as anyone may learn to play a musical 
instrument after sufficient instruction and practice, so may anyone learn to program a 
computer. Some individuals, however, have a gift for programming that sets them apart 
from their peers with the same level of experience, just as some musicians are more tal- 
ented than their contemporaries. 

Gifted or not, you will not become adept at programming until you have written and 
rewritten many programs. The emphasis here is on practice; you can read many books on 
how to ride a bicycle, but you do not know how to ride until you do it. 

If some of the examples and problems seem trivial or without any "real-world" appli- 
cation, remember the playing of scales on a piano by a budding musician. Each example 
will be done using several methods; the best method depends upon what resource is in 
short supply. If programming time is valuable, then the best program is the one that uses 
the fewest lines of code; if either ROM or execution time is limited, then the program that 
uses the fewest code bytes is best. 

EXAMPLE PROBLEM 3.1 

Copy the byte in TCON to register R2 using at least four different methods. 

■ Method 1: Use the direct address for TCON (88h) and register R2. 

Mnemonic Operation 

MOV R2,88h Copy TCON to R2 

■ Method 2: Use the direct addresses for TCON and R2. 

Mnemonic Operation 

MOV 02h,88h Copy TCON to direct address 02h (R2) 

■ Method 3: Use Rl as a pointer to R2 and use the address of TCON. 

Mnemonic Operation 

MOV Rl,#02h UseRl as a pointer to R2 

MOV @RI ,88h Copy TCON byte to address in RI (02h = R2) 

■ Method 4: Push the contents of TCON into direct address 02h (R2). 

Mnemonic Operation 

MOV8ih,#0lh Set the SP to address Olh in RAM 

PUSH 88h Push TCON (88h) to address 02h (R2) 



□ 



□ 



□ 



MOVING DATA 55 

EXAMPLE PROBLEM 3.2 

Set timer TO to an initial setting of 1234h. 

■ Method 1: Use the direct address with an immediate number to set THO and TLO. 

Mnemonic Operation 

MOV 8Ch,#12h Set THO to 12h 

MOV 8Ah,#34h Set TLO to 34h 

Totals: 6 bytes, 2 lines 

* Method 2: Use indirect addressing with RO for TLO and Rl for THO. 

Mnemonic Operation 

MOV R0,#8Ah Copy 8Ah, the direct address of TLO, to RO 

MOV Rl ,#8Ch Copy 8Ch, the direct address of THO, to Rl 

MOV @R0,#34h Copy 34h to TLO 
MOV @R 1 , # 1 2h Copy 1 2h to THO 

Totals: 8 bytes, 4 lines 

The first method is also the better method in this example. 



EXAMPLE PROBLEM 3.3 

Put the number 34h in registers R5, R6, and R7. 

■ Method 1: Use an immediate number and register addressing. 

Mnemonic Operation 

MOV R5,#34h Copy 34h to R5 

MOV R6,#34h Copy 34h to R6 

MOV R7,#34h Copy 34h to R7 

Totals: 6 bytes, 3 lines 

■ Method 2: Since the number is the same for each register, put the number in A and 
MOV A to each register. 

Mnemonic Operation 

MOV A,#34h Copy a 34h to A 

MOV R5,A Copy A to R5 

MOV R6.A Copy A to R6 

MOV R7,A Copy A to R7 

Totals: 5 bytes, 4 lines 

■ Method 3: Copy one direct address to another. 

Mnemonic Operation 

MOV R5,#34h Copy 34h to register R5 

MOV 06h,05h Copy R5 (add 05) to R6 (add 06) 

MOV 07h,06h Copy R6 to R7 

Totals: 8 bytes, 3 lines 



56 CHAPTER THREE 



□ 



EXAMPLE PROBLEM 3.4 

Put the number 8Dh in RAM locations 30h to 34h. 

■ Method 1: Use the immediate number to a direct address: 

Mnemonic Operation 

MOV 30h,#8Dh Copy the number 8Dh to RAM address 30h 

MOV 31h,#8Dh Copy the number 8Dh to RAM address 31 h 

MOV 32h,#8Dh Copy the number 8Dh to RAM address 32h 

MOV 33h,#8Dh Copy the number 8Dh to RAM address 33h 

MOV 34h,#8Dh Copy the number 8Dh to RAM address 34h 
Totals: 15 bytes, 5 lines 

■ Method 2: Using the immediate number in each instruction uses bytes; use a register to 
hold the number: 

M nemonic Operation 

MOV A,#8Dh Copy the number 8Dh to the A register 

MOV 30h,A Copy the contents of A to RAM location 30h 

MOV 3 In, A Copy the contents of A to the remaining addresses 

MOV 32h,A 

MOV 33h,A 

MOV 34h,A Totals: 12 bytes, 6 lines 

■ Method 3: There must be a way to avoid naming each address; the PUSH opcode can 
increment to each address: 

Mnemonic Operation 

MOV 30h,#8Dh Copy the number 8Dh to RAM address 30h 

MOV 81h,#30h Set the SP to 30h 

PUSH 30h Push the contents of 30h ( = 8Dh) to address 31h 

PUSH 30h Continue pushing to address 34h 

PUSH 30h 

PUSH 30h Totals: 14 bytes, 6 tines 



Summary 



£>— COMMENT 



Indirect addressing with the number in A and the indirect address in R1 could be done; how- 
ever, Rl would have to be loaded with each address from 30h to 34h. Loading Rl would take 
a total of 17 bytes and 1 1 lines of code. Indirect addressing is advantageous when we have 
opcodes that can change the contents of the pointing registers automatically. 



The opcodes that move data between locations within the 8051 and between the 8051 and 
external memory have been discussed. The general form and results of these instructions 
are as follows. 

Instruction Type Result 

MOV destination, source Copy data from the internal RAM source address to the 

internal RAM destination address 



MOVING DATA 57 

MOVC A, source Copy internal or external program memory byte from the 

source to register A 
MOVX destination, source Copy byte to or from external RAM to register A 
PUSH source Copy byte to internal RAM stack from internal RAM 

source 
POP destination Copy byte from internal RAM stack to internal RAM 

destination 
XCH A, source Exchange data between register A and the internal RAM 

source 
XCHD A, source Exchange lower nibble between register A and the 

internal RAM source 

There are four addressing modes: an immediate number, a register name, a direct 
internal RAM address, and an indirect address contained in a register. 



Problems 

Write programs that will accomplish the desired tasks listed below, using as few lines of 
code as possible. Use only opcodes that have been covered up to this chapter. Comment 
on each line of code. 

1. Place the number 3Bh in internal RAM locations 30h to 32h. 

2. Copy the data at internal RAM location Flh to RO and R3. 

3. Set the SP at the byte address just above the last working register address. 

4. Exchange the contents of the SP and the PSW. 

5. Copy the byte at internal RAM address 27h to external RAM address 27h. 

6. Set Timer 1 to A23Dh. 

7. Copy the contents of DPTR to registers RO (DPL) and Rl (DPH). 

8. Copy the data in external RAM location 0123h to TLO and the data in external RAM 
location 0234h to THO. 

9. Copy the data in internal RAM locations 12h to I5h to internal RAM locations 20h to 
23h: Copy 12h to 20h. 13h to 2Ih, etc. 

10. Set the SP register to 07h and PUSH the SP register on the stack; predict what number is 
PUSHed to address 08h. 

11. Exchange the contents of the B register and external RAM address 02CFh. 

12. Rotate the bytes in registers RO to R3; copy the data in RO to Rl, Rl to R2, R2 to R3, 
and R3 to RO. 

13. Copy the external code byte at address 007Dh to the SP. 

14. Copy the data in register R5 to external RAM address 032Fh. 

15. Copy the internal code byte at address 0300h to external RAM address 0300h. 
US. Swap the bytes in timer 0; put TLO in THO and THO in TLO. 

17. Store DPTR in external RAM locations OI23h (DPL) and 02BCh (DPH). 

18. Exchange both low nibbles of registers RO and Rl; put the low nibble of RO in Rl, and 
the low nibble of Rl in RO. 



58 CHAPTER THREE 



19. Store the contents of register R3 at the internal RAM address contained in R2. (Be sure 
the address in R2 is legal.) 

20. Store the contents of RAM location 20h at the address contained in RAM location 08h. 

21. Store register A at the internal RAM location address in register A. 

22. Copy program bytes OlOOh to 0I02h to internal RAM locations 20h to 22h. 

23. Copy the data on the pins of port 2 to the port 2 latch. 

24. PUSH the contents of the B register to TMOD. 

25. Copy the contents of external code memory address 0040h to IE. 

26. Show that a set of XCH instructions executes faster than a PUSH and POP when saving 
the contents of the A register. 




Logical Operations 



Chapter Outline 

Introduction 

Byte-Level Logical Operations 

Bit-Level Logical Operations 



Rotate and Swap Operations 
Example Programs 
Summary 



Introduction 



One application area the 805 1 is designed to fill is that of machine control . A large part of 
machine control concerns sensing the on-off states of external switches, making deci- 
sions based on the switch states, and then turning external circuits on or off. 

Single point sensing and control implies a need for byte and bit opcodes that operate 
on data using Boolean operators. All 8051 RAM areas, both data and SFRs, may be ma- 
nipulated using byte opcodes. Many of the SFRs, and a unique internal RAM area that is 
bit addressable, may be operated upon at the individual bit level. Bit operators are notably 
efficient when speed of response is needed. Bit operators yield compact program code that 
enhances program execution speed. 

The two data levels, byte or bit, at which the Boolean instructions operate are shown 
in the following table: 

BOOLEAN OPERATOR 8051 MNEMONIC 



AND 
OR 
XOR 
NOT 



ANL (AND logical) 
ORL (OR logical) 
XRL (exclusive OR logical) 
CPL (complement) 



There are also rotate opcodes that operate only on a byte, or a byte and the carry flag, 
to permit limited 8- and 9-bit shift-register operations. The following table shows the 
rotate opcodes: 



59 



60 



CHAPTER FOUR 



Mnemonic 
RL 

RLC 

RR 
RRC 

SWAP 



Operation 

Rotate a byte to the left; the Most Significant Bit (MSB) becomes the 

Least Significant Bit (LSB) 
Rotate a byte and the carry bit left; the carry becomes the LSB, the 

MSB becomes the carry 
Rotate a byte to the right; the LSB becomes the MSB 
Rotate a byte and the carry to the right; the LSB becomes the carry, and 

the carry the MSB 
Exchange the low and high nibbles in a byte 



Byte-Level Logical Operations 



The byte-level logical operations use all four addressing modes for the source of a data 
byte. The A register or a direct address in internal RAM is the destination of the logical 
operation result. 

Keep in mind that all such operations are done using each individual bit of the desti- 
nation and source bytes. These operations, called byte-level Boolean operations because 
trie entire byte is affected, are listed in the following table: 



Mnemonic Operation 

ANL A,#n AND each bit of A with the same bit of immediate number n; put the 

results in A 
ANL A, add AND each bit of A with the same bit of the direct RAM address; put 

the results in A 
ANL A,Rr AND each bit of A with the same bit of register Rr; put the results in A 

ANL A,@Rp AND each bit of A with the same bit of the contents of the RAM 

address contained in Rp; put the results in A 
ANL add, A AND each bit of A with the direct RAM address; put the results in 

the direct RAM address 
ANL add,#n AND each bit of the RAM address with the same bit in the number n; 

put the result in the RAM address 
ORL A,#n OR each bit of A with the same bit of n; put the results in A 

ORL A, add OR each bit of A with the same bit of the direct RAM address; put 

the results in A 
ORL A,Rr OR each bit of A with the same bit of register Rr; put the results in A 

ORL A,@Rp OR each bit of A with the same bit of the contents of the RAM 

address contained in Rp; put the results in A 
ORL add, A OR each bit of A with the direct RAM address; put the results in the 

direct RAM address 
ORL add,#n OR each bit of the RAM address with the same bit in the number n; 

put the result in the RAM address 
XRL A,#n XOR each bit of A with the same bit of n; put the results in A 

XRL A, add XOR each bit of A with the same bit of the direct RAM address; put 

the results in A 
XRL A,Rr XOR each bit of A with the same bit of register Rr; put the results in A 

XRL A,@Rp XOR each bit of A with the same bit of the contents of the RAM 

address contained in Rp; put the results in A 
XRL add, A XOR each bit of A with the direct RAM address; put the results in the 

direct RAM address 



LOGICAL OPERATIONS 61 

XRL add,#n XOR each bit of the RAM address with the same bit in the number n; 

put the result in the RAM address 
CLR A Clear each bit of the A register to zero 

CPL A Complement each bit of A; every l becomes a 0, and each becomes 

a 1 

Note that no flags are affected unless the direct RAM address is the PSW. 

Many of these byte-level operations use a direct address, which can include the port 
SFR addresses, as a destination. The normal source of data from a port is the port pins; the 
normal destination for port data is the port latch. When the destination of a logical opera- 
tion is the direct address of a port, the latch register, not the pins, is used both as the 
source for the original data and then the destination for the altered byte of data. Any port 
operation that must first read the source data, logically operate on it, and then write it 
back to the source (now the destination) must use the latch. Logical operations that use the 
port as a source, but not as a destination, use the pins of the port as the source of the data. 

For example, the port latch contains FFh, but the pins are all driving transistor 
bases and are close to ground level. The logical operation 

ANL P0,#0Fh 

which is designed to turn the upper nibble transistors off, reads FFh from the latch, ANDs 
it with OFh to produce OFh as a result, and then writes it back to the latch to turn these 
transistors off. Reading the pins produces the result OOh, turning all transistors off, in 
error. But, the operation 

ANL A,P0 

produces A = OOh by using the port pin data, which is OOh. 

The following table shows byte-level logical operation examples: 

Mnemonic Operation 

MOV A,#0FFh A - FFh 

MOV R0,#77h R0 = 77h 

ANL A,R0 A = 77h 

MOV 15h,A !5h = 77h 

CPL A A = 88h 

ORL 15h,#88h 15h = FFh 

XRL A,15h A - 77h 

XRL A,R0 A = OOh 

ANLA,15h A = OOh 

ORL A,R0 A = 77h 

CLR A A = OOh 

XRL l5h,A 15h = FFh 

XRL A.RO A = 77h 

Note that instructions that can use the SFR port latches as destinations are ANL, ORL, 
and XRL. 

CAUTION 

If the direct address destination is one of the port SFRs, the data latched in the SFR, not the pin 
data, is used. 

No flags are affected unless the direct address is the PSW. 

Only internal RAM or SFRs may be logically manipulated. 



62 CHAPTER FOUR 



Bit-Level Logical Operations 



Certain internal RAM and SFRs can be addressed by their byte addresses or by the address 
of each bit within a byte. Bit addressing is very convenient when you wish to alter a single 
bit of a byte, in a control register for instance, without having to wonder what you need to 
do to avoid altering some other crucial bit of the same byte. The assembler can also equate 
bit addresses to labels that make the program more readable. For example, bit 4 of TCON 
can become TRO, a label for the timer run bit. 

The ability to operate on individual bits creates the need for an area of RAM that 
contains data addresses that hold a single bit. Internal RAM byte addresses 20h to 2Fh 
serve this need and are both byte and bit addressable. The bit addresses are numbered 
from OOh to 7Fh to represent the 128d bit addresses (16d bytes x 8 bits) that exist from 
byte addresses 20h to 2Fh. Bit of byte address 20h is bit address OOh, and bit 7 of byte 
address 2Fh is bit address 7Fh. You must know your bits from your bytes to take advan- 
tage of this RAM area. 

Internal RAM Bit Addresses 

The availability of individual bit addresses in internal RAM makes the use of the RAM 
very efficient when storing bit information. Whole bytes do not have to be used up to store 
one or two bits of data. 

The correspondence between byte and bit addresses are shown in the following table: 



BYTE ADDRESS (HEX) 


BIT ADDRESSES (HEX) 


20 


00-07 


21 


08-OF 


22 


10-17 


23 


IS— IF 


24 


20-27 


25 


28-2F 


26 


30-37 


27 


38-3F 


28 


40-47 


29 


48-4F 


2A 


50-57 


2B 


58-5F 


2C 


60-67 


2D 


68- 6F 


2E 


70-77 


2F 


78-7F 



Interpolation of this table shows, for example, the address of bit 3 of internal RAM byte 
address 2Ch is 63h, the bit address of bit 5 of RAM address 21h is ODh, and bit address 
47h is bit 7 of RAM byte address 28h. 

SFR Bit Addresses 

All SFRs may be addressed at the byte level by using the direct address assigned to it, but 
not all of the SFRs are addressable at the bit level. The SFRs that are also bit addressable 
form the bit address by using the five most significant bits of the direct address for that 
SFR, together with the three least significant bits that identify the bit position from posi- 
tion (LSB) to 7 (MSB). 



LOGICAL OPERATIONS 63 

The bit-addressable SFR and the corresponding bit addresses are as follows: 



SFR 


DIRECT ADDRESS (HEX) 


BIT ADDRESSES (HEX) 


A 


0E0 


0E0-0E7 


B 


0F0 


0F0-0F7 


IE 


0A8 


0A8-0AF 


IP 


0B8 


0B8-0BF 


PO 


80 


80-87 


PI 


90 


90-97 


P2 


0A0 


0A0-0A7 


P3 


0B0 


0B0-0B7 


PSW 


0D0 


0D0-0D7 


TCON 


88 


88-8F 


SCON 


98 


98-9F 



The patterns in this table show the direct addresses assigned to the SFR bytes all have 
bits 0-3 equal to zero so that the address of the byte is also the address of the LSB. For 
example, bit 0E3h is bit 3 of the A register. The carry flag, which is bit 7 of the PSW, is 
bit addressable as 0D7h. The assembler can also "understand" more descriptive mne- 
monics, such as P0.5 for bit 5 of port 0, which is more formally addressed as 85h. 

Figure 4.1 shows all the bit-addressable SFRs and the function of each addressable 
bit. (Refer to Chapter 2 for more detailed descriptions of the SFR bit functions.) 

Bit-Level Boolean Operations 

The bit-level Boolean logical opcodes operate on any addressable RAM or SFR bit. 
The carry flag (C) in the PSW special -function register is the destination for most of the 
opcodes because the flag can be tested and the program flow changed using instructions 
covered in Chapter 6. 

The following table lists the Boolean bit-level operations. 

Mnemonic Operation 

ANL C,b AND C and the addressed bit; put the result in C 

ANL C,/b AND C and the complement of the addressed bit; put the result in C; the 

addressed bit is not altered 

ORL C,b OR C and the addressed bit; put the result in C 

ORL C,/b OR C and the complement of the addressed bit; put the result in C; the 

addressed bit is not altered 

CPL C Complement the C flag 

CPL b Complement the addressed bit 

CLR C Clear the C flag to zero 

CLR b Clear the addressed bit to zero 

MOV C,b Copy the addressed bit to the C flag 

MOV b,C Copy the C flag to the addressed bit 

SETB C Set the flag to one 

SETB b Set the addressed bit to one 

Note that no flags, other than the C flag, are affected, unless the flag is an addressed bit. 
As is the case for byte-logical operations when addressing ports as destinations, a 
port bit used as a destination for a logical operation is part of the SFR latch, not the pin. A 
port bit used as a source only is a pin, not the latch. The bit instructions that can use 
a SFR latch bit are: CLR, CPL, MOV, and SETB. 



64 



CHAPTER FOUR 



FIGURES 4.1 Bit-Addressable Control Registers 



7 


6 


5 


4 


3 


2 


1 





CY 


AC 


FO 


RSI 


RSO 


OV 


Reserved 


P 



PROGRAM STATUS WORD (PSW) SPECIAL FUNCTION REGISTER. BIT ADDRESSES DOh to D7h. 

Bit Function 



7 


Carry flag 


6 


Auxiliary carry flag 


5 


User flag 


4 


Register bank select bit 1 


3 


Register bank select bit 


2 


Overflow flag 


1 


Not used (reserved for future) 





Parity flag 



7 


6 


5 


4 


3 


2 


1 





EA 


Reserved 


Reserved 


ES 


ET1 


EX1 


ETO 


EXO 



INTERRUPT ENABLE (IE) SPECIAL FUNCTION REGISTER. BIT ADDRESSES A8h TO AFh. 

Bit Function 

7 Disables all interrupts 

6 Not used (reserved for future) 

5 Not used (reserved for future) 

4 Serial port interrupt enable 

3 Timer 1 overflow interrupt enable 

2 External interrupt 1 enable 

1 Timer interrupt enable 

External interrupt enable 

EA disables all interrupts when cleared to 0; if EA = 1 then each individual interrupt wilt be enabled if 1, and 
disabled if 0. 



7 


6 


5 


4 


3 


2 


1 





* 


* 


Reserved 


PS 


PT1 


PX1 


PTO 


PXO 



INTERRUPT PRIORITY (IP) SPECIAL FUNCTION REGISTER. BIT ADDRESSES B8h to BFh. 

Bit Function 

7 Not implemented 

6 Not implemented 



Continued 



LOGICAL OPERATIONS 



65 



Bit Function 

5 Not used (reserved for future) 

4 Serial port interrupt priority 

3 Timer 1 interrupt priority 

2 External interrupt 1 priority 

1 Timer interrupt priority 

External interrupt priority 



The priority bit may be set to 1 (highest) or (lowest). 



7 


6 


5 


4 


3 


2 


1 





TF1 


TR1 


TFO 


TRO 


IE1 


IT1 


IEO 


ITO 



TIMER/COUNTER CONTROL (TCON) SPECIAL FUNCTION REGISTER. BIT ADDRESSES 88h to 8Fh. 

Bit Function 

7 Timer 1 overflow flag 

6 Timer run control 

5 Timer overflow flag 

4 Timer run control 

3 External interrupt 1 edge flag 

2 External interrupt 1 mode control 

1 External interrupt edge flag 

External interrupt mode control 

Alt flags can be set by the indicated hardware action; the flags are cleared when interrupt is serviced by 
the processor. 



7 


6 


5 


4 


3 


2 


1 





SMO 


SMI 


SM2 


REN 


TB8 


RB8 


Tl 


Rl 



SERIAL PORT CONTROL (SCON) SPECIAL FUNCTION REGISTER. BIT ADDRESSES 98h to 9Fh. 

Bit Function 

7 Serial port mode bit 

6 Serial port mode bit 1 

5 Multiprocessor communications enable 

4 Receive enable 

3 Transmitted bit in modes 2 and 3 

2 Received bit in modes 2 and 3 

1 Transmit interrupt flag 

Receive interrupt flag 



66 



CHAPTER FOUR 



Bit-level logical operation examples are shown in the following table: 



Mnemonic Operation 

SETB OOh Bit of RAM byte 20h = 1 

MOV C.OOh C = 1 

MOV 7Fh,C Bit 7 of RAM byte 2Fh - 1 

ANL C,/00h C = 0; bit of RAM byte 20h = f 

ORL C.OOh C = 1 

CPL 7Fh Bit 7 of RAM byte 2Fh - 

CLR C C - 

ORL C,/7Fh C = t ; bit 7 of RAM byte 2Fh = 



-p>— CAUTION 



Only the SFRs that have been identified as bit addressable may be used in bit operations. 
If the destination bit is a port bit, the SFR latch bit is affected, not the pin. 
ANL C,/b and ORL C,/b do not alter the addressed bit b. 



Rotate and Swap Operations 



The ability to rotate data is useful for inspecting bits of a byte without using individual bit 
opcodes. The A register can be rotated one bit position to the left or right with or without 
including the C Mag in the rotation. If the C flag is not included, then the rotation involves 
the eight bits of the A register. If the C flag is included, then nine bits are involved in the 
rotation. Including the C flag enables the programmer to construct rotate operations in- 
volving any number of bytes. 

The SWAP instruction can be thought of as a rotation of nibbles in the A register. 
Figure 4.2 diagrams the rotate and swap operations, which are given in the following table: 



Mnemonic 

RL A 

RLC A 

RR A 
RRC A 

SWAP A 



Operation 

Rotate the A register one bit position to the left; bit A0 to bit Al, Al to 
A2, A2 to A3, A3 to A4, A4 to A5, A5 to A6. A6 to A7, and A7 to A0 

Rotate the A register and the carry flag, as a ninth bit, one bit position to 
the left; bit A0 to bit Al , Al to A2, A2 to A3, A3 to A4, A4 to A5, 
A5 to A6, A6 to A7, A7 to the carry flag, and the carry flag to A0 

Rotate the A register one bit position to the right; bit A0 to bit A7, A6 to 
A5, A5 to A4, A4 to A3, A3 to A2, A2 to Al, and At to A0 

Rotate the A register and the carry flag, as a ninth bit, one bit position to 
the right; bit A0 to the carry flag, carry flag to A7, A7 to A6, A6 to 
A5, A5 to A4, A4 to A3, A3 to A2, A2 to Al , and Al to A0 

Interchange the nibbles of register A; put the high nibble in the low nibble 
position and the low nibble in the high nibble position 



Note that no flags, other than the carry flag in RRC and RLC, are affected. If the carry is 
used as part of a rotate instruction, the state of the carry flag should be known before the 
rotate is done. 



FIGURE 4.2 Register A Rotate Operations 



RLA 



LOGICAL OPERATIONS 67 





7 6 5 4 3 2 1 































C 


7 6 5 4 3 2 10 




*— -*- -- -*" ■*- H" "*- "*■ -*— ' 



Carry Flag 



RLCA 



LP 



6 5 4 3 2 1 



RRA 





7 6 5 4 3 2 10 




C 

































RRCA 



Carry Flag 



7 


6 5 4 


3 2 


1 





High Nibble 


Low Nibble 




1 . 









SWAP A 



The following table shows examples of rotate and swap operations: 



Mnemonic 


Operation 




MOV A,#0A5h 


A = 10100101b = A5h 




RR A 


A = 11010010b = D2h 




RR A 


A = 01101001b = 69h 




RRA 


A = 101 10100b = B4h 




RR A 


A = 01011010b = 5Ah 




SWAP A 


A = 10100101b - A5h 




CLRC 


C = 0; A = 10100101b = 


A5h 


RRCA 


C = 1; A = 01010010b - 


52h 


RRCA 


C = 0; A = 10101001b - 


A9h 


RLA 


A = 01010011b = 53h 




RLA 


A = 101001 10b = A6h 





68 CHAPTER FOUR 



SWAP A C = 0; A = 01101010b = 6Ah 

RLC A C = 0; A = 1 1010100b = D4h 

RLC A C = 1; A = 10101000b = A8h 

SWAP A C - 1; A - 10001010b = 8Ah 



CAUTION 



Know the state of the carry flag when using RRC or RRL 
Rotation and swap operations are limited to the A register. 



Example Programs 



□ 



The programs in this section are written using only opcodes covered to this point in the 
text. The challenge is to minimize the number of lines of code. 

EXAMPLE PROBLEM 4.1 

Double the number in register R2, and put the result in registers R3 (high byte) and R4 
(low byte). 

■ Thoughts on the Problem The largest number in R2 is FFh; the largest result is lFEh. 
There are at least three ways to solve this problem: Use the MUL instruction (multiply, 
covered in Chapter 5). add R2 to itself, or shift R2 left one time. The solution that shifts 
R2 left is as follows: 

Mnemonic Operation 

MOV R3,#00h Clear R3 to receive high byte 

CLR C Clear the carry to receive high bit of 2 x R2 

MOV A.R2 Get R2 to A 

RLC A Rotate left, which doubles the number in A 

MOV R4,A Put low byte of result in R4 

CLR A Clear A to receive carry 

RLC A The carry bit is now bit of A 

MOV R3,A Transfer any carry bit to R3 



:£>— COMMENT 



□ 



Note how the carry flag has to be cleared to a known state before being used in a rotate 
operation. 

EXAMPLE PROBLEM 4.2 

OR the contents of ports I and 2; put the result in external RAM location OlOOh. 

■ Thoughts on the Problem The ports should be input ports for this problem to make any 
physical sense; otherwise, we would not know whether to use the pin data or the port SFR 
latch data. 

The solution is as follows: 

Mnemonic Operation 

MOV A,90h Copy the pin data from port 1 to A 

ORL A.OAOh OR the contents of A with port 2; results in A 

MOV DPTR,#0l00h Set the DPTR to point to external RAM address 

MOVX (o)DPTR,A Store the result 



LOGICAL OPERATIONS 69 



£>— COMMENT 



□ 



Any time the port is the source of data, the pin levels are read; when the port is the destination, 
the latch is written. If the port is both source and destination (read-modify-write instruc- 
tions), then the latch is used. 

EXAMPLE PROBLEM 4.3 

Find a number that, when XORed to the A register, results in the number 3Fh in A. 
■ Thoughts on the Problem Any number can be in A, so we will work backwards: 

3Fh = A XOR N A XOR 3Fh - A XOR A XOR N - N 
The solution is as follows: 

Mnemonic Operation 

MOV RO,A Save A in RO 

XOR A,#3Fh XOR A and 3Fh; forming N 

XOR A,R0 XOR A and N yielding 3Fh 



Summary 



£>— COMMENT 



Does this program work? Let's try several A's and see. 

A = FFh A XOR 3Fh = COh COh XOR FFh - 3Fh 

A = OOh A XOR 3Fh = 3Fh 3Fh XOR OOh = 3Fh 

A = 5Ah A XOR 3Fh = 65h 65h XOR 5Ah = 3Fh 



Boolean logic, rotate, and swap instructions are covered in this chapter. Byte-level opera- 
tions involve each individual bit of a source byte operating on the same bit position in the 
destination byte; the results are put in the destination, while the source is not changed: 

ANL destination, source 

ORL destination, source 

XRL destination, source 

CLR A 

CPL A 

RR A 

RLA 

RRC A 

RLC A 

SWAP A 

Bit-level operations involve individual bits found in one area of internal RAM and 
certain SFRs that may be addressed both by the assigned direct-byte address and eight 
individual bit addresses. The following Boolean logical operations may be done on each 
of these addressable bits: 

ANL bit 
ORL bit 



70 CHAPTER FOUR 



CLR bit 

CPL bit 

SETB bit 

MOV destination bit, source bit 

Problems 

Write programs that perform the tasks listed using only opcodes that have been discussed 
in this and previous chapters. Write comments for each line of code and try to use as few 
lines as possible. 

1. Set Port 0, bits 1 ,3,5, and 7, to one; set the rest to zero. 

2. Clear bit 3 of RAM location 22h without affecting any other bit. 

3. Invert the data on the port pins and write the data to port 1 . 

4. Swap the nibbles of R0 and Rl so that the low nibble of R0 swaps with the high nibble 
of Rl and the high nibble of R0 swaps with the low nibble of Rl . 

5. Complement the lower nibble of RAM location 2Ah. 

6. Make the low nibble of R5 the complement of the high nibble of R6. 

7. Make the high nibble of R5 the complement of the low nibble of R6. 

8. Move bit 6 of R0 to bit 3 of port 3. 

9. Move bit 4 of RAM location 30h to bit 2 of A. 

10. XOR a number with whatever is in A so that the result is FFh. 

1 1 . Store the most significant nibble of A in both nibbles of register R5; for example, if 
A = B6h. then R5 = BBh. 

12. Store the least significant nibble of A in both nibbles of RAM address 3Ch; for example, 
if A = 36h, then3Ch = 66h. 

13. Set the carry flag to one if the number in A is even; set the carry flag to zero if the 
number in A is odd. 

14. Treat registers RO and Rl as 16-bit registers, and rotate them one place to the left; bit 7 
of RO becomes bit of R 1 . bit 7 of R I becomes bit of RO, and so on . 

15. Repeat Problem 14 but rotate the registers one place to the right. 

16. Rotate the DPTR one place to the left; bit 15 becomes bit 0. 

17. Repeat problem 16 but rotate the DPTR one place to the right. 

18. Shift register B one place to the left; bit becomes a zero, bit 6 becomes bit 7. and so 
on. Bit 7 is lost. 




Arithmetic Operations 



Chapter Outline 

Introduction 

Flags 

Incrementing and Decrementing 

Addition 

Subtraction 



Multiplication and Division 
Decimal Arithmetic 
Example Programs 
Summary 



Introduction 



Applications of microcontrollers often involve performing mathematical calculations on 
data in order to alter program flow and modify program actions. A microcontroller is not 
designed to be a "number cruncher," as is a genera) -purpose computer. The domain of the 
microcontroller is that of controlling events as they change (real-time control). A suffi- 
cient number of mathematical opcodes must be provided, however, so that calculations 
associated with the control of simple processes can be done, in real time, as the controlled 
system operates. When faced with a control problem, the programmer must know whether 
the 8051 has sufficient capability to expeditiously handle the required data manipulation. 
If it does not, a higher performance model must be chosen. 

The 24 arithmetic opcodes are grouped into the following types: 



Mnemonic 

INC destination 

DEC destination 

ADD/ADDC destination, source 

SUBB destination, source 
MULAB 



Operation 

Increment destination by 1 

Decrement destination by 1 

Add source to destination without/with carry (C) 

flag 
Subtract, with carry, source from destination 
Multiply the contents of registers A and B 



71 



72 CHAPTER FIVE 



Flags 



DIV AB Divide the contents of register A by the contents of 

register B 
DA A Decimal Adjust the A register 

The addressing modes for the destination and source are the same as those discussed in 
Chapter 3: immediate, register, direct, and indirect. 



A key part of performing arithmetic operations is the ability to store certain results of 
those operations that affect the way in which the program operates. For example, adding 
together two one-byte numbers results in a one-byte partial sum, because the 8051 is and 
eight-bit machine. But it is possible to get a 9-bit result when adding two 8-bit numbers. 
The ninth bit must be stored also, so the need for a one-bit register, or carry flag in this 
case, is identified. The program will then have to deal with the ninth bit, perhaps by 
adding it to a higher order byte in a multiple-byte addition scheme. Similar actions may 
have to be taken when a larger byte is subtracted from a smaller one. In this case, a borrow 
is necessary and must be dealt with by the program. 

The 8051 has several dedicated latches, or flags, that store results of arithmetic opera- 
tions. Opcodes covered in Chapter 6 are available to alter program flow based upon the 
state of the flags. Not alt instructions change the flags, but many a programming error has 
been made by a forgetful programmer who overlooked an instruction that does change 
a flag. 

The 805 1 has four arithmetic flags: the carry (C), auxiliary carry (AC), overflow (OV), 
and parity (P). 

Instructions Affecting Flags 

The C, AC, and OV flags are arithmetic flags. They are set to 1 or cleared to automat- 
ically, depending upon the outcomes of the following instructions. The following instruc- 
tion set includes all instructions that modify the flags and is not confined to arithmetic 
instructions: 



INSTRUCTION MNEMONIC 


FLAGS AF 


FECTI 


ADD 


C AC 


OV 


ADDC 


C AC 


OV 


ANL Cdirect 


C 




CJNE 


C 




CLR C 


C = 




CPL C 


C = C 




DA A 


C 




DIV 


C =0 


OV 


MOV Cdirect 


C 




MUL 


C =0 


OV 


ORL Cdirect 


C 




RLC 


C 




RRC 


c 




SETB C 


C - 1 




SUBB 


C AC 


OV 



One should remember, however, that the flags are all stored in the PSW. Any instruc- 
tion that can modify a bit or a byte in that register (MOV, SETB, XCH, etc.) changes the 
flags. This type of change takes conscious effort on the part of the programmer. 



ARITHMETIC OPERATIONS 



73 



A flag may be used for more than one type of result. For example, the C flag indicates 
a carry out of the lower byte position during addition and indicates a borrow during sub- 
traction. The instruction that last affects a flag determines the use of that flag. 

The parity flag is affected by every instruction executed. The P flag will be set to a \ 
if the number of 1 *s in the A register is odd and will be set to if the number of 1 *s is even. 
AH O's in A yield a l's count of 0, which is considered to be even. Parity check is an 
elementary error-checking method and is particularly valuable when checking data re- 
ceived via the serial port. 



Incrementing and Decrementing 



The simplest arithmetic operations involve adding or subtracting a binary 1 and a number. 
These simple operations become very powerful when coupled with the ability to repeat the 
operation — that is, to "INCrement" or "DECrement" — until a desired result is reached.' 
Register, Direct, and Indirect addresses may be INCremented or DECremented. No math 
flags (C, AC, OV) are affected. 

The following table lists the increment and decrement mnemonics. 



Mnemonic 

INC A 

INC Rr 
INC add 
INC @ Rp 
INC DPTR 
DEC A 
DECRr 
DEC add 
DEC @ Rp 



Operation 

Add a one to the A register 

Add a one to register Rr 

Add a one to the direct address 

Add a one to the contents of the address in Rp 

Add a one to the 16-bit DPTR 

Subtract a one from register A 

Subtract a one from register Rr 

Subtract a one from the contents of the direct address 

Subtract a one from the contents of the address in register Rp 



Note that increment and decrement instructions that operate on a port direct address alter 
the latch for that port. 

The following table shows examples of increment and decrement arithmetic 
operations: 



Mnemonic 

MOV A,#3Ah 

DEC A 

MOV R0,#15h 

MOV 15h,#t2h 

INC @R0 

DEC I5h 

INCRO 

MOV 16h,A 

INC @R0 

MOVDPTR,#12FFh 

INC DPTR 

DEC 83h 



Operation 

A = 3Ah 

A = 39h 

RO = I5h 

Internal RAM address 15h = 12h 

Internal RAM address 1 5h = 1 3h 

Internal RAM address 15h = 12h 

RO = 16h 

Internal RAM address 16h = 39h 

Interna] RAM address 16h = 3 Ah 

DPTR = 12FFh 

DPTR = I300h 

DPTR = I200h (SFR 83h is the DPH byte) 



'This subject will be explored in Chapter 6. 



74 CHAPTER FIVE 



CAUTION 



Addition 



Remember: No math flags are affected. 
All 8-bit address contents overflow from FFh to OOh. 
DPTR is 16 bits; DPTR overflows from FFFFh to OOOOh. 
The 8-bit address contents underflow from OOh to FFh. 
There is no DEC DPTR to match the INC DPTR. 



All addition is done with the A register as the destination of the result. All addressing 
modes may be used for the source: an immediate number, a register, a direct address, and 
an indirect address. Some instructions include the carry flag as an additional source of a 
single bit that is included in the operation at the least significant bit position. 
The following table lists the addition mnemonics. 

Mnemonic Operation 

ADD A,#n Add A and the immediate number n; put the sum in A 

ADD A,Rr Add A and register Rr; put the sum in A 

ADD A, add Add A and the address contents; put the sum in A 

ADD A,@Rp Add A and the contents of the address in Rp; put the sum in A 

Note that the C flag is set to I if there is a carry out of bit position 7; it is cleared to 
otherwise. The AC flag is set to 1 if there is a carry out of bit position 3; it is cleared 
otherwise. The OV flag is set to I if there is a carry out of bit position 7, but not bit 
position 6 or if there is a carry out of bit position 6 but not bit position 7, which may be 
expressed as the logical operation 

OV = C7 XOR C6 

Unsigned and Signed Addition 

The programmer may decide that the numbers used in the program are to be unsigned 
numbers — that is, numbers that are 8-bit positive binary numbers ranging from OOh to 
FFh. Alternatively, the programmer may need to use both positive and negative signed 
numbers. 

Signed numbers use bit 7 as a sign bit in the most significant byte (MSB) of the group 
of bytes chosen by the programmer to represent the largest number to be needed by the 
program. Bits to 6 of the MSB, and any other bytes, express the magnitude of the num- 
ber. Signed numbers use a 1 in bit position 7 of the MSB as a negative sign and a as a 
positive sign. Further, all negative numbers are not in true form, but are in 2's comple- 
ment form. When doing signed arithmetic, the programmer must know how large the 
largest number is to be — that is, how many bytes are needed for each number. 

In signed form, a single byte number may range in size from 10000000b, which 
is - 1 28d to 01 1 1 1 1 1 1 b, which is + 1 27d. The number 00000000b is OOOd and has a posi- 
tive sign, so there are 128d negative numbers and 128d positive numbers. The C and OV 
flags have been included in the 8051 to enable the programmer to use either numbering 
scheme. 

Adding or subtracting unsigned numbers may generate a carry flag when the sum ex- 
ceeds FFh or a borrow flag when the minuend is less than the subtrahend. The OV flag is 
not used for unsigned addition and subtraction. Adding or subtracting signed numbers can 



ARITHMETIC OPERATIONS 75 

lead to carries and borrows in a similar manner, and to overflow conditions due to the 
actions of the sign bits. 

Unsigned Addition 

Unsigned numbers make use of the carry flag to detect when the result of an ADD opera- 
tion is a number larger than FFh. If the carry is set to one after an ADD, then the carry can 
be added to a higher order byte so that the sum is not lost. For instance, 

95d = 010J 1 1 lib 

189d = lOUUOtb 

284d 1 00011100b - 284d 

The C flag is set to 1 to account for the carry out from the sum. The program could add the 
carry flag to another byte that forms the second byte of a larger number. 

Signed Addition 

Signed numbers may be added two ways: addition of like signed numbers and addition 
of unlike signed numbers. If unlike signed numbers are added, then it is not possible 
for the result to be larger than — 128d or + 127d, and the sign of the result will always be 
correct. For example, 

-001d = lltlllllb 
+027d = 0001101 lb 

+026d 0001 1010b = +026d 

Here, there is a carry from bit 7 so the carry flag is 1 . There is also a carry from bit 6, and 
the OV flag is 0. For this condition, no action need be taken by the program to correct 
the sum. 

If positive numbers are added, there is the possibility that the sum will exceed -f I27d, 
as demonstrated in the following example; 

+100d - 01100100b 
+050d - 00110010b 

+ 150d 10010110b- -106d 

Ignoring the sign of the result, the magnitude is seen to be +22d which would be correct if 
we had some way of accounting for the + I28d, which, unfortunately, is larger than a 
single byte can hold. There is no carry from bit 7 and the carry flag is 0; there is a carry 
from bit 6 so the OV flag is 1 . 

An example of adding two positive numbers that do not exceed the positive limit is: 

+045d = 00101 101b 
+075d= 01001011b 

+ 120d 011 11000b = 120d 

Note that there are no carries from bits 6 or 7 of the sum; the carry and OV flags are 
bothO. 

The result of adding two negative numbers together for a sum that does not exceed the 
negative limit is shown in this example: 

-030d = lUOOOlOb 
-050d = 1 1001 1 10b 

-080d 101 10000b = -080d 



76 CHAPTER FIVE 



c 


ov 











1 


1 





1 


1 



Here, there is a carry from bit 7 and the carry flag is 1 ; there is a carry from bit 6 and the 
OV flag is 0. These are the same flags as the case for adding unlike numbers; no correc- 
tions are needed for the sum. 

When adding two negative numbers whose sum does exceed — I28d, we have 

-070d = lOlMOlOb 
-070d = 101 11010b 

-140d OlllOlOOb^ +116d 

Or, the magnitude can be interpreted as — 1 2d, which is the remainder after a carry out of 
— 1 28d. In this example, there is a carry from bit position 7, and no carry from bit position 
6, so the carry and the OV flags are set to 1 . The magnitude of the sum is correct; the sign 
bit must be changed to a 1 . 

From these examples the programming actions needed for the C and OV flags are as 
follows: 

FLAGS ACTION 



None 

Complement the sign 

None 

Complement the sign 

A general rule is that if the OV flag is set, then complement the sign. The OV flag also 
signals that the sum exceeds the largest positive or negative numbers thought to be needed 
in the program. 

Multiple-Byte Signed Arithmetic 

The nature of multiple-byte arithmetic for signed and unsigned numbers is distinctly 
different from single byte arithmetic. Using more than one byte in unsigned arithmetic 
means that carries or borrows are propagated from low-order to high-order bytes by the 
simple technique of adding the carry to the next highest byte for addition and subtracting 
the borrow from the next highest byte for subtraction. 

Signed numbers appear to behave like unsigned numbers until the last byte is reached. 
For a signed number, the seventh bit of the highest byte is the sign; if the sign is negative, 
then the entire number is in 2*s complement form. 

For example, using a two-byte signed number, we have the following examples: 

+ 32767d = 01111111 IIllMIlb = 7FFFh 
+00000d = 00000000 00000000b = OOOOh 
-OOOOld = 11111111 llllllllb = FFFFh 
-32768d = 10000000 00000000b = 8000h 

Note that the lowest byte of the numbers OOOOOd and -32768d are exactly alike, as are the 
lowest bytes for +32767d and -OOOOld. 

For multi-byte signed number arithmetic, then, the lower bytes are treated as un- 
signed numbers. All checks for overflow are done only for the highest order byte that 
contains the sign. An overflow at the highest order byte is not usually recoverable. The 
programmer has made a mistake and probably has made no provisions for a number larger 
than planned. Some error acknowledgment procedure, or user notification, should be in- 
cluded in the program if this type of mistake is a possibility. 



ARITHMETIC OPERATIONS 77 

The preceding examples show the need to add the carry flag to higher order bytes in 
signed and unsigned addition operations. Opcodes that accomplish this task are similar to 
the ADD mnemonics: A C is appended to show that the carry bit is added to the sum in bit 
position 0. 

The following table lists the add with carry mnemonics: 

Mnemonic Operation 

ADDC A,#n Add the contents of A, the immediate number n, and the C flag; put 

the sum in A 
ADDC A, add Add the contents of A, the direct address contents, and the C flag; 

put the sum in A 
ADDC A,Rr Add the contents of A, register Rr, and the C flag; put the sum in A 

ADDC A,@Rp Add the contents of A, the contents of the indirect address in Rp, 

and the C flag; put the sum in A 

Note that the C, AC, and OV flags behave exactly as they do for the ADD commands. 

The following table shows examples of ADD and ADDC multiple-byte signed arith- 
metic operations: 

Mnemonic Operation 

MOV A,#lCh A = ICh 

MOVR5,#0Alh R5 = Alh 

ADD A,R5 A = BDh; C = 0, OV = 

ADD A,R5 A = 5Eh; C = 1 , OV = 1 

ADDC A,#10h A = 6Fh; C = 0, OV = 

ADDC A,#10h A = 7Fh; C = 0, OV = 



£>— CAUTION 



ADDC is normally used to add a carry after the LSB addition in a multi-byte process. ADD is 
normally used for the LSB addition. 



Subtraction 



Subtraction can be done by taking the 2's complement of the number to be subtracted, the 
subtrahend, and adding it to another number, the minuend. The 8051 , however, has com- 
mands to perform direct subtraction of two signed or unsigned numbers. Register A is the 
destination address for subtraction. All four addressing modes may be used for source 
addresses. The commands treat the carry flag as a borrow and always subtract the carry 
flag as part of the operation. 

The following table lists the subtract mnemonics. 

Mnemonic Operation 

SUBB A,#n Subtract immediate number n and the C flag from A; put the result 

in A 
SUBB A, add Subtract the contents of add and the C flag from A; put the result in A 

SUBB A,Rr Subtract Rr and the C flag from A; put the result in A 

SUBB A,@Rp Subtract the contents of the address in Rp and the C flag from A; 

put the result in A 



78 CHAPTER FIVE 



Note that the C flag is set if a borrow is needed into bit 7 and reset otherwise. The AC flag 
is set if a borrow is needed into bit 3 and reset otherwise. The OV flag is set if there is a 
borrow into bit 7 and not bit 6 or if there is a borrow into bit 6 and not bit 7. As in the case 
for addition, the OV Flag is the XOR of the borrows into bit positions 7 and 6. 

Unsigned and Signed Subtraction 

Again, depending on what is needed, the programmer may choose to use bytes as signed 
or unsigned numbers. The carry flag is now thought of as a borrow flag to account for 
situations when a larger number is subtracted from a smaller number. The OV flag indi- 
cates results that must be adjusted whenever two numbers of unlike signs are subtracted 
and the result exceeds the planned signed magnitudes. 

Unsigned Subtraction 

Because the C flag is always subtracted from A along with the source byte, it must be set 
to if the programmer does not want the flag included in the subtraction. If a multi-byte 
subtraction is done, the C flag is cleared for the first byte and then included in subsequent 
higher byte operations. 

The result will be in true form, with no borrow if the source number is smaller than 
A, or in 2's complement form, with a borrow if the source is larger than A. These are not 
signed numbers, as all eight bits are used for the magnitude. The range of numbers is from 
positive 255d (C = 0, A = FFh) to negative 255d (C = 1, A = Olh). 

The following example demonstrates subtraction of larger number from a smaller 
number: 

0I5d= 00001111b 
SUBB iOOd = 01100100b 

-085d 1 1010101 lb = 17ld 

TheC flag is set to 1, and theOV flag is set to 0. The 2's complement of the result is085d. 
The reverse of the example yields the following result: 

lOOd = 01100100b 
015d = 00001111b 

085d 01010101b - 085d 
The C flag is set to 0, and the OV flag is set to 0. The magnitude of the result is in true form. 

Signed Subtraction 

As is the case for addition, two combinations of unsigned numbers are possible when sub- 
tracting: subtracting numbers of like and unlike signs. When numbers of like sign are 
subtracted, it is impossible for the result to exceed the positive or negative magnitude 
limits of + 127d or — 128d, so the magnitude and sign of the result do not need to be 
adjusted, as shown in the following example: 

+ lOOd = 01 100100b (Carry flag = before SUBB) 
SUBB +I26d = 011111 10b 

-026d I IMOOMOb = -026d 

There is a borrow into bit positions 7 and 6; the carry flag is set to 1 , and the OV flag is 
cleared. 



ARITHMETIC OPERATIONS 79 



The following example demonstrates using two negative numbers: 

-061d = 11000011b (Carry flag = before SUBB) 
SUBB -116d - 10001 100b 

+055d 001 101 lib - +55d 

There are no borrows into bit positions 6 or 7, so the OV and carry flags are cleared to zero. 
An overflow is possible when subtracting numbers of opposite sign because the situa- 
tion becomes one of adding numbers of like signs, as can be demonstrated in the following 
example: 

-099d = 1001 1 101b (Carry flag = before SUBB) 
SUBB +100d = 01100100b 

-199d 00111001b = +057d 

Here, there is a borrow into bit position 6 but not into bit position 7; the OV flag is set to 1 , 
and the carry flag is cleared to 0. Because the OV flag is set to I, the result must be 
adjusted. In this case, the magnitude can be interpreted as the 2's complement of 7 Id, the 
remainder after a carry out of I28d from 199d. The magnitude is correct, and the sign 
needs to be corrected to a 1 . 

The following example shows a positive overflow: 

+087d = 01010111b (Carry flag - before SUBB) 
SUBB -052d = llOOIIOOb 

+ 139d 1000101 lb = -117d 

There is a borrow from bit position 7, and no borrow from bit position 6; the OV flag and 
the carry flag are both set to 1 . Again the answer must be adjusted because the OV flag is 
set to one. The magnitude can be interpreted as a +01 Id, the remainder from a carry out 
of 128d. The sign must be changed to a binary and the OV condition dealt with. 

The general rule is that if the OV flag is set to 1 , then complement the sign bit. The 
OV flag also signals that the result is greater than — 128d or + 127d. 

Again, it must be emphasized: When an overflow occurs in a program, an error has 
been made in the estimation of the largest number needed to successfully operate the pro- 
gram. Theoretically, the program could resize every number used, but this extreme proce- 
dure would tend to hinder the performance of the microcontroller. 

Note that for all the examples in this section, it is assumed that the carry flag = 
before the SUBB. The carry flag must be before any SUBB operation that depends upon 
C — is done. 

The following table lists examples of SUBB multiple-byte signed arithmetic 
operations: 

Mnemonic Operation 

MOV 0D0h,#00h Carry flag - 

MOV A,#3Ah A - 3Ah 

MOV 45h,#13h Address 45h = 13h 

SUBB A,45h A = 27h; C = 0, OV = 

SUBB A,45h A = 14h; C = 0, OV = 

SUBB A,#80h A = 94h; C = 1, OV = 1 

SUBB A,#22h A = 71h; C = 0, OV = 

SUBB A,#0FFh A = 72h; C = 1, OV = 



80 CHAPTER FIVE 



£>— CAUTION 



Remember to set the carry flag to zero if it is not to be included as part of the subtraction 

operation- 



Multiplication and Division 



The 8051 has the capability to perform 8-bit integer multiplication and division using the 
A and B registers. Register B is used solely for these operations and has no other use 
except as a location in the SFR space of RAM that could be used to hold data. The 
A register holds one byte of data before a multiply or divide operation, and one of the 
result bytes after a multiply or divide operation. 

Multiplication and division treat the numbers in registers A and B as unsigned. The 
programmer must devise ways to handle signed numbers. 

Multiplication 

Multiplication operations use registers A and B as both source and destination addresses 
for the operation. The unsigned number in register A is multiplied by the unsigned number 
in register B, as indicated in the following table: 

Mnemonic Operation 

MUL AB Multiply A by B; put the low-order byte of the product in A, put the 

high-order byte in B 

The OV flag will be set if A x B > FFh. Setting the OV flag does not mean that an error 
has occurred. Rather, it signals that the number is larger than eight bits, and the program- 
mer needs to inspect register B for the high-order byte of the multiplication operation. The 
carry flag is always cleared to 0. 

The largest possible product is FEOlh when both A and B contain FFh. Register A 
contains Olh and register B contains FEh after multiplication of FFh by FFh. The OV flag 
is set to 1 to signal that register B contains the high-order byte of the product; the carry 
flag is 0. 

The following table gives examples of MUL multiple-byte arithmetic operations: 

Mnemonic Operation 

MOV A,#7Bh A - 7Bh 

MOV OFOh,#02h B = 02h 

MUL AB A = OOh and B = F6h; OV Flag = 

MOV A,#0FEh A - FEh 

MUL AB A = 14h and B = F4h; OV Flag = 1 



£>— CAUTION 



Note there is no comma between A and B in the MUL mnemonic. 

Division 

Division operations use registers A and B as both source and destination addresses for the 
operation. The unsigned number in register A is divided by the unsigned number in regis- 
ter B, as indicated in the following table: 



ARITHMETIC OPERATIONS 81 

Mnemonic Operation 

DIV AB Divide A by B; put the integer part of quotient in register A and the 

integer part of the remainder in B 

The OV flag is cleared to unless B holds OOh before the DIV. Then the OV flag is set to l 
to show division by 0. The contents of A and B, when division by is attempted, are 
undefined. The carry flag is always reset. 

Division always results in integer quotients and remainders, as shown in the following 
example: 

= 1 2 (quotient) and 9 (remainder) 



When done in hex: 



B - 017d 213 [(12 x 17) + 91 



C (quotient) and 9 (remainder) 



B = 011h 
The following table lists examples of DIV multiple-byte arithmetic operations: 

Mnemonic Operation 

MOV A,#0FFh A - FFh (255d) 

MOV 0F0h,#2Ch B = 2C (44d) 

DIV AB A = 05h and B = 23h [255d = (5 x 44) + 35] 

DIV AB A = OOh and B = 05h |05d = (0x 35) + 5] 

DIV AB A = OOh and B = OOh [OOd = (0 x 5) + 0] 

DIV AB A = ?? and B = ??; OV flag is set to one 



£>— CAUTION 



The original contents of B (the divisor) are lost. 

Note there is no comma between A and B in the DIV mnemonic. 



Decimal Arithmetic 



Most 8051 applications involve adding intelligence to machines where the hexadecimal 
numbering system works naturally. There are instances, however, when the application 
involves interacting with humans, who insist on using the decimal number system. In such 
cases, it may be more convenient for the programmer to use the decimal number system to 
represent all numbers in the program. 

Four bits are required to represent the decimal numbers from to 9 (0000 to 1001) 
and the numbers are often called Binary coded decimal (BCD) numbers. Two of these 
BCD numbers can then be packed into a single byte of data. 

The 8051 does all arithmetic operations in pure binary. When BCD numbers are being 
used the result will often be a non-BCD number, as shown in the following example: 

49BCD = 01001001b 
+ 38BCD = 00111000b 

87BCD 10000001b = 8IBCD 
Note that to adjust the answer, an 06d needs to be added to the result. 



82 CHAPTER FIVE 



The opcode that adjusts the result of BCD addition is the decimal adjust A for addi- 
tion (DA A) command, as shown in the following table: 

Mnemonic Operation 

DA A Adjust the sum of two packed BCD numbers found in A register; leave 

the adjusted number in A. 

The C flag is set to 1 if the adjusted number exceeds 99BCD and set to otherwise. The 
DA A instruction makes use of the AC flag and the binary sums of the individual binary 
nibbles to adjust the answer to BCD. The AC flag has no other use to the programmer and no 
instructions — other than a MOV or a direct bit operation to the PSW — affect the AC flag. 

It is important to remember that the DA A instruction assumes the added numbers 
were in BCD before the addition was done. Adding hexadecimal numbers and then using 
DA A will not convert the sum to BCD. 

The DA A opcode only works when used with ADD or ADDC opcodes and does not 
give correct adjustments for SUBB, MUL or DIV operations. The programmer might best 
consider the ADD or ADDC and DA A as a single instruction and use the pair automat- 
ically when doing BCD addition in the 805 1 . 

The following table gives examples of BCD multiple-byte arithmetic operations: 

Mnemonic Operation 

MOV A,#42h A = 42BCD 

ADD A,#13h A = 55h; C = 

DA A A = 55h; C = 

ADD A,#17h A = 6Ch; C = 

DA A A = 72BCD; C = 

ADDC A,#34h A - A6h; C = 

DA A A = 06BCD; C = 1 

ADDC A,#llh A = 18BCD;C = 

DA A A = 18BCD;C = 



{>^ CAUTION - 



All numbers used must be in BCD form before addition. 
Only ADD and ADDC are adjusted to BCD by DA A. 



Example Programs 



□ 



The challenge of the programs presented in this section is writing them using only opcodes 
that have been covered to this point in the book. Experienced programmers may long for 
some of the opcodes to be covered in Chapter 6, but as we shall see, programs can be 
written without them. 

EXAMPLE PROBLEM 5.1 

Add the unsigned numbers found in internal RAM locations 25h, 26h, and 27h together 
and put the result in RAM locations 30h (MSB) and 31h (LSB). 

■ Thoughts on the Problem The largest number possible is FFh + FFh -OlFEh + FFh - 
02FDh, so that two bytes will hold the largest possible number. The MSB will be set to 
and any carry bit added to it for each byte addition. 



ARITHMETIC OPERATIONS 



83 



To solve this problem, use an ADD instruction for each addition and an ADDC to the 
MSB for each carry which might be generated. The first ADD will adjust any carry flag 
which exists before the program starts. 

The complete program is shown in the following table: 



Mnemonic 

MOV31h,#00h 
MOV A,25h 
ADD A,26h 
MOV RO,A 
MOV A,#00h 
ADDC A,31h 
MOV 3 In, A 
MOV A,R0 
ADD A,27h 
MOV 39h,A 
MOV A,#00h 
ADDCA,3Ih 
MOV 31h,A 



Operation 

Clear the MSB of the result to 

Get the first byte to be added from location 25h 

Add the second byte found in RAM location 26h 

Save the sum of the first two bytes in RO 

Clear A to 00 

Add the carry to the MSB; carry = after this operation 

Store MSB 

Get partial sum back 

Form final LSB sum 

Store LSB 

Clear A for MSB addition 

Form final MSB 

Store final MSB 



COMMENT 



□ 



Notice how awkward it becomes to have to use the A register for all operations. Jump instruc- 
tions, which will be covered in Chapter 6, require less use of A. 

EXAMPLE PROBLEM 5.2 

Repeat problem 5.1 using BCD numbers. 

■ Thoughts on the Problem The numbers in the RAM locations must be in BCD before 
the problem begins. The largest number possible is 99d + 99d = 198d + 99d = 297d, so 
that up to two carries can be added to the MSB. 

The solution to this problem is identical to that for unsigned numbers, except a DA A 
must be added after each ADD instruction. If more bytes were added so that the MSB 
could exceed 09d, then a DA A would also be necessary after the ADDC opcodes. 

The complete program is shown in the following table: 



Mnemonic 

MOV 31h,#00h 
MOV A,25h 
ADD A,26h 
DA A 
MOV R0,A 
MOV A,#00h 
ADDC A,31h 
MOV 3ih,A 
MOV A,R0 
ADD A,27h 
DA A 

MOV 30h,A 
MOV A,#00h 
ADDC A,3In 
MOV 31h,A 



Operation 

Clear the MSB of the result to 

Get the first byte to be added from location 25h 

Add the second byte found in RAM location 26h 

Adjust the answer to BCD form 

Save the sum of the first two bytes in RO 

Clear A to 00 

Add the carry to the MSB; carry = after this operation 

Store MSB 

Get partial sum back 

Form final LSB sum 

Adjust the final sum to BCD 

Store LSB 

Clear A for MSB addition 

Form final MSB 

Store final MSB 



84 



CHAPTER FIVE 



COMMENT 



When using BCD numbers, DA A can best be thought of as an integral part of the ADD 
instructions. 



□ 



EXAMPLE PROBLEM 5.3 



Multiply the unsigned number in register R3 by the unsigned number on port 2 and put the 
result in external RAM locations lOh (MSB) and 1 Ih (LSB). 

■ Thoughts on the Problem The MUL instruction uses the A and B registers; the prob- 
lem consists of MOVes to A and B followed by MOVes to the external RAM. The com- 
plete program is shown in the following table: 



Mnemonic 

MOV A,0A0h 
MOV 0F0h,R3 
MUL AB 
MOV RO,#llh 
MOV @RO,A 
DEC RO 
MOV A,OFOh 
MOV <a)R0,A 



Operation 

Move the port 2 pin data to A 

Move the data in R3 to the B register 

Multiply the data; A has the low order result byte 

Set RO to point to external RAM location 1 Ih 

Store the LSB in external RAM 

Decrement RO to point to I Oh 

Move B to A 

Store the MSB in external RAM 



COMMENT 



Again we see the bottleneck created by having to use the A register for all external data 
transfers. 

More advanced programs which do signed math operations and multi-byte multiplication and 
division will have to wait for the development of Jump instructions in Chapter 6. 



Summary 



The 8051 can perform all four arithmetic operations: addition, subtraction, multiplication, 
and division. Signed and unsigned numbers may be used in addition and subtraction; an 
OV flag is provided to signal programmer errors in estimating signed number magnitudes 
needed and to adjust signed number results. Multiplication and division use unsigned 
numbers. BCD arithmetic may be done using the DA A and ADD or ADDC instructions. 
The following table lists the arithmetic mnemonics: 



Mnemonic 

ADD A, source 

ADDC A, source 

DA A 

DEC source 
DIV AB 



Operation 

Add the source byte to A; put the result in A and adjust the C and 

OV flags 
Add the source byte and the carry to A; put the result in A and 

adjust the C and OV flags 
Adjust the binary result of adding two BCD numbers in the A 

register to BCD and adjust the carry flag 
Subtract a 1 from the source; roll from OOh to FFh 
Divide the byte in A by the byte in B; put the quotient in A and 

the remainder in B; set the OV flag to 1 if B - OOh before the 

division 



ARITHMETIC OPERATIONS 85 

INC source Add a 1 to the source; roll from FFh or FFFFh to OOh or OOOOh 

MUL AB Multiply the bytes in A and B; put the high-order byte of the 

result in B, the low-order byte in A; set the OV flag to 1 if the 

result is > FFh 
SUBB A, source Subtract the source byte and the carry from A; put the result in A 

and adjust the C and OV flags 

Problems 

Write programs that perform the tasks listed using only opcodes that have been discussed 
in this and previous chapters. Use comments on each line of code and try to use as few 
lines as possible. All numbers may be considered to be unsigned numbers. 

1. Add the bytes in RAM locations 34h and 35h; put the result in register R5 (LSB) and 
R6 (MSB). 

2. Add the bytes in registers R3 and R4; put the result in RAM location 4Ah (LSB) and 
4Bh (MSB). 

3. Add the number 84h to RAM locations 17h and 18h. 

4. Add the byte in external RAM location 02CDh to internal RAM location 19h; put the 
result into external RAM location OOCOh (LSB) and OOClh (MSB). 

5-8. Repeat Problems 1 -4, assuming the numbers are in BCD format. 

9. Subtract the contents of R2 from the number F3h; put the result in external RAM loca- 
tion 028Bh. 

10. Subtract the contents of RI from RO; put the result in R7. 

11. Subtract the contents of RAM location 13h from RAM location 2Bh; put the result in 
RAM location 3Ch. 

12. Subtract the contents of THO from TH I ; put the result in TLO. 

13. Increment the contents of RAM location 13h, 14h, and 15h using indirect addressing only. 

14. Increment TL1 by lOh. 

15. Increment external RAM locations OlOOh and 0200h. 

16. Add a I to every external RAM address from OOh to 06h. 

17. Add a 1 to every external RAM address from OlOOh to 0106h. 

18. Decrement TLO. THO, TL1, and TH1. 

19. Decrement external RAM locations 0123h and OlBDh. 

20. Decrement external RAM locations 45h and 46h. 

21. Multiply the data in RAM location 22h by the data in RAM location 15h; put the result 
in RAM locations 19h (low byte), and lAh (high byte). 

22. Square the contents of R5; put the result in RO (high byte), and Rl (low byte). 

23. Divide the data in RAM location 3Eh by the number 12h; put the quotient in R4 and the 
remainder in R5. 

24. Divide the number in RAM location 15h by the data in RAM location I6h; put the result 
in external RAM location 7Ch. 

25. Divide the data in RAM location 13h by the data in RAM location 14h, then restore the 
original data in 13h by multiplying the answer by the data in 14h. 




Jump and Call Opcodes 



Chapter Outline 

Introduction 

The Jump and Call Program Range 

Jumps 



Calls and Subroutines 
Interrupts and Returns 
Problems 



Introduction 



86 



The opcodes that have been examined and used in the preceding chapters may be thought 
of as action codes. Each instruction performs a single operation on bytes of data. 

The jumps and calls discussed in this chapter are decision codes that alter the flow of 
the program by examining the results of the action codes and changing the contents of the 
program counter. A jump permanently changes the contents of the program counter if cer- 
tain program conditions exist. A call temporarily changes the program counter to allow 
another part of the program to run. These decision codes make it possible for the program- 
mer to let the program adapt itself, as it runs, to the conditions that exist at the time. 

While it is true that computers can't "think" (at least as of this writing), they can 
make decisions about events that the programmer can foresee, using the following deci- 
sion opcodes: 

Jump on bit conditions 

Compare bytes and jump if not equal 

Decrement byte and jump if zero 

Jump unconditionally 

Call a subroutine 

Return from a subroutine 

Jumps and calls may also be generically referred to as "branches," which emphasizes that 
two divergent paths are made possible by this type of instruction. 



JUMP AND CALL OPCODES 



87 



The Jump and Call Program Range 

A jump or call instruction can replace the contents of the program counter with a new 
program address number that causes program execution to begin at the code located at the 
new address. The difference, in bytes, of this new address from the address in the program 
where the jump or call is located is called the range of the jump or call. For example, if a 
jump instruction is located at program address OlOOh, and the jump causes the program 
counter to become 0120h, then the range of the jump is 20h bytes. 

Jump or call instructions may have one of three ranges: a relative range of + 127d, 
— 128d bytes from the instruction /o/Zowmg the jump or call instruction; an absolute range 
on the same 2K byte page as the instruction following the jump or call; or a long range of 
any address from OOOOh to FFFFh, anywhere in program memory. Figure 6. 1 shows the 
relative range of all the jump instructions. 



FIGURE 6.1 Jump Instruction Ranges 

Memory Address (HEX) 
FFFF 



LADD Limit 



Next Page 



PC + 127d 



PC 




PC - 128d 



This Page 



SADD Limit 



Relative Limit 



J— | * 



Next Opcode 



Jump Opcode 



Relative Limit 



SADD Limit 



I 



JNC 



JNB 



Bit 
Jumps 



"I 



I 



I 

I _JBC 'aJM^_ 

™T CJNE T 



I 



DJNZ 
I JZ 



I 



JNZ 



Byte 
Jumps 



I SJMP 



0000 




UMP 



-I 



88 CHAPTER SIX 



Relative Range 

Jumps that replace the program counter contents with a new address that is greater than the 
address of the instruction following the jump by I27d or less than the address of the in- 
struction following the jump by 128d are called relative jumps. They are so named 
because the address that is placed in the program counter is relative to the address where 
the jump occurs. If the absolute address of the jump instruction changes, then the jump 
address changes also but remains the same distance away from the jump instruction. The 
address following the jump is used to calculate the relative jump because of the action of 
the PC. The PC is incremented to point to the next instruction before the current instruc- 
tion is executed. Thus, the PC is set to the following address before the jump instruction is 
executed, or in the vernacular: "before the jump is taken." 

Relative jumping has two advantages. First, only one byte of data need be specified, 
either in positive format for jumps ahead in the program or in 2's complement negative 
format for jumps behind. The jump address displacement byte can then be added to the PC 
to get the absolute address. Specifying only one byte saves program bytes and speeds up 
program execution. Second, the program that is written using relative jumps can be lo- 
cated anywhere in the program address space without re-assembling the code to generate 
absolute addresses. 

The disadvantage of using relative addressing is the requirement that all addresses 
jumped be within a range of +127d, — 128d bytes of the jump instruction. This range is 
not a serious problem. Most jumps form program loops over short code ranges that are 
within the relative address capability. Jumps are the only branch instructions that can use 
the relative range. 

If jumps beyond the relative range are needed, then a relative jump can be done to 
another relative jump until the desired address is reached. This need is better handled, 
however, by the jumps that are covered in the next sections. 

Short Absolute Range 

Absolute range makes use of the concept of dividing memory into logical divisions called 
"pages." Program memory may be regarded as one continuous stretch of addresses from 
OOOOh to FFFFh. Or, it may be divided into a series of pages of any convenient binary 
size, such as 256 bytes, 2K bytes, 4K bytes, and so on. 

The 8051 program memory is arranged as 2K byte pages, giving a total of 32d (20h) 
pages. The hexadecimal address of each page is shown in the following table: 

PAGE ADDRESS(HEX) PAGE ADDRESS(HEX) PAGE ADDRESS(HEX) 



00 


0000-07FF 


0B 


5800- 5FFF 


16 


B000-B7FF 


01 


0800 -0FFF 


OC 


6000- 67FF 


17 


B800-BFFF 


02 


1000- 17FF 


00 


6800- 6FFF 


18 


C000-C7FF 


03 


1800-1FFF 


0E 


7000- 77FF 


19 


C800-CFFF 


04 


2000-27FF 


OF 


7800- 7FFF 


1A 


D000-D7FF 


05 


2800-2FFF 


10 


8000- 8 7FF 


IB 


D800-DFFF 


06 


3000-37FF 


11 


8800- 8FFF 


1C 


E000-E7FF 


07 


3800-3FFF 


12 


9000-97FF 


1D 


E800-EFFF 


08 


4000-47FF 


13 


9800- 9FFF 


1E 


F000-F7FF 


09 


4800-4FFF 


14 


A000-A7FF 


1F 


F800-FFFF 


0A 


5000-57FF 


15 


A800-AFFF 







Inspection of the page numbers shows that the upper five bits of the program counter 
hold the page number, and the lower eleven bits hold the address within each page. An 
absolute address is formed by taking the page number of the instruction following the 



Jumps 



JUMP AND CALL OPCODES 89 



branch and attaching the absolute page range address of eleven bits to it to form the 16-bit 
address. 

Branches on page boundaries occur when the jump or call instruction finishes at 
X7FFh or XFFFh. The next instruction starts at X800h or XOOOh, which places the jump 
or call address on the same page as the next instruction after the jump or call. The page 
change presents no problem when branching ahead but could be troublesome if the branch 
is backwards in the program. The assembler should flag such problems as errors, so ad- 
justments can be made by the programmer to use a different type of range. 

Absolute range addressing has the same advantages as relative addressing; fewer 
bytes are needed and the code is relocatable as long as the relocated code begins at the 
start of a page. Absolute addressing has the advantage of allowing jumps or calls over 
longer programming distances than does relative addressing. 

Long Absolute Range 

Addresses that can access the entire program space from OOOOh to FFFFh use long range 
addressing. Long-range addresses require more bytes of code to specify and are relocat- 
able only at the beginning of 64K byte pages. Since we are limited to a nominal ROM 
address range of 64K bytes, the program must be re-assembled every time a long-range 
address changes and these branches are not generally relocatable. 

Long-range addressing has the advantage of using the entire program address space 
available to the 8051 . It is most likely to be used in large programs. 



The ability of a program to respond quickly to changes in conditions depends largely upon 
the number and types of jump instructions available to the programmer. The 8051 has a 
rich set of jumps that can operate at the bit and byte levels. These jump opcodes are one 
reason the 8051 is such a powerful microcontroller. 

Jumps operate by testing for conditions that are specified in the jump mnemonic. If 
the condition is true, then the jump is taken — that is, the program counter is altered to the 
address that is part of the jump instruction. If the condition is false, then the instruction 
immediately following the jump instruction is executed because the program counter is 
not altered. Keep in mind that the condition of true does not mean a binary 1 and that false 
does not mean binary 0. The condition specified by the mnemonic is either true or false. 

Bit Jumps 

Bit jumps all operate according to the status of the carry flag in the PSW or the status of 
any bit-addressable location. All bit jumps are relative to the program counter. 
Jump instructions that test for bit conditions are shown in the following table: 

Mnemonic Operation 

JC radd Jump relative if the carry flag is set to 1 

JNC radd Jump relative if the carry flag is reset to 

JB b,radd Jump relative if addressable bit is set to 1 

JNB b,radd Jump relative if addressable bit is reset to 

JBC b,radd Jump relative if addressable bit is set, and clear the addressable bit to 

Note that no flags are affected unless the bit in JBC is a flag bit in the PSW. When the bit 
used in a JBC instruction is a port bit, the SFR latch for that port is read, tested, and 
altered. 



90 



CHAPTER SIX 



The following program example makes use of bit jumps: 



ADDRESS 

LOOP: 

ADDA: 



MNEMONIC 

MOV A,#10h 
MOV R0,A 
ADD A.RO 
JNC ADDA 



ADDR: 



MOV A,#10h 
ADD A,RO 
JNB 0D7h,ADDR 
JBC 0D7h,L00P 



COMMENT 

A - lOh 

RO = lOh 

add RO to A 

if the carry flag is 0, then no carry is 

true; jump to address ADDA; jump until A 

is FOh; the C flag is set to 

1 on the next ADD and no carry is 

false; do the next instruction 

A = lOh; do program again using JNB 

add RO to A {RO already equals lOh) 

D7h is the bit address of the carry flag 

the carry bit is 1; the jump to LOOP 

is taken, and the carry flag is cleared 

to 



{>^ CAUTION 



All jump addresses, such as ADDA and ADDR, must be within + 1 27d, - 1 28d of the instruction 
following the jump opcode. 

If the addressable bit is a flag bit and JBC is used, the flag bit will be cleared. 

Do not use any label names that are also the names of registers in the 8051. These are called 
"reserved" words and will cause great agitation in the assembler. 

Byte Jumps 

Byte jumps — jump instructions that test bytes of data — behave as bit jumps. If the condi- 
tion that is tested is true, the jump is taken; if the condition is false,the instruction after 
the jump is executed. AH byte jumps are relative to the program counter. 
The following table lists examples of byte jumps: 



Mnemonic 

CJNE A,add,radd 



CJNE A,#n,radd 



CJNE Rn,#n,radd 



CJNE @Rp,#n,radd 



Operation 

Compare the contents of the A register with the contents of the 
direct address; if they are not equal , then jump to the relative 
address; set the carry flag to 1 if A is less than the contents 
of the direct address; otherwise, set the carry flag to 

Compare the contents of the A register with the immediate 
number n; if they are not equal, then jump to the relative 
address; set the carry flag to 1 if A is less than the number; 
otherwise, set the carry flag to 

Compare the contents of register Rn with the immediate 
number n; if they are not equal, then jump to the relative 
address; set the carry flag to 1 if Rn is less than the number; 
otherwise, set the carry flag to 

Compare the contents of the address contained in register Rp 
to the number n; if they are not equal, then jump to the 
relative address; set the carry flag to 1 if the contents of the 
address in Rp are less than the number; otherwise, set the 
carry flag to 



JUMP AND CALL OPCODES 



91 



DJNZ Rn,radd 
DJNZ add,radd 

JZ radd 
JNZ radd 



Decrement register Rn by I and jump to the relative address if 

the result is not zero; no flags are affected 
Decrement the direct address by I and jump to the relative 

address if the result is not 0; no flags are affected unless the 

direct address is the PSW 
Jump to the relative address if A is 0; the flags and the A 

register are not changed 
Jump to the relative address if A is not 0; the flags and the A 

register are not changed 



Note that if the direct address used in a DJNZ is a port, the port SFR is decremented and 
tested for 0. 

Unconditional Jumps 

Unconditional jumps do not test any bit or byte to determine whether the jump should be 
taken. The jump is always taken. All jump ranges are found in this group of jumps, and 
these are the only jumps that can jump to any location in memory. 
The following table shows examples of unconditional jumps: 



Mnemonic 

JMP @A + DPTR 



AJMP sadd 
LJMP ladd 
SJMP radd 
NOP 



Operation 

Jump to the address formed by adding A to the DPTR; this is an 
unconditional jump and will always be done; the address can 
be anywhere in program memory; A, the DPTR, and the flags 
are unchanged 

Jump to absolute short range address sadd; this is an unconditional 
jump and is always taken; no flags are affected 

Jump to absolute long range address ladd; this is an unconditional 
jump and is always taken; no flags are affected 

Jump to relative address radd; this is an unconditional jump and 
is always taken; no flags are affected 

Do nothing and go to the next instruction; NOP (no operation) is 
used to waste time in a software timing loop; or to leave room 
in a program for later additions; no flags are affected 



The following program example uses byte and unconditional jumps: 



ADDRESS MNEMONIC 





.ORG OlOOh 


BGN: 


MOV A,#30h 




MOV 50h,#00h 


AGN: 


CJNE A,50h,AEQ 




SJMP NXT 


AEQ: 


DJNZ 50h,AGN 




NOP 


NXT: 


MOV R0,#0FFh 


DWN: 


DJNZ RO.DWN 




MOV A.RO 




JNZ ABIG 




JZ AZRO 



COMMENT 

begin program at OlOOh 

A = 30h 

RAM location 50h = OOh 

compare A and the contents of 50h in RAM 

SJMP will be executed if (50h) = 30h 

count RAM location 50h down until (50h) = 

A; (50h) will reach 30h before OOh 

R0 = FFh 

count R0 to OOh; loop here until done 

A = R0 = OOh 

the jump will not be taken 

the jump will be taken 

Continued 



92 



CHAPTER SIX 



ADDRESS 

Continued 

ABIG: 

AZRO: 



HERE 



MNEMONIC 

NOP 
ORG lOOOh 

MOV A,#08h 

MOV DPTR,#1000h 

JMP (5>A + DPTR 

NOP 

NOP 

AJMP AZRO 



£>— CAUTION 



COMMENT 

; this address will not be reached 

;start this segment of program code at 

; lOOOh 

;A = 08h (code at 1000. lh) 

;DPTR = lOOOh (code at 1002, 3 ,4h) 

;jump to location 1008h (code at 1005h 

; (code at 1006h) 

; (code at 1007h) 

; ( code at 1008h, all code on page 2) 



DJNZ decrements first, then checks for 0. A location set to OOh and then decremented goes to 
Ffh, then FEh, and so on, down to OOh. 

CJNE does not change the contents of any register or RAM location. It can change the carry 
flag to 1 if the destination byte is less than the source byte. 

There is no zero flag; the JZ and JNZ instructions check the contents of the A register for 0. 

JMP @A+DPTR does not change A, DPTR, or any flags. 



Calls and Subroutines 



The life of a microcontroller would be very tranquil if all programs could run with no 
thought as to what is going on in the real world outside. However, a microcontroller is 
specifically intended to interact with the real world and to react, very quickly, to events 
that require program attention to correct or control. 

A program that does not have to deal unexpectedly with the world outside of the 
microcontroller could be written using jumps to alter program flow as external conditions 
require. This sort of program can determine external conditions by moving data from the 
port pins to a location and jumping on the conditions of the port pin data. This technique is 
called "polling" and requires that the program does not have to respond to external condi- 
tions quickly. (Quickly means in microseconds; slowly means in milliseconds.) 

Another method of changing program execution is using "interrupt" signals on cer- 
tain external pins or internal registers to automatically cause a branch to a smaller program 
that deals with the specific situation. When the event that caused the interruption has been 
dealt with, the program resumes at the point in the program where the interruption took 
place. Interrupt action can also be generated using software instructions named calls. 

Call instructions may be included explicitly in the program as mnemonics or im- 
plicitly included using hardware interrupts. In both cases, the call is used to execute a 
smaller, stand-alone program, which is termed a routine or, more often, a subroutine. 

Subroutines 

A subroutine is a program that may be used many times in the execution of a larger pro- 
gram. The subroutine could be written into the body of the main program everywhere it is 
needed, resulting in the fastest possible code execution. Using a subroutine in this manner 
has several serious drawbacks. 

Common practice when writing a large program is to divide the total task among 
many programmers in order to speed completion. The entire program can be broken into 
smaller parts and each programmer given a part to write and debug. The main program 



JUMP AND CALL OPCODES 



93 



can then call each of the parts, or subroutines, that have been developed and tested by each 
individual of the team. 

Even if the program is written by one individual, it is more efficient to write an oft-used 
routine once and then call it many times as needed. Also, when writing a program, the 
programmer does the main part first. Calls to subroutines, which will be written later, 
enable the larger task to be defined before the programmer becomes bogged down in the 
details of the application. 

Finally, it is quite common to buy "libraries" of common subroutines that can be 
called by a main program. Again, buying libraries leads to faster program development. 

Calls and the Stack 

A call, whether hardware or software initiated, causes a jump to the address where the 
called subroutine is located. At the end of the subroutine the program resumes operation at 
the opcode address immediately following the call. As calls can be located anywhere in 
the program address space and used many times, there must be an automatic means of 
storing the address of the instruction following the call so that program execution can 
continue after the subroutine has executed. 

The stack area of internal RAM is used to automatically store the address, called the 
return address, of the instruction found immediately after the call. The stack pointer regis- 
ter holds the address of the last space used on the stack. It stores the return address above 
this space, adjusting itself upward as the return address is stored. The terms "stack" and 
"stack pointer" are often used interchangeably to designate the top of the stack area in 
RAM that is pointed to by the stack pointer. 

Figure 6.2 diagrams the following sequence of events: 

1. A call opcode occurs in the program software, or an interrupt is generated in the 
hardware circuitry. 

2. The return address of the next instruction after the call instruction or interrupt is 
found in the program counter. 

3. The return address bytes are pushed on the stack, low byte first. 

4. The stack pointer is incremented for each push on the stack. 

5. The subroutine address is placed in the program counter. 

6. The subroutine is executed. 

7. A RET (return) opcode is encountered at the end of the subroutine. 



FIGURE 6.2 Storing and Retrieving the Return Address 





*. S p +2 

| ►- SP + 1 




SP + 2 *■ 


Program 


Counter 




PCH 


PCL 




1 1 
1 1 


r 


PCH 


— _l 


_J 


i 


PCL 


SP+ 1 — *~ 
SP | 




■ 


l 


f SP 


Stack Area 


RET RETI 


PCH 


PCL 




Program 
ACALL 


Counter 
LCALL 







Interrupt 



Interna! RAM 



94 CHAPTER SIX 



8. Two pop operations restore the return address to the PC from the stack area in 
internal RAM. 

9. The stack pointer is decremented for each address byte pop. 

All of these steps are automatically handled by the 8051 hardware. It is the responsi- 
bility of the programmer to ensure that the subroutine ends in a RET instruction and that 
the stack does not grow up into data areas that are used by the program. 

Calls and Returns 

Calls use short- or long-range addressing; returns have no addressing mode specified but 
are always long range. The following table shows examples of call opcodes: 

Mnemonic Operation 

ACALL sadd Call the subroutine located on the same page as the address of the 
opcode immediately following the ACALL instruction; push the 
address of the instruction immediately after the call on the stack 

LCALL ladd Call the subroutine located anywhere in program memory space; push 
the address of the instruction immediately following the call on 
the stack 

RET Pop two bytes from the stack into the program counter 

Note that no flags are affected unless the stack pointer has been allowed to erroneously 
reach the address of the PSW special-function register. 



Interrupts and Returns 



As mentioned previously, an interrupt is a hardware- generated call. Just as a call opcode 
can be located within a program to automatically access a subroutine, certain pins on the 
8051 can cause a call when external electrical signals on them go to a low state. Internal 
operations of the timers and the serial port can also cause an interrupt call to take place. 
The subroutines called by an interrupt are located at fixed hardware addresses dis- 
cussed in Chapter 2. The following table shows the interrupt subroutine addresses. 



INTERRUPT 


ADDRESS (HEX) CALLED 


IE0 


0003 


TFO 


000B 


IE1 


0013 


TF1 


001 B 


SERIAL 


0023 



When an interrupt call takes place, hardware interrupt disable flip-flops are set to pre- 
vent another interrupt of the same priority level from taking place until an interrupt return 
instruction has been executed in the interrupt subroutine. The action of the interrupt rou- 
tine is shown in the table below. 

Mnemonic Operation 

RETI Pop two bytes from the stack into the program counter and reset the 

interrupt enable flip-flops 

Note that the only difference between the RET and RETI instructions is the enabling 
of the interrupt logic when RETI is used. RET is used at the ends of subroutines called by 
an opcode. RETI is used by subroutines called by an interrupt. 



JUMP AND CALL OPCODES 



95 



ADDRESS 

MAIN: 



The following program example use a call to a subroutine. 



MNEMONIC 

MOV 81h,#30h 
LCALL SUB 
NOP 



COMMENT 

;set the stack pointer to 30h in RAM 
;push address of NOP; PC = #SUB; SP = 32h 
; return from SUB to this opcode 



SUB: 



ADDRESS 



MOV A,#45h 
RET 

CAUTION 



;SUB loads A with 45h and returns 
;pop return address to PC; SP = 30h 



Set the stack pointer above any area of RAM used for additional register banks or data memory. 

The stack may only be 1 28 bytes maximum; which limits the number of successive calls with no 
returns to 64. 

Using RETI at the end of a software called subroutine may enable the interrupt logic erroneously. 

To jump out of a subroutine (not recommended), adjust the stack for the two return address 
bytes by POPing it twice or by moving data to the stack pointer to reset it to its original value. 

Use the LCALL instruction if your subroutines are normally placed at the end of your program. 

In the following example of an interrupt call to a routine, timer is used in mode to 
overflow and set the timer interrupt flag. When the interrupt is generated, the program 
vectors to the interrupt routine, resets the timer interrupt flag, stops the timer, and returns. 



MNEMONIC 

.ORG OOOOh 
AJMP OVER 
.ORG OOOBh 
CLR 8Ch 
RETI 



COMMENT 

;begin program at 0000 

; jump over interrupt subroutine 

;put timer interrupt subroutine here 

;stop timer 0; set TRO = 

; return and enable interrupt structure 



OVER: 



MOV 0A8h,#82h 
MOV 89h.#00h 
MOV 8Ah,#O0h 
MOV 8Ch.#00h 
SET 8Ch 



;enable the timer interrupt in the IE 

;set timer operation, mode 

; clear TLO 

; clear THO 

; start timer 0; set TRO = 1 



the program will continue on and be interrupted when the timer has 
timed out 



CAUTION 



The programmer must enable any interrupt by setting the appropriate enabling bits in the IE 
register. 



Example Problems 



We now have all of the tools needed to write powerful, compact programs. The addition of 
the decision jump and call opcodes permits the program to alter its operation as it runs. 



96 



CHAPTER SIX 



! I 



EXAMPLE PROBLEM 6.1 



ADDRESS 


MNEMONIC 


ONE: 


CLR C 




MOV A,#2Ah 




SUBB A,3Ch 




JZ DONE 




INC 3Ch 




SJMP ONE 


DONE: 


NOP 



Place any number in internal RAM location 3Ch and increment it until the number equals 
2 Ah. 

■ Thoughts on the Problem The number can be incremented and then tested to see 
whether it equals 2Ah. If it does, then the program is over; if not, then loop back and 
decrement the number again. 

Three methods can be used to accomplish this task. 
« Method 1: 

COMMENT 

;this program will use SUBB to detect equality 

;put the target number in A 

;subtract the contents of 3Ch; C is cleared 

;if A = OOh, then the contents of 3Ch = 2Ah 

;if A is not zero, then loop until it is 

;loop to try again 

;when finished, jump here and continue 



£>— COMMENT 





■ Method 2: 


ADDRESS 


MNEMONIC 


TWO: 


INC 3Ch 




MOV A,#2Ah 




XRL A,3Ch 




JNZ TWO 




NOP 



As there is no compare instruction for the 8051, the SUBB instruction is used to compare A 
against a number. The SUBB instruction subtracts the C flag also, so the C flag has to be cleared 
before the SUBB instruction is used. 



COMMENT 

incrementing 3Ch first saves a jump later 
this program will use XOR to detect equality 
XOR with the contents of 3Ch; if equal, A = OOh 
this jump is the reverse of program one 



finished when the jump is false 



£>— COMMENT 



Many times if the loop is begun with the action that is to be repeated until the loop is satisfied, 
only one jump, which repeats the loop, is needed. 

■ Method 3: 



ADDRESS MNEMONIC 

THREE: INC 3Ch 

MOV A,#2Ah 

CJNE A,3Ch,THREE 

NOP 



COMMENT 

begin by incrementing the direct address 
this program uses the very efficient CJNE 
jump if A and (3Ch) are not equal 
all done 



□ 



COMMENT 



CJNE combines a compare and a jump into one compact instruction. 

EXAMPLE PROBLEM 6.2 

The number A6h is placed somewhere in external RAM between locations 01 OOh and 
0200h. Find the address of that location and put that address in R6 (LSB) and R7 (MSB). 



JUMP AND CALL OPCODES 



97 



■ Thoughts on the Problem The DPTR is used to point to the bytes in external memory, 
and CJNE is used to compare and jump until a match is found. 



ADDRESS MNEMONIC 

MOV 20h,#0A6h 
MOV DPTR, #OOFFh 
MOR: INC DPTR 

MOVX A,@DPTR 
CJNE A,20h,M0R 

MOV R7,83h 
MOV R6,82h 



COMMENT 

;load 20h with the number to be found 

; start the DPTR below the first address 

; increment first and save a jump 

; get a number from external memory to A 

; compare the number against (20h) and 

;loop to MOR if not equal 

;move DPH byte to R7 

;move DPL byte to R6; finished 



COMMENT 



□ 



This program might loop forever unless we know the number will be found; a check to see 
whether the DPTR has exceeded 0200h can be included to leave the loop if the number is not 
found before DPTR = 0201 h. 

EXAMPLE PROBLEM 6.3 

Find the address of the first two internal RAM locations between 20h and 60h which con- 
tain consecutive numbers. If so, set the carry flag to 1 , else clear the flag. 

■ Thoughts on the Problem A check for end of memory will be included as a Called 
routine, and CJNE and a pointing register will be used to search memory. 



ADDRESS 



NXT: 



THRU 
DUN: 



BCK: 



MNEMONIC 

MOV 81h.#65h 

MOV R0.#20h 

MOV A,@R0 

INC A 

MOV lFh.A 

INC R0 

CALL DUN 

JNC THRU 

MOV A,@R0 

CJNE A,lFh,NXT 

SETB 0D7h 

SJMP THRU 

PUSH A 

CLR C 

MOV A,#61h 

XRL A.RO 

JNZ BCK 

RET 

POP A 

CPL C 

RET 



COMMENT 

set the stack above memory area 

load RO with address of memory start 

get first number 

increment and compare to next number 

store incremented number at lFh 

point to next number 

see if RO greater than 60h 

DUN returns C = if over 60h 

get next number 

if not equal then look at next pair 

set the carry to 1 ; finished 

jump here if beyond 60h 

save A on the stack 

clear the carry 

use XOR as a compare 

A will be if equal 

if not then continue 

A 0, signal calling routine 

get A back 

A not 0, set C to indicate not done 



COMMENT 



Set the stack pointer to put the stack out of the memory area in use. 



98 CHAPTER SIX 

Summary 



Jumps 

Jumps alter program flow by replacing the PC counter contents with the address of the 
jump address. Jumps have the following ranges: 

Relative: up to PC + 127 bytes, PC - 128 bytes away from the PC 
Absolute short: anywhere on a 2K-byte page 
Absolute long: anywhere in program memory 

Jump opcodes can test an individual bit, or a byte, to check for conditions that make 
the program jump to a new program address. The bit jumps are shown in the following 
table: 

INSTRUCTION TYPE RESULT 

JC radd Jump relative if carry flag set to 1 

JNC radd Jump relative if carry flag cleared to 

JB b,radd Jump relative if addressable bit set to 1 

JNB b,radd Jump relative if addressable bit cleared to 

JBC b,radd Jump relative if addressable bit set to 1 and clear bit to 

Byte jumps are shown in the following table: 

INSTRUCTION TYPE RESULT 

CJNE destination, source, address Compare destination and source; jump to address if 

not equal 
DJNZ destination, address Decrement destination by one; jump to address if 

the result is nor zero 
JZ radd Jump A = OOh to relative address 

JNZ radd lump A > OOh to relative address 

Unconditional jumps make no test and are always made. They are shown in the fol- 
lowing table: 

INSTRUCTION TYPE RESULT 

JMP <aA+DPTR Jump to 16-bit address formed by adding A to the DPTR 

AJMP sadd Jump to absolute short address 

LIMP ladd Jump to absolute long address 

SJMP radd Jump to relative address 

NOP Do nothing and go to next opcode 

Call and Return 

Software calls may use short- and long-range addressing; returns are to any long-range 
address in memory. Interrupts are calls forced by hardware action and call subroutines 
located at predefined addresses in program memory. The following table shows calls and 
returns: 

INSTRUCTION TYPE RESULT 

ACALL sadd Calf the routine located at absolute short address 

LCALL ladd Call the routine located at absolute long address 

RET Return to anywhere in the program at the address found on the 

top two bytes of the stack 
RETI Return from a routine called by a hardware interrupt and reset 

the interrupt logic 



JUMP AND CALL OPCODES 99 



Problems 



Write programs for each of the following problems using as few lines of code as you can. 
Place comments on each line of code. 

1. Put a random number in R3 and increment it until it equals E 1 h. 

2. Put a random number in address 20h and increment it until it equals a random number 
put in R5. 

3. Put a random number in R3 and decrement it until it equals Elh. 

4. Put a random number in address 20h (LSB) and 2 lh (MSB) and decrement them as if 
they were a single 16-bit counter until they equal random numbers in R2 (LSB) and 
R3 (MSB). 

5. Random unsigned numbers are placed in registers RO to R4. Find the largest number and 
put it in R6. 

6. Repeat Problem 3, but find the smallest number. 

7. If the lower nibble of any number placed in A is larger than the upper nibble, set the 
C flag to one; otherwise clear it. 

8. Count the number of ones in any number in register B and put the count in R5. 

9. Count the number of zeroes in any number in register R3 and put the count in R5. 

10. If the signed number placed in R7 is negative, set the carry flag to I ; otherwise clear it. 

11. Increment the DPTR from any initialized value to ABCDh. 

12. Decrement the DPTR from any initialized value to 0033h. 

13. Use R4 (LSB) and R5 (MSB) as a single 16-bit counter, and decrement the pair until 
they equal OOOOh. 

14. Get the contents of the PC to the DPTR. 

15. Get the contents of the DPTR to the PC. 

16. Get any two bytes you wish to the PC. 

17. Write a simple subroutine, call it, and jump back to the calling program after adjusting 
the stack pointer. 

18. Put one random number in R2 and another in R5. Increment R2 and decrement R5 until 
they are equal. 

19. Fill external memory locations lOOh to 200h with the number AAh. 

20. Transfer the data in internal RAM locations lOh to 20h to internal RAM locations 30h 
to 40h. 

21. Set every third byte in internal RAM from address 20h to 7Fh to zero. 

22. Count the number of bytes in external RAM locations lOOh to 200h that are greater than 
the random unsigned number in R3 and less than the random unsigned number in R4. 
Use registers R6 (LSB) and R7 (MSB) to hold the count. 

23. Assuming the crystal frequency is 10 megahertz, write a program that will use timer 1 to 
interrupt the program after a delay of 2 ms. 

24. Put the address of every internal RAM byte from 50h to 70h in the address; for instance, 
internal RAM location 6Dh would contain 6Dh. 

25. Put the byte AAh in all internal RAM locations from 20h to 40h, then read them back 
and set the carry flag to I if any byte read back is not AAh. 




An 8051 Microcontroller Design 



Chapter Outline 

Introduction 

A Microcontroller Specification 
A Microcontroller Design 
Testing the Design 



Timing Subroutines 
Lookup Tables for the 8051 
Serial Data Transmission 
Summary 



introduction 



100 



In this chapter a hardware configuration for an 8051 microcontroller, which will be used 
for all of the example applications in Chapters 8 and 9, is defined. Programs that check the 
initial prototype of the design (debugging programs) are given in this chapter, followed by 
several common subroutines that can be used by programs in succeeding chapters. 

The design of the microcontroller begins with an identified need and a blank piece of 
paper or computer screen. The evolution of the microcontroller follows these steps; 

1. Define a specification. 

2. Design a microcontroller system to this specification. 

3. Write programs that will assist in checking the design. 

4. Write several common subroutines and test them. 

The most important step is the first one. !f the application is for high-volume produc- 
tion (greater than 10,000 units), then the task must be very carefully analyzed. A precise 
or "tight" specification is evolved for what will become a major investment in factory- 
programmed parts. As the volume goes down for any particular application, the specifica- 
tions become more general as the designers attempt to write a specification that might fit a 
wider range of applications. 



AN 8051 MICROCONTROLLER DESIGN 101 

The list leaves out a few real-world steps, most notably the redesign of the micro- 
controller after it is discovered that the application has grown beyond the original specifi- 
cation or, as is more common, the application was not well understood in the beginning. 
Experienced designers learn to add a little "fat" to the specification in anticipation of the 
inexorable need for "one more bit of I/O and one more kilobyte of memory." 



A Microcontroller Specification 



A typical outline for a microcontroller design might read as follows: 

"A requirement exists for an intelligent controller for real-time control and data moni- 
toring applications. The controller is part of a networked system of identical units that are 
connected to a host computer through a serial data link. The controller is to be produced in 
low volumes, typically less than one thousand units for any particular application, and it 
must be low cost." 

The 805 1 family is chosen for the following reasons: 

Low part cost 

Multiple vendors 

Available in NMOS and CMOS technologies 

Software tools available and inexpensive 

High-level language compilers available 

The first three items are very important from a production cost standpoint. The soft- 
ware aids available reduce first costs and enable projects to be completed in a timely 
manner. 

The low-volume production requirement and the need for changing the program to fit 
particular applications establish the necessity of using external EPROM to hold the appli- 
cation program. In turn, ports (AD0-AD7) and 2 (A8-A15) must be used for inter- 
facing to the external ROM and will not be available for I/O. 

Because one possible use of the controller will be to gather data, RAM beyond that 
available internally may be needed- External RAM is added for this eventuality. The 
immediate consequence of this decision is that port 3 bits 6 (WR) and 7 (RD) are needed 
for the external RAM and are not available for I/O. External memory uses the 28-pin 
standard configuration, which enables memories as large as 64K to be inserted in the 
memory sockets. 

Commercially available EPROM parts that double in size beginning at 2K bytes can 
be purchased. The minimum EPROM size selected is 8K and the maximum size is 64K. 
These choices reflect the part sizes that are most readily available from vendors and parts 
that are now beginning to enter high-volume production. 

Static RAM parts are available in 2K, 8K, and 32K byte sizes; again, the RAM sizes 
are chosen to be 8K or 32K to reflect commercial realities. The various memory sizes can 
be incorporated by including jumpers for the additional address lines needed by larger 
memories and pullup resistors to enable alternate pin uses on smaller memories. 

The serial data needs can be handled by the internal serial port circuitry. Once again, 
two more I/O pins of port 3 are used: bits 3.0 (RXD) and 3. 1 (TXD). We are left with ail 
of port I for general-purpose I/O and port 3 pins 2-5 for general-purpose I/O or for exter- 
nal interrupts and timing inputs. 

Note that rapid loss of I/O capability occurs as the alternate port functions are used and 
should be expected unless volumes are high enough to justify factory- programmed parts. 



102 CHAPTER SEVEN 



The handicap is not as great as it appears, however; two methods exist that are commonly 
used to expand the I/O capability of any computer application: port I/O and memory- 
mapped I/O. 

Finally, we select a 16 megahertz crystal to take advantage of the latest high-speed 
devices available, and the specification is complete. To summarize, we have 

80C31-1 (ROMIess) microcontroller 

64K bytes of external EPROM 

32K bytes of external RAM 

8 general-purpose I/O lines 

4 general -purpose or programmable I/O lines 

! full-duplex serial port 

16 megahertz crystal clock 

Now that the specification is complete, the design can be done. 



A Microcontroller Design 



The final design, shown in Figure 7. 1, is based on the external memory circuit found in 
Chapter 2. Any I/O circuitry needed for a particular application will be added to the basic 
design as required. A design may be done in several ways; the choices made for this design 
are constrained by cost and the desire for flexibility. 

External Memory and Memory Space Decoding 

External memory is added by using port as a data and low-order address bus, and port 2 
as a high-order address bus. The data and low addresses are time multiplexed on port 0. 
An external 373 type address latch is connected to port to store the low address byte 
whenever external memory is accessed. The low-order address is gated into the trans- 
parent latch by the ALE pulse from the 8051 . Port then becomes a bidirectional data bus 
during the read or write phase of a machine cycle. 

RAM and ROM are addressed by entirely different control lines from the 8051 : PSEN 
for the ROM and WR or RD for the RAM. The result is that each occupies one of two 
parallel 64 kilobyte address spaces. The decoding problem becomes one of simply adding 
suitable jumpers and pullup resistors so that the user can insert the memory capacity 
needed. Jumpers are inserted so that the correct address line reaches the memory pin or 
the pin is pulled high as required by the memory used. The jumper table in Figure 7. 1 for 
the EPROM and RAM memories that can be inserted in the memory sockets shows the 
jumper configuration. Figure 7.2 graphically demonstrates the relative sizes of the internal 
and external memories available to the programmer. 

Reset and Clock Circuits 

The 8051 uses an active high reset pin. The reset input must go high for two machine 
cycles when power is first applied and then sink low. The simple RC circuit used here will 
supply system voltage (Vcc) to the reset pin until the capacitor begins to charge. At a 
threshold of about 2.5 V, the reset input reaches a low level, and the system begins to run. 
Internal reset circuitry has hysteresis necessitated by the slow fall time of the RC circuit. 



AN 8051 MICROCONTROLLER DESIGN 



103 



FIGURE 7.1 8031 Microcontroller with External ROM and RAM 



WR 



3.6 



CI 30PF 

■HI- 



XTAL 

16MHZ. 



•Hr 



T 

x 



C230PF. 



3.5 
3.4 
3.3 
3.2 
3.1 
3.0 

1-7 
1.6 

1.5 
1.4 
1.3 
1.2 
1.1 
1.0 



3.7 



31 16 17 29 



18 



19 



28 
27 
26 
Port 2 25 
24 
23 
22 
21 



8031 



isrri) 

14fT0) 

12(INT01 
llfTXD) 

lO(RXD) 



30 

B 32 

7 33 

6 34 

") Portl PortO !f 

4 36 

3 

2 

1 a 



37 
38 
39 



C3 10ft r. 
+ 5 V« ^ 



R5.1K 



RD 



PSEN 



X 



J3 

2. 
Jl 



R133K 



A 15 



A 14 



A 13 



R2 33K 



X 



A12 



All 



A 10 



A9 



AS 



+5V 



R3 33K 



220E 20CE 



Hi- 



1 NpP> 

27 (PGM) 

26 (N.C.) 

2 

23 

21 

24 

25 



EPROM 

2764 <8K) 

27128 (16K) 

27256 (32K) 

27512 (64K) 




J5 i 
A 12 



All 



A 10 



A9 



A8 



A14 



A 13 



J4 



22 OE 

27R/W 

1A14/N.C. 

26A13/CE2 

2 

23 

21 

24 

25 



20(CE1) 



RAM 
6264 (8K) 
62256 (32K) 



Jumper Table 



Reset 



I 



R4 8.2K 



1 



I 



Memory Sze 


EPROM 


RAM 


8K 


None 


None 


16K 


Jl 


NA 


32K 


Jl JE 


J4J5 


64K 


J1J2J3 


NA 



The addition of a reset button enables the user to reset the system without having to turn 
power off and on. 

The clock circuit of Chapter 2 is added, and the design is finished. 

Expanding I/O 

Ports 1 and 3 can be used to form small control and bidirectional data buses. The data 
buses can interface with additional external circuits to expand I/O up to any practical 
number of lines. 



104 CHAPTER SEVEN 



FIGURE 7.2 8031 Memory Sizes 



Internal RAM 
OOh to FFh 

MOV 



External RAM 
OOOOh to 7FFFh 



External ROM 
OOOOh to FFFFh 



MOVX® 



Program ROM 
MOVC® 



There are many popular families of programmable port chips. The one chosen here is 
the popular 8255 programmable interface adaptor, which is available from a number of 
vendors. Details on the full capabilities of the 8255 are given in Appendix D. The 8255 
has an internal mode register to which control words are written by the host computer. 
These control words determine the actions of the 8255 ports, named A, B, and C, enab- 
ling them to act as input ports, output ports, or some combination of both. 

Figure 7.3 shows a circuit that adds an 8255 port expansion chip to the design. The 
number of ports is now three 8-bit ports for the system. The penalty paid for expanding 
I/O in this manner is a reduction in speed that occurs due to the overhead time needed to 
write control bits to ports 1 and 3 before the resulting I/O lines selected can be accessed. 
The advantage of using I/O port expansion is that the entire range of 805 1 instructions can 
be used to access the added ports via ports 1 and 3. 



Memory-Mapped I/O 

The same programmable chip used for port expansion can also be added to the RAM 
memory space of the design, as shown in Figure 7.4. The present design uses only 32K. of 



AN 8051 MICROCONTROLLER DESIGN 



105 



FIGURE 7.3 Expanding I/O Using 8031 Ports 



Port 3 



8031 Port 1 



15 
14 
13 
12 
11 
10 



CS 



Reset 



A0 



Al 



RD 



WR 



DO 



Dl 



D2 



D3 



D4 



D5 



D6 



D7 



6 

35 

9 

8 

5 

36 



34 
33 
32 
31 
30 
29 
28 
27 



8255 



4 




PAO 


3 




PA1 


2 




PA2 


1 




PA3 


40 




PA4 


39 




PA5 


38 




PA6 


37 




PA 7 


18 




PBO 


19 




PB1 


20 




PB2 


21 




PB3 


22 




PB4 


23 




PB5 


24 




PB6 


25 




PB7 


14 




PCO 


15 




PCI 


16 




PC2 


17 




PC3 


13 




PC4 


12 




PC5 


11 




PC6 


10 




PC7 



the permitted 64K of RAM address space; the upper 32K is vacant. The port chip can be 
addressed any time A15 is high (8000h or above), and the 32K RAM can be addressed 
whenever A15 is low (7FFFh and below). This decoding scheme requires only the addi- 
tion of an inverter to decode the memory space for RAM and I/O. 

Should more RAM be added to the design, a comprehensive memory-decoding scheme 
will require the use of a programmable array-type decoder to reserve some portion of mem- 
ory space for the I/O port chips. Figure 7.4 shows a design that permits the addition of three 
memory-mapped port chips at addresses FFF0h-FFF3h, FFF4h-FFF7h, FFF8h-FFFBh. 
and FFFCh-FFFFh. RAM is addressable from OOOOh to FFEFh. 

Memory-mapped I/O has the advantage of not using any of the 8051 ports. Disadvan- 
tages include the loss of memory space for RAM that is used by the I/O address space, or 
the addition of memory decoding chips in order to limit the RAM address space loss. 
Programming overhead is about the same as for port I/O because only the cumbersome 
MOVX instruction may be used to access the memory-mapped I/O. 

For both types of I/O expansion, the cost of the system begins to mount. At some 
point, a conventional microprocessor, with a rich set of I/O and memory instructions, 
may become a more economical choice. 



106 



CHAPTER SEVEN 



FIGURE 7.4 Expanding I/O Using Memory Mapping 



To RAM CS Pin 



A15 



Reset 
8051 
Address Bus 
P3.7 
P3.6 



8051 
Address/Data Bus 




— FFFC-F 
■ FFF8-B ToB255 

— FFF4-7 CSPin 

— FFFO-3 



Reset 



8255 Connections For Memory Mapping 



Reset Circuit 



Part Speed 

One consideration, that does not appear on the design drawings, is the selection of parts 
that will work at the system speeds determined by the crystal frequency. All memory parts 
are priced according to the nanosecond of access time. The longer the access time (the 
time it takes for a byte of data to be read or written from or to the device after the address 
is valid), the cheaper the part. For our design, Figure 7.4 shows the timing involved in 
reading data from the ROM and reading and writing data to the RAM. These times are 
totally determined by the selection of the crystal frequency, and the designer must choose 
memory parts that are fast enough to keep up with the microcontroller at the chosen fre- 
quency. For our example, EPROMS with maximum access times of 1 50 ns and RAM with 
access times of 400 ns must be used. These access times are representative of standard 
commercial types currently available at the low end of the cost spectrum. These times are 
worst-case times; actual access times are at least 30 percent longer. 

Other parts, such as the '373 type latch can be any family from LSTTL to HCMOS. 
The speeds of these parts far exceed the speed of the 8051 . 

Production Concerns 

The design omits many features that would be incorporated by a design-manufacturing 
team. Chief among these are the inclusion of test-points, LED indicators, and other items 
that should be added to enhance manufacturing and field service of the microcontroller. 



AN 8051 MICROCONTROLLER DESIGN 



107 



These concerns are well beyond the scope of this book, but the wise designer always 
ensures that the legitimate concerns of the technical, manufacturing, and service depart- 
ments are addressed. 



Testing the Design 



ADDRESS 

begin: 

add2: 

add3: 

add4: 

add5: 

add6 : 



Once the hardware has been assembled, it is necessary to verify that the design is correct 
and that the prototype is built to the design drawing. This verification of the design is done 
by running several small programs, beginning with the most basic program and building 
on the demonstrated success of each. 

Crystal Test 

The initial test is to ensure that both the crystal and the reset circuit are working. The 805 1 
is inserted in the circuit, and the ALE pulse is checked with an oscilloscope to verify that 
the ALE frequency is 1/6 of the crystal frequency. Next, the reset button is pushed, and 
all ports are checked to see that they are in the high (input) state. 

ROM Test 

The most fundamental program test is to ensure that the microcontroller can fetch and 
execute programs from the EPROM. Code byte fetching can be tested by verifying that 
each address line of the ROM is properly wired by using a series of repeated jump instruc- 
tions that exercise all of the address lines. The test used here will jump to addresses that 
are a power of two. Only one address line will be high, and all of the rest will be low. The 
address pattern tests for proper wiring of each address line and also checks for shorts 
between any two lines. 

If the test is successful, the program stops at the highest possible ROM address. The 
address bus can then be checked with a logic probe to verify that the highest address has 
been reached. Correct operation is indicated by the highest order address bus bit, which 
will appear constant. If not, the probe will blink indicating random program fetches. 

The test is run by inserting the '373 latch, the programmed 64K EPROM, inserting 
jumpers l - 3 and resetting the 805 1 . The test can be stopped at any address by jumping to 
that address, as is done in the last statement in the following ROM test program: 



MNEMONIC 

.org OOOOh 
ljmp add2 
.org 0004h 
ljmp add3 
.org 0008h 
ljmp add4 
.org OOlOh 
ljmp add5 
.org 0020h 
ljmp add6 
.org 0040h 
ljmp add7 
.org 0080h 



COMMENT 

;start at the 

; test address 

;next jump at 

; test address 

;next jump at 

; test address 

;next jump at 

; test address 

;next jump at 

;test address 

;next jump at 

;test address 

;next jump at 



bottom of ROM 

lines A0 and Al 

address 0004h (A2 

line A2 

address 0008h (A3 

line A3 

address OOlOh (A4 

line A4 

address 0020h (A5 

line A5 

address 0040h (A6 

line A6 

address 0080h (A7 



Continued 



108 


CHAPTER SEVEN 












ADDRESS 


MNEMONIC 


COMMENT 






Continued 














add7: 




ljmp 


add8 


; test 


address 


line A7 








■ org 


OlOOh 


.next 


jump at 


address OlOOh 


(A8) 


add8: 




ljmp 


add9 


; test 


address 


line A8 








■ org 


0200h 


; next 


jump at 


address 0200h 


(A9) 


add9: 




ljmp 


addlO 


; test 


address 


line A9 








■ org 


0400h 


;next 


jump at 


address 0400h 


(A10) 


addlO: 




ljmp 


addll 


; test 


address 


line A10 








■ org 


0800h 


; next 


jump at 


address 0800h 


(All) 


addll: 




ljmp 


addl2 


; test 


address 


line All 








• org 


lOOOh 


;next 


jump at 


address lOOOh 


(A12) 


addl2: 




ljmp 


addl3 


; test 


address 


line A12 








.org 


2000h 


;next 


jump at 


address 2000h 


(A13) 


addl3: 




ljmp 


addl4 


; test 


address 


line A13 








• org 


4000h 


; last 


jump at 


address 4000h 


(A14) 


addl4: 




ljmp 


addl5 


; test 


address 


line A14 








■org 


8000h 


; test 


address 


line A15 and remain her 


addl5: 




.ljmp addl5 


; jump 


here in 


a loop 








. end 




; assembler use 





This address, A15, will remain latched while A2-A14 will 
remain low. AO and Al will vary as the bytes of the jump 
instruction are fetched. 



Inspection of the listing for this program in Figure 7.5 shows that all the address lines are 
exercised. 



RAM Test 

Once sure of the ability of the microcontroller to execute code, the RAM can be checked. A 
common test is to write a so-called checkerboard pattern to RAM — that is, an alternating 
pattern of I and in memory. Writing bytes of 55h or AAh will generate such a pattern. 

The next program writes this pattern to external RAM, then reads the pattern back 
andchecks each byte read back against the byte that was written. If a check fails, then the 
address where the failure occurred is in the DPTR register. Port 1 and the free bits of port 3 
can then be used to indicate the contents of DPTR. 

There are 14 bits available using these ports (the serial port is not in use now, so bits 
3.0 and 3. 1 are free), and 15 are needed to express a 32K address range. The program will 
test a range of 8K bytes at a time, using 13 bits to hold the 8K. address upon failure. Four 
versions have to be run to cover the entire RAM address space. If the test is passed, then 
bit 14 (port 3.5) is a 1. If the test fails, then bit 14 is a 0, and the other 13 bits hold the 
address (in the 8K page) at which the failure occurred. 

Interestingly, this test does not check for correct wiring of the RAM address lines. As 
long as all address lines end on some valid address, the test will work. A wiring check 
requires that a ROM be programmed with some unique pattern at each address that is a 
power of two and read using a check program that inspects each unique address location 
for a unique pattern. 

The RAM test program is listed on the following page. 



AN 8051 MICROCONTROLLER DESIGN 



109 



FIGURE 7.5 Assembled ROM Check Program 



oooo 
oooo 

0004 
0004 
0008 
0008 
0010 
0010 
0020 
0020 
0040 
0040 
0080 
0080 
0100 
0100 
0200 
0200 
0400 
0400 
0800 
0800 
1000 
1000 
2000 
2000 
4000 
4000 
8000 



020004 
020008 
020010 
020020 
020040 
020080 
020100 
020200 
020400 
020800 
021000 
022000 
024000 
028000 



8000 028000 
8003 



begin 

add2: 

add3: 

add4: 

add5: 

add6: 

add7: 

add8: 

add9: 

addlO 

addll: 

addl2: 

addl3; 

addl4; 

add!5; 



-org 
ljmp 
.org 
ljmp 

• org 
ljmp 

■ org 
ljmp 
.org 
ljmp 
.org 
ljmp 

■ org 
ljmp 

• org 
ljmp 

■ org 
ljmp 
.org 
ljmp 
.org 
ljmp 

• org 
ljmp 

• org 
ljmp 

■ org 
ljmp 

• org 



OOOOh 

add2 

0004h 

add3 

0008h 

add4 

OOlOh 

add5 

0020h 

add6 

0040h 

add7 

0080h 

add8 

OlOOh 

add9 

0200h 

addlO 

0400h 

addll 

0800h 

addl2 

lOOOh 

addl3 

2000h 

addl4 

4000h 

addl5 

8000h 



ljmp addl5 
. end 



start at the bottom of ROM 

test address lines AO and Al 

next jump at address 0004h (A2) 

test address line A2 

next jump at address 0008h (A3) 

test address line A3 

next jump at address OOlOh (A4) 

test address line A4 

next jump at address 0020h (A5) 

test address line A5 

next jump at address 0040h (A6) 

test address line A6 

next jump at address 0080h (A7) 

test address line A7 

next jump at address OlOOh <A8) 

test address line A8 

next jump at address 0200h (A9) 

test address line A9 

next jump at address 0400h (A10) 

test address line A10 

next jump at address 0800h (All) 

test address line All 

next jump at address lOOOh (A12) 

test address line A12 

next jump at address 2000h (A13) 

test address line A13 

last jump at address 4000h (A14) 

test address line A14 and remain 

test address line A15 and remain 

here 

jump here in a loop 

assembler use 



ADDRESS 



test : 



MNEMONIC 

. equ ramstart , OOOOh 
. equ rmstphi , 20h 
.equ pattern, 55h 
.equ good,20h 
.equ bad.Odfh 
.org OOOOh 
mov p3,#0ffh 
mov dptr, #ramstart 
mov a,#pattern 
movx @dptr,a 



COMMENT 

set RAM test start address 
set RAM test high stop address 
determine test pattern 
RAM good pattern P3.5 = 1 
RAM bad pattern, P3.5 = 
begin test program at OOOOh 
set Port 3 high 
initialize DPTR 
set pattern byte 
write byte to RAM 



Continued 



110 



CHAPTER SEVEN 



ADDRESS 

Continued 



check: 



here : 
fail: 



there: 



MNEMONIC 

inc dptr 
mov a,#rmstphi 
cjne a.dph.test 
mov dptr, #ramstart 
movx a, @dptr 
cjne a, #pattern, fail 
inc dptr 
mov a,#rmstphi 
cjne a.dph, check 
mov p3,#good 
sjmp here 
mov p3 , dph 
anl p3,#bad 
mov pi, dpi 
sjmp there 
end 



■£>— COMMENT 



COMMENT 

point to next RAM byte 

check to see if at stop address 

if not then loop until done 

start read-back test 

read byte from RAM 

test against what was written 

go to next byte if tested ok 

check to see if all bytes tested 

if not then check again 

checked ok, set Port 3 to good 

stop here 

test failed, get address 

set 3.5 to zero 

set Port 1 to low address byte 

stop there 



Change the ramstart and rmstphi .equ hex numbers to check pages 2000h to 3FFFh, 4000h to 
5FFFh, and 6000h to 7FFFh. 

Note that a full 1 6-bit check for end of memory does not have to be done due to page bounda- 
ries of (20)00, (40)00, (60)00, and (80)00h. 

There is no halt command for the 8051 ; jumps in place serve to perform the halt function. 

We have now tested all the external circuitry that has been added to the 8051. The 
remainder of the chapter is devoted to several subroutines that can be used by the applica- 
tion programs in Chapters 8 and 9. 



Timing Subroutines 



Subroutines are used by call programs in what is known as a "transparent" manner— -that 
is, the calling program can use the subroutines without being bothered by the details of 
what is actually going on in the subroutine. Usually, the call program preloads certain 
locations with data, calls the subroutine, then gets the results back in the preload locations. 

The subroutine must take great care to save the values of all memory locations in the 
system that the subroutine uses to perform internal functions and restore these values be- 
fore returning to the call program. Failure to save values results in occasional bugs in the 
main program. The main program assumes that everything is the same both before and 
after a subroutine is called. 

Finally, good documentation is essential so that the user of the subroutine knows pre- 
cisely how to use it. 

Time Delays 

Perhaps the most-used subroutine is one that generates a programmable time delay. Time 
delays may be done by using software loops that essentially do nothing for some period, 
or by using hardware timers that count internal clock pulses. 



AN8051 MICROCONTROLLER DESIGN 111 

The hardware timers may be operated in either a software or a hardware mode. In the 
software mode, the program inspects the timer overflow flag and jumps when it is set. The 
hardware mode uses the interrupt structure of the 8051 to generate an interrupt to the pro- 
gram when the timer overflows. 

The interrupt method is preferred whenever processor time is scarce. The interrupt 
mode allows the processor to continue to execute useful code while the time delay is 
taking place. Both the pure software and timer-software modes tie up the processor while 
the delay is taking place. 

If the interrupt mode is used, then the program must have an interrupt handling rou- 
tine at the dedicated interrupt program vector location specified in Chapter 2. The program 
must also have programmed the various interrupt control registers. This degree of "non- 
transparency" generally means that interrupt-driven subroutines are normally written by 
the user as needed and not used from a purchased library of subroutines. 

Pure Software Time Delay 

The subroutine named "softime" generates delays ranging from 1 to 65,535 milliseconds 
by using register R7 to generate the basic 1 millisecond delay. The call program loads the 
desired delay into registers A (LSB) and B (MSB) before calling Softime. 

The key to writing this program is to calculate the exact time each instruction will 
take at the clock frequency in use. For a crystal of 16 megahertz, each machine cycle 
(12 clock pulses) is 

12 pulses 
Cycle Time = = .75 us 

J 16,000,000 pulses/s ^ 

Should the crystal frequency be changed, the subroutine would have to have the internal 
timing loop number "delay" changed. 

Softime 

Softime will delay the number of milliseconds expressed by the binary number, from 1 to 
65,535d, found in registers A (LSB) and B (MSB). The call program loads the desired 
delay into registers A and B and calls Softime. Loading zeroes into A and B results in an 
immediate return. 

The number after the comma in the comments section of the following program is the 
number of cycles for that instruction. 

ADDRESS MNEMONIC COMMENT 

.equ delay, Oech ; for 996 /as time dela# = 222d 

softime: -org OOOOh ;set origin 

push 07h ;save R7 

push ace ; save A for A = B = 00 test 

orl a,b ;will be 00 if both 00 

cjne a,#00h,ok ;return if all 00 

pop ace ;keep stack balanced 

sjmp done 

ok: pop ace ;not all zeroes, proceed 

timer: mov r7,#delay ;initialize R7, 1 

onemil: nop ; tune the loop for 6 cycles, 1 

nop ;this makes 2 cycles total, 1 

nop ;3 cycles total, 1 

Continued 



112 



CHAPTER SEVEN 



ADDRESS MNEMONIC 

Continued 

nop 

djnz r7, onemil 

total delay is 6 cycles ( 

nop 

total delay is 999.75 /is, 
frequency used ( 1000 fis 



djnz ace, timer 
cjne a, b, bdown 
sjmp done 

bdown: dec b 

sjmp timer 

done : pop 07h 
ret 
. end 



COMMENT 

;4 cycles total, 1 

; count R7 down; 6 cycles total, 2 

(4.5 /as) x 222d = 999d ps. 

; tune subroutine .75 /xs more 

, which is as close as possible for the 
= 4000/3 cycles) 

; count A and B down as one 

;A = 00. count B down until = 00 

;if so then delay is done 

; count B down and time again 

; restore R7 to original value 
; return to calling routine 



COMMENT 



Note that register A, when used in a defined mnemonic is used as "A." When used as a direct 
address in a mnemonic (where any add could be used), the equate name ACC is used. The 
equate usage is also seen for R7, where the name of the register may be used in those mne- 
monics for which it is specifically defined. For mnemonics that use any add, the actual address 
must be used. 

The restriction on A = B - 00 is due to the fact that the program would initially count A from 
00 ... FFh ... 00 then exit. If it were desired to be able to use this initial condition for A and B, 
then an all zero condition could be handled by the test for 0000 used, set a flag for the condi- 
tion, decrement B from 00 to FFh the first time B is decremented, then reset the flag for the 
remainder of the program. 

The accuracy of the program is poorest for a 1 millisecond delay due to time delay for the rest 
of the program to set up and return. The actual delay if 0001 is passed to the subroutine is 
1014.75 microseconds or an error of 1.5 percent. 

Software Polled Timer 

A delay that uses the timers to generate the delay and a continuous software flag test 
(the flag is "polled" to see whether it is set) to determine when the timers have finished 
the delay is given in this section. The user program signals the total delay desired by pass- 
ing delay variables in the A and B registers in a manner similar to the pure software delay 
subroutine. A basic interval of I millisecond is again chosen so that the delay may range 
from I to 65,535 ms. 

The clock frequency for the timer is the crystal frequency divided by 12, or one 
machine cycle, which makes each count of the timer .75 microsecond for a 16 megahertz 
crystal. A I millisecond delay gives 

Count for 1000 microseconds = 1000/.75 = 1333.33 (1333) 

Due to the fraction, we can not generate a precise I millisecond delay using the crystal 
chosen. If accurate timing is important, then a crystal frequency that is a multiple of 12 



AN 8051 MICROCONTROLLER DESIGN 



113 



must be chosen. Twelve megahertz is an excellent choice for generating accurate time 
delays, such as for use in systems which maintain a time of day clock. 

Timer will be used to count 1333 (0535h) internal clock pulses to generate the basic 
1 millisecond delay; registers A and B will be counted down as TO overflows. The timer 
counts up, so it will be necessary to put the 2's complement of the desired number in the 
timer and count up until it overflows. 

Timer 

The time delay routine named "Timer" uses timer and registers A and B to generate 
delays from 1 to 65,535d milliseconds. The calling program loads registers A (LSB) and 
B (MSB) with the desired delay in milliseconds. Loading a delay of OOOOh results in an 
immediate return. 



ADDRESS 



timer: 



go: 

onems 

wait : 
dwnab 

bdown; 
done : 



MNEMONIC 

.equ onemshi.Ofah 

.equ onemslo,0cbh 

.org OOOOh 

push tlO 

push thO 

cjne a,#00h,go 

orl a,b 

jz done 

clr A 

anl tcon,#0cfh 

anl tmod,#0f0h 

orl tmod,#01h 

mov tl0,#onemslo 

mov thO , #onemshi 

orl tcon,#10h 

jbc tfO, dwnab 

sjmp wait 

anl tcon,#0efh 

djnz ace, onems 

cjne a, b, bdown 

sjmp done 

dec b 

sjmp onems 

pop thO 

pop tlO 

ret 

. end 

COMMENT 



COMMENT 

;2's complement of 535h = FACBh 

;set program origin 
;save timer contents 

; test for A = 00 

;A = 00, test for B = 00 

;A will be 00 if A = B = 00 

;B is not 00, clear A 

; clear timer overflow and run 

; flags in TC0N 

; clear TO part of TM0D, set TO for 

; timer operation, mode 1 (16 bit) 

;set TO to count up from FACBh 

; start timer 

;poll TO overflow flag 

;loop until TO overflows 

;stop TO 

; count A down and loop until zero 

;if A = B = 00 then done, return 

;decrement B and count again 

; restore TO contents 



TO cannot be used accurately for other timing or counting functions in the user program; thus, 
there is no need to save the TCON and TMOD bits for TO. TO itself could be used to store data; 
it is saved. 

This program has no inherent advantage over the pure software delay program; both take up 
all processor time. The software polled timer has a slight advantage in flexibility in that the 

Continued 



114 CHAPTER SEVEN 



COMMENT 

Continued 

number loaded into TO can be easily changed in the program to shorten or lengthen the basic 
timing loop. Thus, the call program could also pass the basic timing delay (in other memory 
locations) and get delays that could be programmed in microseconds or hours. 

One way for the program to continue to run while the timer times out is to have the program 
loop back on itself periodically, checking the timer overflow flag. This looping is the normal 
operating mode for most programs; if the program execution time is small compared with the 
desired delay, then the error in the total time delay will be small. 

Pure Hardware Delay 

If lengthy delays must be done or processor time is so valuable that no time can be wasted 
for even relatively short software delays, then the time delays must be done using a timer 
in the interrupt mode. The program given in this section operates in the following manner: 

1. The occurrence of a timer overflow will interrupt the processor, which then per- 
forms a hardware call to whatever subroutine is located at the dedicated timer 
flag interrupt address location in ROM. 

2. The subroutine determines whether the time delay passed by the using program 
is finished. (If not, an immediate return is done to the user program at the place 
where it was interrupted. If the delay is up, then a call to the user part of the 
program that needed the delay is done, followed by a return to the program 
where it was interrupted.) 

The time delay is initiated by the user program that stores the desired delay at an 
external RAM location named "Savetime," and then calls "Startime," which sets the 
timing in motion. The main program then runs while the delay is timing out. 

This type of program must use the manufacturer-specified dedicated interrupt loca- 
tions in ROM that contain the interrupt handling routines. For this reason, the user must 
have placed some set of instructions at the ROM interrupt location before incorporating 
the time delay subroutine program in the user program. 

In this example, the following three subroutines have been placed at the interrupt 
location in ROM: 

1 . Hardtime: a subroutine located at the timer flag interrupt location that determines 
whether the time delay has expired (If time has not expired, then the subroutine 
immediately returns to the main user program at the location where it was inter- 
rupted by the timer flag; if time is up, then it calls the user program, "Usertime.") 

2. Usertime: a subroutine, written by the user, that needed the delay (For this 
example, the subroutine is simply a return.) 

3. Stoptime: a subroutine that stops the timer 

■ Note: To the assembler, the name of the subroutine can be in any combination of 
uppercase or lowercase: for example, HARDTIME, hardtime, and HaRdTiMe are all 
read as the same label name. 

The hardware delay subroutine examined here uses timer 1 for the basic delay. When 
timer 1 overflows and sets the overflow flag, the program will vector to location 001 Bh in 
program memory if the proper bits in the interrupt control registers IE and IP are set. 

As in previous examples, the user can set timer 1 for delays of 1 to 65,535 milli- 
seconds by setting the desired delay in external RAM locations "Savetime" (LSB) and 
"Savetime" + 1 (MSB), which is a two-byte address pointed to by DPTR. Registers A 



AN 8051 MICROCONTROLLER DESIGN 



115 



and B cannot be used as in previous examples because to do so would preclude their use 
for any other purpose in the program. 

The hardware delay called "Hardtime" is listed in the following subsection. To avoid 
confusion as to which is the subroutine and which is the user program, all user code will 
begin with a label that starts with the name "User." Everything else is the timing routine. 

Hardtime 

The "Hardtime" subroutine is a hardware-only time delay. To start the delay, IE. 7 and 
IE. 3 (EA and ET1) must be set and the subroutine "Startime" called. Three instructions 
must be assembled at timer i location 001 Bh: LJMP hardtime, ACALL usertime (with the 
label "Userdly"), and ACALL stoptime. The priority of the interrupt can be set at bit 
IP.3 (PT1) to high (1) or low (0). An excerpt from the calling program follows to show 
these details: 



ADDRESS 

userpgm: 

userdly: 
userover 



here : 



MNEMONIC 

. equ savetime , OOlOh 

.org OOOOh 

sjmp userover 

.org OOlbh 

ljmp hardtime 

acall usertime 

acall stoptime 

reti 

mov dptr, #savetime 

mov a, #01h 

movx @dptr,a 

inc dptr 

mov a,#10h 

movx @dptr, a 

orl ie, #88h 

acall startime 

sjmp here 



COMMENT 

; external RAM address for delay 

; start user program 

; jump over interrupt addresses 

; interrupt location for TF1 

;jump to time delay subroutine 

;called if delay is up 

;dissable timer interrupt 

; return to main program 

; point to delay address 

; store desired delay, LSB first 

;point to next byte (MSB) 

;desired delay now stored 
;enable Tl and all interrupts 
; start time delay 
;loop to simulate user program 



the user program now continues while timer 1 runs until TF1 = 1. 
the interrupt generated will vector to location OOlBh and execute 
a jump to hardtime that will decrement the contents of savetime 
until the desired time delay has been done; hardtime will return to 
the main program if the delay is not finished, or to userdly if the 
delay is up; userdly returns to call stoptime, which stops the timer 
and returns to the RETI instruction for return to the main program 

;set Tl for a 1 ms delay 

;(see TIMER example) 

; clear Tl part of TMOD 

;set Tl to timer mode 1 

; start timer 1 

; return to calling program 

;save registers to be used 



startime : 


mov thl, #0fah 




mov til, #0cbh 




anl tmod,#0fh 




orl tmod,#40h 




orl tcon,#40h 




ret 


hardtime : 


push ace 




push dph 



Continued 



116 



CHAPTER SEVEN 



ADDRESS 

Continued 



aff: 



done : 



sava: 



MNEMONIC 

push dpi 

mov dptr, #savetime 

movx a,@dptr 

dec a 

cjne a,#OOh,aff 

movx @dptr,a 

inc dptr 

movx a,@dptr 

jz done 

sjmp sava 

cjne a,#Offh,sava 

movx @dptr,a 

inc dptr 

movx a, @dptr 

dec a 

sjmp sava 

pop dpi 

pop dph 

pop ace 

ljmp userdly 

movx @dptr,a 

pop dpi 

pop dph 

pop ace 

acall startime 

reti 



COMMENT 



:get pointer to time delay 

; count delay number down to 0000 

low byte first 

check for 0000 

save low byte = 00 

get high byte and look for 00 

done if low, high byte = 

not 0, delay again 

if low byte = FF dec high 

save low byte = FF 

point to high byte 

count high byte down 

save the high byte 
finished, jump to userdly 
restore all registers used 

continue at user delay 
delay not up, save byte 
restore saved registers 



start Tl for next 1 ms 
return to user program 



the user program "usertime" can now be written as needed; a return 
will be used to simulate the user routine . 



usertime: 



ret 



after the user program is done then "stoptime" will stop timer Tl 
and return to the interrupted main program 



stoptime : 



anl tcon,#0bfh 

ret 

.end 



;stop timer Tl 
; return to reti 



COMMENT 



The minimum usable delay is 1 ms because a 1 ms delay is done to begin the delay interrupt 
cycle. 

All timing routines can be assembled at interrupt location 001 Bh if stack space is limited. 

The RETI instruction is used when returning to the main program, after each interrupt, while 
RET instructions are used to return from caffed routines. 



There is no check for an initial delay of OOOOh. 



AN 8051 MICROCONTROLLER DESIGN 



117 



Lookup Tables for the 8051 



There are many instances in computing when one number must be converted into another 
number, or a group of numbers, on a one-to-one basis. A common example is to change an 
ASCII character for the decimal numbers to 9 into the binary equivalent (BCD) of those 
numbers. ASCII 30h is used to represent OOd, 31h is Old, and so on, until ASCII 39h is 
used for 09d. 

Clearly, one way to convert from ASCII to BCD is to subtract a 30h from the ASCII 
character. Another approach uses a table in ROM that contains the BCD numbers 00 to 
09. The table is stored in ROM at addresses that are related to the ASCII character that is 
to be converted to BCD. The ASCII character is used to form part of the address where its 
equivalent BCD number is stored. The contents of the address "pointed" to by the ASCII 
character are then moved to a register in the 8051 for further use. The ASCII character is 
then said to have "looked up" its equivalent BCD number. 

For example, using ASCII characters 30h to 39h we can construct the following pro- 
gram, at the addresses indicated, using ,db commands: 



ADDRESS 



MNEMONIC 

.org 1030h 
.db OOh 
.db Olh 
.db 02h 
.db 03h 
.db 04h 
.db 05h 
.db 06h 
.db 07h 
.db 08h 
.db 09h 



COMMENT 

; start table at 
; location 1030h 
; location 1031h 
; location 1032h 
; location 1033h 
; location 1034h 
; location 1035h 
; location 1036h 
; location 1037h 
; location 1038h 
; location 1039h 



ROM location 1030h 



contains 
contains 
contains 
contains 
contains 
contains 
contains 
contains 
contains 
contains 



00 BCD 

01 BCD 

02 BCD 

03 BCD 

04 BCD 

05 BCD 

06 BCD 

07 BCD 

08 BCD 

09 BCD 



Each address whose low byte is the ASCII byte contains the BCD equivalent of that ASCII 
byte. If the DPTR is loaded with lOOOh and A is loaded with the desired ASCII byte, then a 
MOVC A,@A+DPTR will move the equivalent BCD byte for the ASCII byte in A to A. 

Lookup tables may be used to perform very complicated data translation feats, in- 
cluding trigonometric and exponential conversions. While lookup tables require space 
in ROM, they enable conversions to be done very quickly, far faster than using computa- 
tional methods. 

The 8051 is equipped with a set of instructions that facilitate the construction and use 
of lookup tables: the MOVC A,@A+DPTR and the MOVC A,@A+PC. In both cases A 
holds the pointer, or some number calculated from the pointer, which is also called an 
"offset." DPTR or PC holds a "base" address that allows the data table to be placed at 
any convenient location in ROM. In the ASCII example just illustrated, the base address 
is lOOOh, and A holds an offset number ranging from 30h to 39h. 

Typically, PC is used for small "local" tables of data that may be included in the 
body of the program. DPTR might be used to point to large tables that are normally as- 
sembled at the end of program code. 

In both cases, the desired byte of data is found at the address in ROM that is equal to 
base + offset. Figure 7.6 demonstrates how the final address in the lookup table is calcu- 
lated using the two base registers. 



118 CHAPTER SEVEN 



FIGURE 7.6 MOVC ROM Address Calculations 



A + DPTR = Any Address From DPTR To DPTR + FFh > 



A Register 



DPTR = Any Number nn 



A + PC « Address From Nl To Nt + FFh 



A Register 



PC = Address Of Next Instruction 



DPTR + FFh 



DPTR + 01 h 



DPTR + OOh 



PC + FFh 



PC + 02h 



PC + Olh 



Next Instruction 



MOVC A, @A + PC 



MOVC A, @A+ DPTR 



MOV DPTR, #nn 



External ROM 



PC = Nl 



One limitation of lookup tables might be the appearance that only 256 different 
values — corresponding to the 256 different values that A might hold — may be put in 
a table. This limitation can be overcome by using techniques to alter the DPTR such that 
the base address is changed in increments of 256 bytes. The same offset in A can point 
to any number of data bytes in tables that differ only by the beginning address of the 
base. For example, by changing the number loaded in DPTR from lOOOh to 1 IOOh in the 
ASCII-to-BCD table given previously, the ASCII byte in A can now point to an entirely 
new set of conversion bytes. 

Both PC and DPTR base address programs are given in the examples that follow. 

PC as a Base Address 

Suppose that the number in A is known to be between OOh and OFh and that the number 
in A is to be squared. A could be loaded into B and a MUL AB done or a local lookup 
table constructed. 



AN 8051 MICROCONTROLLER DESIGN 



119 



The table cannot be placed directly after the MOVC instruction. A jump instruction 
must be placed between the MOVC and the table, or the program soon fetches the first 
data byte of the table and executes it as code. Remember also that the PC contains the 
address of the jump instruction (the Next Instruction, after the MOVC command) when 
the table address is computed. 

Pdook 

The program "pclook" looks up data in a table that has a base address in the PC and the 
offset in A. After the MOVC instruction, A contains the number that is the square of the 
original number in A. 



ADDRESS 

pclook: 



MNEMONIC 

.org OOOOh 
mov a,#0ah 
add a,#02h 
move a,@a+pc 
sjmp over 



COMMENT 

find the square of OAh (64h) 
adjust for two byte sjmp over 
get equivalent data from table to A 
jump over the lookup table 



the lookup table is inserted here, at PC + 2. (PC = 0005h 



over: 



.db OOh 
.db Olh 
.db 04h 
.db 09h 
.db lOh 
.db 19h 
.db 24h 
.db 31h 
.db 40h 
.db 51h 
.db 64h 
.db 79h 
.db 90h 
.db 0a9h 
.db 0c4h 
.db Oelh 
sjmp over 
. end 



begin table here, 00 A 2 = 00 

01 A 2 = Old 

02 A 2 = 04d 

03 A 2 = 09d 

04 A 2 = 16d 

05 A 2 = 25d 

06 A 2 = 36d 

07 A 2 = 49d 

08 A 2 = 64d 

09 A 2 = 81d 

0A A 2 - lOOd 

0B A 2 = 121d 

0C A 2 = 144d 

0D A 2 - 169d 

0E A 2 = 196d 

0F A 2 = 225d 

simulate rest of user program 



Figure 7.7 shows the assembled listing of this program and the resulting address of the 
table relative to the MOVC instruction. 



COMMENT 



The number added to A reflects the number of bytes in the SJMP instruction. If more code is 
inserted between the MOVC and the table, a similar number of bytes must be added. Adding 
bytes can result in overflowing A when the sum of these adjusting bytes and the contents of A 
exceed 255d. If this happens, the lookup data must be limited to the number of bytes found by 
subtracting the number of adjustment bytes from 255d. 



120 



CHAPTER SEVEN 



FIGURE 7.7 Lookup Table using the PC 



0000 

oooo 

0002 
0004 

0005 
0007 
0007 
0008 
0009 
000A 
OOOB 
OOOC 
OOOD 
OOOE 
OOOF 
0010 
0011 
0012 
0013 
0014 
0015 
0016 
0017 
0019 



740A pclook: 

2402 

83 



.org 0000b 
mov a,#Oah 
add a.#02h 
move a,@a+pc 



8010 sjmp over 

; the lookup table is inse 

00 .db OOh 

01 .db Olh 
04 .db 04h 

09 .db 09h 

10 .db lOh 
19 .db 19h 
24 .db 24h 
31 .db 3lh 
40 .db 40h 
51 .db 5lh 
64 .db 64h 
79 .db 79h 
90 .db 90h 
A9 .db 0A9h 
C4 .db 0C4h 
El .db OElh 
80F over: sjmp over 

.end 



;find the square of OAh (64h) 
;adjust for two byte sjmp over 
;get equivalent data from table 
;to A 

;jump over the lookup table 
rted here, at PC + 2 (PC = 0005h 
begin table here, 00 A 2 = 00 



01 A 2 


= 


Old 


02 A 2 


= 


04d 


03 A 2 


= 


09d 


04 A 2 


= 


16d 


05 A 2 


= 


25d 


06 A 2 


= 


36d 


07 A 2 


= 


49d 


08 A 2 


= 


64d 


09 A 2 


= 


81d 


OA A 2 


= 


lOOd 


0B A 2 


= 


121d 


0C A 2 


= 


I44d 


0D A 2 


= 


I69d 


0E A 2 


= 


I96d 


0F A 2 


= 


225d 



simulate rest of user program 



DPTR as a Base Address 

The DPTR is used to construct a lookup table in the next example. Remove the restriction 
that the number in A must be less than 10h and Jet A hold any number from OOh to FFh. 
The square of any number larger than OFh results in a four-byte result; store the result in 
registers RO (LSB) and Rl (MSB). 

Two tables are constructed in this section: one for the LSB and the second for the 
MSB. A points to both bytes in the two tables, and the DPTR is used to hold two base 
addresses for the two tables. The entire set of two tables, each with 256 entries, will not be 
constructed for this example. The beginning and example values are shown as a skeleton 
of the entire table. 

Dp took 

The lookup table program "dplook" holds the square of any number found in the A regis- 
ter. The result is placed in RO (LSB) and Rl (MSB). A is stored temporarily in Rl in order 
to point to the MSB byte. 



ADDRESS MNEMONIC 

.equ lowbyte,0200h 
.equ hibyte,0300h 
.org OOOOh 



COMMENT 

;base address of LSB table 
;base address of MSB table 



Continued 



AN 8051 MICROCONTROLLER DESIGN 



121 



ADDRESS MNEMONIC 

dplook: mov a,#5ah 

mov rl.a 

mov dptr, #lowbyte 

move a,@a+dptr 

mov r0 , a 

mov a.rl 

mov dptr, #hibyte 

move a,@a+dptr 

mov rl.a 
here: sjmp here 

.org lowbyte 

.db OOh 

.db Olh 
;place rest of table up to the 

.org lowbyte + 5ah 

.db 0a4h 
;place rest of LSB table here 

.org hibyte 

.db OOh 

.db OOh 
;place rest of table up to the 

.org hibyte + 5ah 

.db lfh 
;place rest of MSB table here 

.end 



COMMENT 

;find the square of 5Ah (lFA4h) 
;store A for later use 
;set DPTR to base address of LSB 
;get LSB 

; store LSB in R0 
; recover A for pointing to MSB 
;set DPTR to base address of MSB 
;get MSB 

; store MSB in Rl 
; simulate rest of user program 
; place LSB table starting here 
;00 A 2 = 0000 
;01 A 2 = 0001 
LSB of 59 A 2 here 

;put LSB of 5A A 2 here 
;LSB is A4h 

place MSB table starting here 

00 A 2 = 0000 

01 A 2 = 0001 
MSB of 59 A 2 here 

;put MSB of 5A A 2 here 
;MSB is lFh 



£>— COMMENT 



Note that there are no jumps to "get over" the tables; the tables are normally placed at the end 
of the program code. 

A does not require adjustment; DPTR is a constant. 

Figure 7.8 shows the assembled code; location 025Ah holds the LSB of 5A A 2, and 
location 035Ah holds the MSB. 



Serial Data Transmission 



The hallmark of contemporary industrial computing is the linking together of multiple 
processors to form a "local area network" or LAN. The degree of complexity of the LAN 
may be as simple as a microcontroller interchanging data with an I/O device, as compli- 
cated as linking multiple processors in an automated robotic manufacturing cell, or as 
truly complex as the linking of many computers in a very high speed, distributed system 
with shared disk and I/O resources. 

All of these levels of increasing sophistication have one feature in common: the need 
to send and receive data from one location to another. The most cost-effective way to meet 
this need is to send the data as a serial stream of bits in order to reduce the cost (and bulk) 
of multiple conductor cable. Optical fiber bundles, which are physically small, can be 
used for parallel data transmission. However, the cost incurred for the fibers, the termina- 
tions, and the optical interface to the computer currently prohibit optical fiber use, except 
in those cases where speed is more important than economics. 



122 



CHAPTER SEVEN 



FIGURE 7.8 Lookup Table using the DPTR 



0200 
0300 

oooo 

0000 745A dplook 

0002 F9 

0003 900200 

0006 93 

0007 F8 

0008 E9 

0009 900300 

000C 93 
000D F9 
OOOE 80FE here: 

0200 



. equ lowbyte , 0200h 
.equ hibyte,0300h 
.org OOOOh 
mov a,#5ah 

mov rl.a 

mov dptr , #lowbyte 

move a, @a + dptr 
mov rO , a 
mov a,rl 

mov dptr,#hibyte 

move a.@a + dptr 
mov rl.a 
sjmp here 

.org lowbyte 



0200 


00 




.db OOh 


0201 


01 




.db Olh 


0202 




; place 


rest of table up to the 


025A 






.org lowbyte + 5ah 


025A 


A4 




.db 0a4h 


025B 




; place 


rest of LSB table here 


0300 






.org hibyte 


0300 


00 




.db OOh 


0301 


00 




.db OOh 


0302 




;place 


rest of table up to the 


035A 






.org hibyte + 5ah 


035A 


IF 




.db lfh 


035B 




;place 


rest of MSB table here 


035B 






.end 



;base address of LSB table 
;base address of MSB table 

; find the square of 5Ah 
; <lFA4h) 

; store A for later use 
;set DPTR to base address 
;of LSB 
;get LSB 

; store LSB in RO 
; recover A for pointing 
;to MSB 

;set DPTR to base address 
;of MSB 
;get MSB 

; store MSB in Rl 
;simulate rest of user 
; program 

;place LSB table starting 
;here 

;00 A 2 = 0000 
;01 A 2 - 0001 
LSB of 59 A 2 here 
;put LSB of 5A A 2 here 
;LSB is A4h 

place MSB table starting 

here 

00 A 2 = 0000 

01 A 2 = 0001 
MSB of 59 A 2 here 
;put MSB of 5A"2 here 
;MSB is lFh 



So pervasive is serial data transmission that special integrated circuits, dedicated solely 
to serial data transmission and reception, appeared commercially in the early 1970s. These 
chips, commonly called "universal asynchronous receiver transmitters," or UARTS, per- 
form all the serial data transmission and reception timing tasks of the most popular data 
communication scheme still in use today: serial 8-bit ASCII coded characters at pre- 
defined bit rates of 300 to 19200 bits per second. 

Asynchronous transmission utilizes a start bit and one or more stop bits, as shown 
in Figure 7.9, to alert the receiving unit that a character is about to arrive and to signal 
the end of a character. This "overhead" of extra bits, with the attendant slowing of data 
byte rates, has encouraged the development of synchronous data transmission schemes. 
Synchronous data transmission involves alerting the receiving unit to the arrival of data 



AN 8051 MICROCONTROLLER DESIGN 



123 



FIGURE 7.9 Asynchronous 8-Bit Character 

Idle State 

™T T 



r 

i I 



Start 
Bit 



Bit Time = 



1 j j r T T 

3|4I5I6|7|8| 
I J _L _L J J 

Data Bits 

t » 



Idle State 



Stop 
Bit 



by a unique pattern that starts data transmission, followed by a long string of characters. 
The end of transmission is signaled by another unique pattern, usually containing error- 
checking characters. 

Each scheme has its advantages. For relatively short or infrequent messages, the 
asynchronous mode is best; for long messages or constant data transmission, the synchro- 
nous mode is superior. 

The 8051 contains serial data trans mission /receiver circuitry that can be programmed 
to use four asynchronous data communication modes numbered from to 3. One of these, 
mode 1, is the standard UART mode, and three simple asynchronous communication pro- 
grams using this mode will be developed here. More complicated asynchronous programs 
that use all of the communication modes will be written in Chapter 9. 

Character Transmission Using a Time Delay 

Often data transmission is unidirectional from the microcontroller to an output device, 
such as a display or a printer. Each character sent to the output device takes from 33.3 
to .5 milliseconds to transmit, depending upon the baud rate chosen. The program must 
wait until one character is sent before loading the next, or data will be lost. A simple way 
to prevent data loss is to use a time delay that delays the known transmission time of one 
character before the next is sent. 



ADDRESS 



Sendchar 

A program called "Sendchar" takes the character in the A register, transmits it, delays for 
the transmission time, and then returns to the calling program. Timer 1 must be used to set 
the baud rate, which is 1200 baud in this example. The delay for one ten-bit character 
is 1000/120 or 8.4 milliseconds. The software delay developed in Section 7.5 is used for 
the delay with the basic delay period of 1 milliseconds changed to .1 milliseconds by re- 
defining "delay." Timer I needs to generate a final baud rate of 1200 at SBUF. Using a 
16 megahertz crystal, the reload number is 256 - 16E6/(16 x 12 x 1200), which is 
186.6 or integer 187. This yields an actual rate of 1208. 



here : 



MNEMONIC 

.org OOOOh 
.set delay, 16h 
mov a , # * A ' 
acall sendchar 
sjmp here 



COMMENT 

;basic delay = 22d x 4.5 = 99 /as 

; for this example, send an A 

; send it 

; simulate rest of user program 



Continued 



124 



CHAPTER SEVEN 



ADDRESS 

Continued 

sendchar : 



MNEMONIC 

anl tcon,#Ofh 
orl tcon,#20h 
mov thl,#0bbh 
orl pcon,#80h 
orl tcon,#40h 
mov scon,#40h 
mov sbuf.a 
mov a,#54h 
acall softime 
ret 



COMMENT 

;alter timer 1 configuration only 

; set timer 1 for mode 2 (auto reload) 

;set reload number to 187d (256 - 69 

;set SMOD bit to 1 

;start timer 1 by setting TR1 

;set serial port to mode 1 

;load transmit register and wait 

; delay for 8.4 ms (84d = 54h) 

; wait 

; character now sent 



;softime will be simulated by a return instruction 
softime : ret 

.end ; assembler use only 



{>— COMMENT 



If timer 1 and the serial port have different uses in the user program, then push and pop 
affected control registers. But remember, T1 and SBUF can only be used for one function at any 
given time. 

The use of the .set statement lets the user change the basic delay interval to different values in 
the same program. 

The 16 megahertz crystal does not yield convenient standard baud rates of 300, 1200, 2400, 
4800, 9600, or 19200. The errors using this crystal for these rates are given in the following 
table: 



RATE 


ERROR (%) 


300 


.08 


1200 


.64 


4800 


2.12 


9600 


3.55 


19200 


8.51 



The error grows for higher baud rates as ever smaller reload numbers are rounded to 
the nearest integer. Using an 11.059 megahertz crystal reduces the errors to less than 
.002 percent at the cost of speed of program execution. 

Character Transmission by Polling 

An alternative to waiting a set time for transmission is to monitor the TI flag in the SCON 
register until it is set by the transmission of the last character written to SBUF. The polling 
routine must reset TI before returning to the call program. Failure to reset TI will inhibit 
all calls after the first, stopping all data transmission except the first character. 

This technique has the advantage of simplicity; less code is used, and the routine does 
not care what the actual baud rate is. In this example, it is assumed that the timer 1 baud 
rate has been established at the beginning of the program in a manner similar to that used 
in the previous example. 



AN 8051 MICROCONTROLLER DESIGN 



125 



Xmit 

The subroutine "xmit" polls the TI flag in the SCON register to determine when SBUF is 
ready for the next character. The calling part of the user program follows: 



ADDRESS 



here : 

xmit : 
wait: 



MNEMONIC 

.org OOOOh 
mov a, #'3* 
acall xmit 
sjmp here 

mov sbuf.a 

jnb scon. 1 .wait 

clr scon.l 

ret 

. end 



COMMENT 

; send an ASCII 3 for this example 

;send the character using xmit 

; simulate remainder of user program 

; transmit the contents of A and wait 
;loop until TI = 1 (SBUF is empty) 
; reset TI to 



£>— COMMENT 



TI remains a until SBUF is empty; when the 8051 is reset, or upon power up, TI is set to 0. 

Interrupt-Driven Character Transmission 

The third method of determining when transmission is finished is to use the interrupt 
structure of the 8051. One interrupt vector address in program code, location 0023h, is 
assigned to both the transmit interrupt, TI, and the receive interrupt, RI. When a serial 
interrupt occurs, a hardware call to location 0023h accesses the interrupt handling routine 
placed there by the programmer. 

The user program "calls" the subroutine by loading the character to be sent into 
SBUF and enabling the serial interrupt bit in the EI register. The user program can then 
continue executing. When SBUF becomes empty, TI will be set, resulting in an immedi- 
ate vector to 0023h and the subroutine placed there executed. The subroutine at 0023h, 
called "serial," will reset TI and then return to the user program at the place where it was 
interrupted. 

This scheme is satisfactory for testing the microprocessor when only one character is 
sent from the program. Long strings of character transmission will overload SBUF. Chap- 
ter 9 contains routines that will build on this technique and send arbitrarily long strings 
with no loss of data. 

SBUFR 

An interrupt-driven data transmission routine for one character which is assembled at the 
interrupt vector location 0023h. A portion of the user program that activates the interrupt 
routine is shown. 



ADDRESS 

sbufr : 



MNEMONIC 

.org OOOOh 
sjmp user 
.org 0023h 



COMMENT 

;jump over interrupt vectors 

;put serial interrupt routine here 



Continued 



126 



CHAPTER SEVEN 



ADDRESS 

Continued 

serial : 



user: 
here : 



MNEMONIC 

clr scon.l 
reti 

mov sbuf,#*X 
orl ie,#90h 
sjmp here 
.end 



COMMENT 

; clear TI 

; return to interrupted user program 

.send an X in this example 

; enable serial interrupt 

; simulate remainder of program 



{>— COMMENT 



If TI is not cleared before the RETI instruction is used, there will be an immediate interrupt and 
vector back to 0023h. 

RETI is used to reset the entire interrupt structure, not to clear any interrupt bits. 

Receiving Serial Data 

Transmissions from outside sources to the 8051 are not predictable unless an elaborate 
time-of-day clock is maintained at the sender and receiver. Messages can then be sent at 
predefined times. A time-of-day clock generally ties up timers at both ends to generate the 
required "wake-up" calls. 

Two methods are normally used to alert the receiving program that serial data has 
arrived: software polling or interrupt driven. The sending entity, or "talker," transmits 
data at random times, but uses an agreed-upon baud rate and data transmission mode. The 
receiving unit, commonly dubbed the "listener," configures the serial port to the mode 
and baud rate to be used and then proceeds with its program. 

If one programmer were responsible for the talker and another for the listener, lively 
discussions would ensue when the units are connected and data interchange does not take 
place. One common method used to test communication programs is for each programmer 
to use a terminal to simulate the other unit. When the units are connected for the final test, 
a CRT terminal in a transparent mode, which shows all data transmitted in both direc- 
tions, is connected between the two systems to show what is taking place in the communi- 
cation link. 

Polling for Received Data 

Polling involves periodically testing the received data flag Rl and calling the data receiving 
subroutine when it is set. Care must be taken to remember to reset RI, or the same character 
will be read again. Reading SBUF does not clear the data in SBUF or the RI flag. 

The program can sit in a loop, constantly testing the flag until data is received, or run 
through the entire program in a circular manner, testing the flag on each circuit of the 
program. The loop approach guarantees that the data be read as soon as it is received; 
however, very little else will be accomplished by the program while waiting for the data. 
The circular approach lets the program run while awaiting the data. 

In order not to miss any data, the circular approach requires that the program be able 
to run a complete circuit in the time it takes to receive one data character. The time re- 
straint on the program is not as stringent a requirement as it may first appear. The receiver 
is double buffered, which lets the reception of a second character begin while a previous 
character remains unread in SBUF. If the first character is read before the last bit of the 



AN 8051 MICROCONTROLLER DESIGN 



127 



second is complete, then no data will be lost. This means that, after a two-character burst, 
the program still must finish in one-character time to catch a third. 

The character time is the number of bits per character divided by the baud rate. For 
serial data transmission mode I , a character uses ten bits: start, eight code bits, and stop. 
A 1 200 baud rate, which might be typical for a system where the talker and listener do not 
interchange volumes of data, results in a character rate of 1 20 characters per second , or a 
character time of 8.33 milliseconds. Using an average of 18 oscillator periods per instruc- 
tion, each instruction will require 1.13 microseconds to execute, enabling a program 
length of 7371 instructions. This large machine language program will suffice for many 
simple control and monitoring applications where data transmission rates are low. If more 
time is needed, the baud rate could be reduced to as low as 300 baud, yielding a program 
size of over 29K bytes, which approaches half the maximum size of the ROM in our ex- 
ample 8051 design. 

The polling program for the loop approach follows: 



ADDRESS 

here : 



MNEMONIC 

jnb scon. 0, here 
clr scon.O 
acall getchar 



COMMENT 

wait here until RI = 1 
clear the RI bit 
getchar is some user routine 
which reads SBUF 



The circular approach is very similar: 



ADDRESS MNEMONIC 

jnb scon.O there 
clr scon.O 
acall getchar 
there: sjmp there 

ret 
.end 



COMMENT 

; test for RI = 1, go on if not 

;clear the RI bit 

;call user routine 

;rest of user program getchar: 

; simulate user routine 



Interrupt-Driven Data Reception 

When large volumes of data must be received, the data rate will overwhelm the polling 
approach unless the user program is extremely short, a feature not usually found in sys- 
tems in which large amounts of data are interchanged. Interrupt -driven systems allow the 
program to run with brief pauses to read the received data. In Chapter 9, a program is 
developed that allows for the reception of long strings of data in a manner completely 
transparent to the user program. 

Intdat 

This interrupt-driven data reception subroutine assembles the program at 0023h, which is 
the serial interrupt vector location. 



ADDRESS 

intdat : 



MNEMONIC 

.org OOOOh 
orl ie,#90h 
sjmp over 



COMMENT 

; enable serial and all interrupts 
;jump over the interrupt locations 



Continued 



128 



CHAPTER SEVEN 



ADDRESS 

Continued 



xmit : 

over : 

trans: 
recv: 



MNEMONIC 

.org 0023h 

jbc scon. 1, xmit 

clr scon.O 

lcall recv 

reti 

lcall trans 

reti 

sjmp over 

ret 

ret 



COMMENT 

;put serial interrupt program here 

;if TI bit set, clear it and jump 

;must have been RI, clear it 

;call receive subroutine 

; return to program where interrupted 

;call transmit program 

; return to program where interrupted 

; dummy transmit /receive routines 



COMMENT 



If both RI and TI are set, this routine will service the transmit function first. After the RETI, which 
follows the LCALL to trans, the RI bit will still be set, causing an immediate interrupt back to 
location 0O23h where the receive routine will be called. 

If the transmit or receive subroutines that are called take longer to execute than the character 
time, then data will be lost. Long subroutine times would be highly unusual; however, it is 
possible to overload any system by constant data reception. 



Summary 



An 8051 based microprocessor system has been designed that incorporates many features 
found in commercial designs. The design can be easily duplicated by the reader and uses 
external EPROM and RAM so that test programs may be exercised. Various size memo- 
ries may be used by the impecunious to reduce system cost. 
The design features are 

External RAM: 8K to 32K bytes 
External ROM: 8K to 64K bytes 
I/O ports: 1-8 bit, port 1 

Other ports: port 3.0 (RXD) 

3.1 (TXD) 

3.2 ( INTO ) 

3.3 (INT1) 

3.4 (TO) 

3.5 (TI) 

Crystal: 16 megahertz 

Other crystal frequencies may be used to generate convenient timing frequencies. The 
design can be modified to include a single step capability (see Problem 2). 

Methods of adding additional ports to the basic design are discussed and several ex- 
ample circuits that indicate the expansion possibilities of the 8051 are presented. 

Programs written to test the design can be used to verify any prototypes that are built 
by the reader. These tests involve verifying the proper operation of the ROM and RAM 
connections. 



AN 8051 MICROCONTROLLER DESIGN 129 

Several programs and subroutines are developed that let the user begin to exercise the 
8051 instruction code and hardware capabilities. This code can be run on the simulator or 
on an actual prototype. These programs cover the most common types found in most 
applications: 

Time delays: software; timer, software polled; timer, interrupt driven 
Lookup Tables: PC base, DPTR base 

Serial data communications transmission: time delay, software polled, interrupt 

driven 

Serial data communications reception: software polled, interrupt driven 

The foundations laid in this chapter will be built upon by example application pro- 
grams and hardware configurations found in Chapters 8 and 9. 

Problems 

1. Determine whether the 8051 can be made to execute a single program instruction 
(single -stepped) using external circuitry (no software) only. 

2. Outline a scheme for single-stepping the 8051 using a combination of hardware and 
software. (Hint: use an INTX.) 

3. While running the EPROM test, it is found that the program cannot jump from 2000h to 
4000h successfully. Determine what address line(s) is faulty. 

4. Calculate the error for the delay program "Softime" when values of 2d, lOd and lOOOd 
milliseconds are passed in A and B. 

5. The program "Softime" has a bug. When A = OOh the delay becomes: (B + l)d x 256d x 
delay. Find the bug and fix it without introducing a new bug. 

6. Find the shortest and longest delays possible using "Softime" by changing only the 
equate value of the variable "delay." 

7. Give a general description of how you would test any time delay program. (Hint: use a 
port pin.) 

8. In the discussion for the program named "Timer," the statement is made that an accurate 
1 ms delay cannot be done due to the need for a count of 1333.33 using a 16 megahertz 
clock. Find a way to generate an accurate 60 second delay using TO for the basic delay 
and some registers to count the TO overflows. 

9. Calculate the shortest and longest delays possible using the program named "Timer" by 
changing the initial value of TO. 

10. Why is there no check for an initial timing value of OOOOh in the program named 
"Hardtime"? 

11. Write a lookup table program, using the PC as the base, that finds a one-byte square root 
(to the nearest whole integer) of any number placed in A. For example, the square roots 
of 01 and 02 are both 01 , while the roots of 03 and 04 are 02. Calculate the first four 
and last four table values. 

12. Write a lookup table, using the DPTR as the base, that finds a two-byte square root of 
the number in A. The first byte is the integer value of the root, and the second byte is the 
fractional value. For example, the square root of 02 is 01 ,6Ah. Calculate four first and 
last table values. 



130 CHAPTER SEVEN 



13. Write a lookup table program that converts the hex number in A (0-F) to its ASCII 
equivalent. 

14. A PC based lookup table, which contains 256d values, is placed 50h bytes after the 
MOVC instruction that accesses it. Construct the table, showing where the byte associ- 
ated with A = OOh is located. Find the largest number which can be placed in A to 
access the table. 

15. Construct a lookup table program that converts the hex number in A to an equivalent 
BCD number in registers R4 (MSB) and R5 (LSB). 

16. Reverse Problem 15 and write a lookup table program that takes the BCD number in R4 
(MSB) and R5 (LSB) and converts it to a hex number in A. 

17. Verify the errors listed for the 16 megahertz crystal in the third comment after the pro- 
gram named "Sendchar." 

18. Verify the error listed for the 1 1 .059 megahertz crystal in the fourth comment after the 
program named "Sendchar." 

19. Does asynchronous communication between two microprocessors have to be done at 
standard baud rates? Name one reason why you might wish to use standard rates. 

20. Write a test program that will "loop test" the serial port. The output of the serial port 
(TXD) is connected to the input (RXD), and the test program is run. Success is indicated 
by port I pin 1 going high. 

21. What is the significance of the transmit flag, TI, when it is cleared to 0? When set to 1? 

22. Using the programmable port of Figure 7.3, write a program that will configure all ports 
as outputs, and write a 55h to each. 

23. Repeat problem 22 using the memory-mapped programmable port of Figure 7.4. 




Applications 



Chapter Outline 

Introduction 

Keyboards 

Displays 

Pulse Measurement 



Multiple Interrupts 
Putting it all Together 
Summary 



Introduction 



131 



Microcontrollers tend to be underutilized in many applications. There are several reasons 
for this anomaly. Principally, the devices are so inexpensive that it makes little economic 
sense to try to select an optimal device for each application. A new microcontroller in- 
volves the expense of new development software and training for the designers and pro- 
grammers that could easily cost more than the part savings. Also, some members of the 
technical community are unfamiliar with the microcontroller due to a dearth of established 
academic course offerings on the subject. These individuals tend to apply classic eight-bit 
microprocessor families to problems that are more economically served by a micro- 
controller. Finally, there is always the pressure to use the latest multibyte processor for 
marketing reasons or just to keep up with the "state of the art." 

The result of this application pattern is that microcontrollers tend to become obsolete at 
a slower rate than their CPU cousins. The microcontroller will absorb more eight-bit CPU 
applications as the economic advantage of using microcontrollers becomes compelling. 

Application examples in a textbook present a picture of use that supports the previ- 
ously-made claim of underutilization. Limitations on space, time, and the patience of the 
reader preclude the inclusion of involved, multi-thousand line, real-time examples. We 
will, instead, look at pieces of larger problems, each piece representing a task commonly 
found in most applications. 

One of the best ways to get a "feel" for a new processor is to examine circuits and 
programs that address easily visualized applications and then to write variations. To assist 



132 CHAPTER EIGHT 



Keyboards 



in this process, we will study in detail the following typical hardware configurations and 
their accompanying programs: 

Keyboards 

Displays 

Pulse measurements 

A/D and D/A conversions 

Multi-source interrupts 

The hardware and software are inexorably linked in the examples in this chapter. The 
choice of the first leads to the programming techniques of the second. The circuit designer 
should have a good understanding of the software limitations faced by the programmer. 
The programmer should avoid the temptation of having all the tricky problems handled by 
the hardware. 



The predominant interface between humans and computers is the keyboard. These range 
in complexity from the "up-down" buttons used for elevators to the personal computer 
QWERTY layout, with the addition of function keys and numeric keypads. One of the 
first mass uses for the microcontroller was to interface between the keyboard and the main 
processor in personal computers. Industrial and commercial applications fall somewhere 
in between these extremes, using layouts that might feature from six to twenty keys. 

The one constant in all keyboard applications is the need to accommodate the human 
user. Human beings can be irritable. They have little tolerance for machine failure; watch 
what happens when the product isn't ejected from the vending machine. Sometimes they 
are bored, or even hostile, towards the machine. The hardware designer has to select keys 
that will survive in the intended environment. The programmer must write code that will 
anticipate and defeat inadvertent and also deliberate attempts by the human to confuse the 
program. It is very important to give instant feedback to the user that the key hit has been 
acknowledged by the program. By the light a light, beep a beep, display the key hit, or 
whatever, the human user must know that the key has been recognized. Even feedback 
sometimes is not enough; note the behavior of people at an elevator. Even if the "up" light 
is lit when we arrive, we will push it again to let the machine know that "I'm here too." 

Human Factors 

The keyboard application program must guard against the following possibilities: 

More than one key pressed (simultaneously or released in any sequence) 
Key pressed and held 
Rapid key press and release 

All of these situations can be addressed by hardware or software means; software, which 
is the most cost effective, is emphasized here. 

Key Switch Factors 

The universal key characteristic is the ability to bounce: The key contacts vibrate open 
and close for a number of milliseconds when the key is hit and often when it is released. 
These rapid pulses are not discernable to the human, but they last a relative eternity in 



APPLICATIONS 



133 



the microsecond-dominated life of the microcontroller. Keys may be purchased that do 
not bounce, keys may be debounced with RS flip-flops, or debounced in software with 
time delays. 

Keyboard Configurations 

Keyboards are commercially produced in one of the three general hypothetical wiring con- 
figurations for a 16-key layout shown in Figure 8.1. The lead-per-key configuration is 
typically used when there are very few keys to be sensed. Since each key could tie up a 
port pin, it is suggested that the number be kept to 16 or fewer for this keyboard type. This 
configuration is the most cost effective for a small number of keys. 

The X- Y matrix connections shown in Figure 8.1 are very popular when the number 
of keys exceeds ten. The matrix is most efficient when arranged as a square so that N leads 
for X and N leads for Y can be used to sense as many as N 2 keys. Matrices are the most 
cost effective for large numbers of keys. 

FIGURE 8.1 Hypothetical Keyboard Wiring Configurations 

Key Key 1 Key 2 Key 3 Key 4 Key 5 Key 6 Key 7 

• «-lf •-!• *-!• «-J# ©-If •"-»• #-!• «-J 



Common 



Key 8 Key 9 Key A Key B Key C Key D Key E Key F 

f »Jf »-ly »-ly •-ly #Jy •-! f #Jy «J 



(a) Lead • Per - Key Keyboard 



RowO 



Rowl 



Row 2 



Row 3 



KeyO 



Keyl 
_L_ 



Key 2 Key 3 



1 



Key 4 



1 



Key 8 



1_T 



KeyC 
_L_ 



1 



Key 5 



T - 



Key 9 



T - 



KeyD 



T 



1 



Key 6 



1 



Key A 



1 



KeyE 



1 



J 



Key 7 



J 



KeyB 



1 



KeyF 



J 



1 2 

Columns 
(b)X-Y Matrix Keyboard 



Continued 



134 CHAPTER EIGHT 



FIGURE 8.1 Continued 



KeyO 
_J_ 



Common 



Key 4 



M 



Key 8 



KeyC 



Key 1 Key 2 Key 3 
_J I l_ 



T T t T T T I 



Key 5 



H 



Key 9 
_l_ 



KeyD 



Key 6 
_1_ 



H 



Key A 
_i_ 



KeyE 

_L_ 



T T 



i 



Key 7 



H 



KeyB 

_L_ 



KeyF 



I 



Rows 



Columns 
(c) Coded Keyboard 



Coded keyboards were evolved originally for telephonic applications involving touch- 
tone signaling. The coding permits multiple key presses to be easily detected. The quality 
and durability of these keypads are excellent due to the high production volumes and in- 
tended use. They are generally limited to 16 keys or fewer, and tend to be the most expen- 
sive of all keyboard types. 

Programs for Keyboards 

Programs that deal with humans via keyboards approach the human and keyswitch factors 
identified in the following manner: 

Bounce: A time delay that is known to exceed the manufacturer's specification is 
used to wait out the bounce period in both directions. 

Multiple keys: Only patterns that are generated by a valid key pressed are ac- 
cepted — all others are ignored — and the first valid pattern is accepted. 



APPLICATIONS 



135 



Key held: Valid key pattern accepted after valid debounce delay; no additional keys 
accepted until all keys are seen to be up for a certain period of time. 

Rapid key hit: The design is such that the keys are scanned at a rate faster than any 
human reaction time. 

The last item brings up an important point: Should the keyboard be read as the pro- 
gram loops (software polled) or read only when a key has been hit (interrupt driven)? 

In general, the smaller keyboards (lead-per-key and coded) can be handled either 
way. The common lead can be grounded and the key pattern read periodically. Or, the 
lows from e ach can be active-low ORed, as shown in Figure 8.2, and connected to one of 
the external INTX pins. 

Matrix keyboards are scanned by bringing each X row low in sequence and detecting 
a Y column low to identify each key in the matrix. X-Y scanning can be done by using 
dedicated keyboard scanning circuitry or by using the microcontroller ports under pro- 
gram control. The scanning circuitry adds cost to the system. The programming approach 
takes processor time, and the possibility exists that response to the user may be sluggish if 
the program is busy elsewhere when a key is hit. Note how long your personal computer 
takes to respond to a break key when it is executing a print command, for instance. The 
choice between adding scanning hardware or program software is decided by how busy the 
processor is and the volume of entries by the user. 



FIGURE 8.2 Lead-per-Key and Coded Keyboard Interrupt Circuits 



To Port Pins 



KeyO 
Key 1 



Common Lead 



Lead -Per -Key 
Keyboard 



KeyF 



AAAr 



+ 5V 



■VW 



■•+5V 



To INTX 



W 



•♦+5V 



Common Lead 



Two-Of-Eight 5 

Coded Keyboard g 

7 

8 



To Port Pins 



+ 5V 



■A/W 



■W* — 



AWV 



AAA^ 



To INTX 



To Port Pins 



136 



CHAPTER EIGHT 



A Scanning Program for Small Keyboards 

Assume that a lead-per-key keyboard is to be interfaced to the microcontroller. The key- 
board has ten keys (0-9), and the debounce time, when a key is pressed or released, is 20 
milliseconds. The keyboard is used to select snacks from a vending machine, so the pro- 
cessor is only occupied when a selection is made. The program constantly scans the key- 
board waiting for a key to be pressed before calling the vending machine actuator sub- 
routine. The keys are connected to port 1 (0-7) and ports 3.2 and 3.3 (8-9), as shown in 
Figure 8.3. 

The 8031 works best when handling data in byte-sized packages. To save internal 
space, the ten-bit word representing the port pin configuration is converted to a single-byte 
number. 

Because the processor has nothing to do until the key has been detected, the time 
delay "Softime" (see Chapter 7) is used to debounce the keys. 



Getkey 

The routine "Getkey" constantly scans a ten-key pad via ports and 3. The keys are 
debounced in both directions and an "all-up" period of 50 milliseconds must be seen be- 
fore a new key will be accepted. Invalid key patterns (more than one port pin low) are 
rejected. 

FIGURE 8.3 Keyboard Configuration for "Getkey" and "Inkey" Programs 

KeyO 

4 




8031 



APPLICATIONS 



137 



ADDRESS 



getkey: 



scan: 



wait : 



MNEMONIC 

.equ bounce, 14h 
.equ next,32h 

.equ newkey,70h 

.equ flag.OOh 

.org OOOOh 
mov pl,#Offh 
mov p3,#0ffh 
acall keydown 
jz scan 
acall convert 

jbc flag, scan 
mov newkey,a 

mov a,#bounce 
acall sof time 
acall keydown 
jz scan 

acall convert 

jbc flag, scan 
cjne a, newkey , scan 
acall vendit 
acall keydown 
jnz wait 
mov a,#next 

acall softime 
acall keydown 
jnz wait 
sjmp scan 



COMMENT 

set debounce delay to 20d ms 

set interval between keys to 

50d ms 

store accepted key in internal RAM 

addressable bit 00 used as a flag 

;set ports 1 and 3 as inputs 

keydown looks for any key(s) down 

if A = then no key(s) down; loop 

convert returns flag set if not 

valid 

or A set to 00 to 09 for keys 0-9 

store key and wait for debounce 

time 

then check to see if same key 

wait 20 ms 

see if a key is still down 

if not down then must have been 

noise 

see if key is still valid and 

matches 

the original key found 

check for equal 

call vending machine subroutine 

now wait for all keys to go up 

wait until A = 00 : keys all up 

wait 50d ms and see if all 

still up 

continue until keys are up 
loop until keys up for 50d ms 
get next key 



"keydown" gets the contents of PI and P3 pins, which are connected 
to the keys, and checks for any zero bits; no check is made to see 
if more than one bit is low 



;get state of PI keys to R0 

;get state of P3 keys to A 

;make bits 0,1, and 4-7 a one 

; check for any one or more keys 

;down 

;A = FFh if all keys up, now 00 

;if A not 00 then at least one key 

;down 



keydown: 


mov 


r0.pl 




mov 


a,p3 




orl 


a,#0f3h 




anl 


a,r0 




cpl 


a 




ret 





Continued 



138 



CHAPTER EIGHT 



ADDRESS MNEMONIC COMMENT 

Continued 
"convert" checks for more than one key down; if more than one key 
is down then addressable bit "flag" is set; if only one key is 
down then the one-of-ten bit pattern is converted to an 
equivalent 0-9 number in the A register and "flag" is reset 
valid patterns (a single out of ten bits) are found by CJNE 
operations; A is counted up for each test to match the key number 



convert 



one : 



two : 



three : 



four: 



five : 



six : 



seven : 



eight : 



nine : 

good: 
check3 : 



clr flag 

clr a 

mov rl.pl 

mov r3 , p3 

orl 03h,#0f3h 

cjne rl,#0feh,one 

sjmp check3 

inc a 

cjne rl,#0fdh,two 

sjmp check3 

inc a 

cjne rl,#0fbh, three 

sjmp check3 

inc a 

cjne rl,#0f7h,four 

sjmp check3 

inc a 

cjne rl,#0efh, five 

sjmp check3 

inc a 

cjne rl,#Odfh,six 

sjmp check3 

inc a 

cjne rl , #0bfh , seven 

sjmp check3 

inc a 

cjne rl,#7fh,eight 

sjmp check3 

inc a 

cjne r3 , #0fdh , nine 

jnb p3.3 bad 

sjmp good 

inc a 

cjne r3,#0f7h,bad 

ret 

jnb p3.3,bad 

jnb p3.4,bad 
sjmp good 



assume that key hit is valid 

A contains first possible key (00 

get PI key pattern in Rl 

get P3 key pattern in R3 

make r3 bits 0,1 and 4-7 a one 

search Rl for a legal pattern 

check R3 for no key down 

A contains next key possible (01) 

continue this for all valid 

patterns 

A ^ 02 



A ^ 03 



A = 04 



A ^ 05 



A = 06 



07 



A « 08 

now look for a key in R3 

check that key 9 is up 

A = 09 
redundant check 

if Rl has a low then P3 must be 
high 



Continued 



APPLICATIONS 



139 



ADDRESS 


MNEMONIC 


bad: 


setb flag 




ret 


softime: 


ret 


vendit : 


ret 




. end 




COMMENT - 



COMMENT 

; signal an invalid key pattern 

;simulate "softime" subroutine 
;simulate "vendit" subroutine 



The "convert" subroutine is looking for a single low bit. The CJNE patterns all have one bit low 
and the rest high. 

Multiple keys are rejected by "convert." Held keys are ignored as the program waits for a 50d 
millisecond "all keys up" period before admitting the next key. The program loops so quickly 
that it is humanly impossible to hit a key so that it can be missed. 

The main program is predominantly a series of calls to subroutines which can each be written 
by different programmers. Agreement on what data is passed to and received from the sub- 
routines is essential for success, as well as a clear understanding of what 8051 registers and 
memory locations are used. 

Interrupt-Driven Programs for Small Keyboards 

If the application is so time sensitive that the delays associated with debouncing and await- 
ing an "all-up" cannot be tolerated, then some form of interrupt must be used so that the 
main program can run unhindered. 

A compromise may be made by polling the keyboard as the main program loops, but 
all time delays are done using timers so that the main program does not wait for a software 
delay. The "Getkey" program can be modified to use a timer to generate the delays associ- 
ated with the key down debounce time and the "all-up" delay. The challenge associated 
with this approach is to have the program remember which delay is being timed out. Re- 
membering which delay is in progress can be handled using a flag bit, or one timer can be 
used to generate the key-down debounce delay, and another timer to generate the key-up 
delay. The flag approach is examined in the example given in this section. 

The important feature of the program is that the main program will check a flag to 
see whether there is any keyboard activity. If the flag is set, then the program finds the 
key stored in a RAM location and resets the flag. The getting of the key is "transparent" 
to the main program; it is done in the interrupt program. The keyboard is still polled by 
the main program, but the interrupt program gets the key after that. The program named 
"Hardtime" from Chapter 7 is used for the time delay. The keyboard user may notice 
some sluggishness in response if the main program takes so long to loop that the keyboard 
initiation sequence is not done every quarter-second or so. 

Inkey 

The program "lnkey" uses hardware timer Tl to generate all time delays. The keyboard 
sequence is initiated when a key is found to be down; otherwise, the program continues 
and checks for a key down in the next loop. A key down initiates a debounce time delay in 
timer Tl and sets a timer flag to notify the interrupt program of the use of the timer. The 
interrupt program checks that a key is still down and is valid. Valid keys are stored, and a 
flag is set that may be tested by the main program. The interrupt program then begins the 
key-up delay and sets the timer flag to signify this condition. After each key-up delay, the 
interrupt program checks for all keys up. The time delay is reinitialized until all keys are 
up and the timer interrupts are halted. 



140 



CHAPTER EIGHT 



ADDRESS 



inkey : 



MNEMONIC 

. equ newkey,70h 
.equ flag,00h 
.equ newflg, Olh 

.equ timflg, 02h 

. equ bounce, 14h 
.equ next,32h 

. equ savetime.OOlOh 
.org OOOOh 
.sjmp over 



COMMENT 

; store any new key in RAM 

addressable bit 00 used as a flag 

; when newflg = 1 then there is 

; a key 

;timflg = for debounce, 1 for 

; delay 

;set debounce delay to 20d ms 

;set interval between keys to 

; 50d ms 

; external RAM address for delay 

;jump over interrupt locations 



when Tl times out it vectors here and jumps to "hardtime" for the 
desired delay. When the delay is up then the key program is called. 



userdly : 



.org OOlbh 
ljmp hardtime 
acall usertime 
reti 



the main program begins here; 
is a new key to be processed, 
a key read is in progress 



over : 



begin 



mov pl,#0ffh 

mov p3,#0ffh 

clr newflg 

clr flag 

clr timflg 

jbc newflg, key 

jb tcon.6,mainprog 
acall keydown 
jz mainprog 

acall convert 
jz mainprog 

mov newkey , a 
clr timflg 

mov dptr,#savetime 
mov a, #bounce 
movx @dptr ,a 
inc dptr 
mov a,#00h 
movx @dptr,a 



; interrupt location for TF1 
;jump to time delay subroutine 
;call usertime if delay done 
; return to program when usertime 
; done 

the keyboard is scanned unless there 
or Tl is counting, signifying that 



;set ports 1 and 3 as inputs 
; initialize all flags 

; check if a key is waiting and 
;get it 

;if Tl is running then wait 
; keydown looks for any key(s) down 
;if A = then no key(s) down; 
; go on 

; check for a valid key 
; go on with main program if not 
; valid 

; store key and start debounce timer 
;signal interrupt program Tl 
; running 

: point to delay address 
set 20 ms delay 

point to next byte 

desired delay now stored 

Continued 



APPLICATIONS 



141 



ADDRESS 



key: 
mainprog: 



MNEMONIC 

orl ie,#88h 
acall startime 
sjmp mainprog 
mov a.newkey 
sjmp begin 



COMMENT 

;enable interrupts and Tl interrupt 
; start time delay go to mainprog 

;get key and use in main program 
; simulate main program and 
;loop back 



**#»**»*##*###■*#♦»*#♦***#■*♦*#* CONVERT ****************************** 
"convert" checks for more than one key down; if more than one key 
is down then addressable bit "flag" is set; if only one key is 
down then the one-of-ten bit pattern is converted to an 
equivalent 0—9 number in the A register and "flag" is reset 
valid patterns (a single out of ten bits) are found by CJNE 
operations; A is counted up for each test to match the key number 



convert 



one 



two 



three 



four 



five 



six: 



seven 



eight: 



nine: 



clr flag 

clr a 

mov rl,pl 

mov r3 , p3 

orl 03h,#0f3h 

cjne rl,#0feh,one 

sjmp check3 

inc a 

cjne rl,#0fdh,two 

sjmp check3 

inc a 

cjne rl,#0fbh, three 

sjmp check3 

inc a 

cjne rl,#0f7h, four 

sjmp check3 

inc a 

cjne rl , #0efh, five 

sjmp check3 

inc a 

cjne rl,#0dfh,six 

sjmp check3 

inc a 

cjne rl, #0bfh, seven 

sjmp check3 

inc a 

cjne rl ,#7fh, eight 

sjmp check3 

inc a 

cjne r3, #0fdh, nine 

jnb p3.3 bad 

sjmp good 

inc a 

cjne r3,#0f7h,bad 



; assume that key hit is valid 

;A contains first possible key (00 

;get Fl key pattern in Rl 

;get F3 key pattern in R3 

;make R3 bits 0,1 and 4—7 a one 

;search Rl for a legal pattern 

; check R3 for no key down 

;A contains next key possible (01) 

;continue this for all valid 

;patterns 

;A = 02 



A = 03 



A = 04 



A = 05 



A = 06 



;A = 07 



;A = 08 

; now look for a key in R3 

; check key 9 is up 

;A = 09 

; redundant check 



Continued 



142 



CHAPTER EIGHT 



ADDRESS 

Continued 

good: 
check3: 



bad: 



MNEMONIC 

ret 

jnb p3 .3, bad 

jnb p3.4,bad 
sjmp good 
setb flag 
ret 



COMMENT 



if Rl has a low then P3 must 
be high 



signal an invalid key pattern 



»*****#♦♦##*#*#»*»■»*#**-»##♦■»* HARDTI ME *»****»*******»***«»»***»*»** 
"hardtime" will count the interrupts generated by Tl until the 
number placed in RAM location "savetime" is zero 



hardtime 



aff : 



done : 



sava: 



push ace 

push dph 

push dpi 

mov dptr, #savetime 

movx a, @dptr 

dec a 

cjne a,#00h,aff 

movx @dptr,a 

inc dptr 

movx a, @dptr 

jz done 

sjmp sava 

cjne a,#Offh,sava 

movx @dptr , a 

inc dptr 

movx a, @dptr 

dec a 

sjmp sava 

pop dpi 

pop dph 

pop ace 

Ijmp userdly 

movx @dptr,a 

pop dpi 

pop dph 

pop ace 

acall startime 

reti 



save registers to be used 



get pointer to time delay number 
count delay number down to 0000 

;low byte first 

; check for 0000 

; save low byte = 00 

;get high byte and look for 00 

done if low byte = high byte = 00 
not 0000, reset Tl and delay again 
if low byte is FF then dec high 
save low byte = FF 
point to high byte 
count high byte down 

save the high byte 

delay is finished 

restore all registers used 

continue at user delay program 
delay is not up, save the byte 
restore saved registers 



start Tl for next 1 ms delay 
return to place in user program 



****#«-#**#«.*****##*##**###«-*## KEYD0WN ****************************** 
"keydown" gets the contents of PI and P3 pins that are connected 
to the keys and checks for any zero bits; no check is made to see 
if more than one bit is low 



keydown: 



mov r0.pl 



;get state of PI keys to R0 



Continued 



APPLICATIONS 



143 



ADDRESS MNEMONIC 

mov a,p3 
orl a,#0f3h 
aril a,rO 

cpl a 
ret 

♦ ##*♦■*******##♦#*■***#**■*■*#»#* 
"startime" initializes timer 



startime: 



mov thl, #Ofah 
mov til. #0cbh 

anl tmod,#0fh 

orl tmod,#40h 

orl tcon,#40h 
ret 



COMMENT 

;get state of P3 keys to A 

;make bits 0,1, and 4-7 a one 

; check, for any one or more 

;keys down 

;A = FFh if all keys up, now 00 

;if A not 00 then one or more down 

STARTIME ***************************** 
1 and enables timing to begin 

;set Tl for a I ms delay 

; {see "Timer" example in 

; Chapter 7) 

; clear Tl part of TM0D 

;set Tl to timer mode 1 

;start timer 1 

; return to calling program 



a-*-****-****************-******* STOPTIME ******■**■*****************-**** 



" stoptime " disables Tl 

stoptime: anl tcon,#0bfh 
ret 



;stop timer Tl 



♦ »»**♦*»*■**»*■»####»#**##*#»♦# USERTIME ***************************** 

"usertime, " the user program called from the interrupt program after 
hardtime has timed out, will process the key and set the 50d ms 
delay if the key was valid 



usertime: acall stoptime 
jb timflg.keyup 
acall keydown 
jz goback 
acall convert 
jbc flag, goback 
cjne a.newkey, goback 
setb newflg 

delay: mov dptr , #savetime 
mov a,#next 
movx @dptr,a 
inc dptr 
mov a,#00h 
movx @dptr,a 
orl ie,#88h 
acall startime 
setb timflg 

goback: ret 



stop timer and determine Tl use 
if a delay then see if keys up 
see if a key is still down 
if not down then must be noise 
see if key is valid and matches 
the original key found 

set new key flag for main program 
point to delay address 
set 50d ms delay 

point to next byte 

desired delay now stored 

enable interrupts and Tl interrupt 

start time delay 

set flag for delay condition 

Continued 



144 



CHAPTER EIGHT 



ADDRESS 

Continued 

keyup: 



MNEMONIC 

acall keydown 
jnz delay 
sjmp goback 
. end 



COMMENT 

;see if keys are up after delay 
;if not then delay again 
; return with Tl stopped 



£>— COMMENT 



This program is large enough to require additional attempts to make it legible. All of the sub- 
routines are arranged in alphabetical order. 

Codekey 

The completely interrupt-driven small keyboard example given in this section requires no 
program action until a key has been pressed. Hardware must be added to attain a com- 
pletely interrupt-driven event. The circuit of Figure 8.4 is used. 



FIGURE 8.4 Keyboard Configuration Used for "Codekey" Program 



Two-Of-Four 
Coded Keyboard 



Common 



+ 5V 




12 ONTO) 



8031 



Keyboard Code 


Key 


Pins Low 



1 
2 
3 


1 5 

2 5 

3 5 

4 5 


4 
5 
6 
7 


1 6 

2 6 

3 6 

4 6 


8 


1 7 


9 


2 7 



APPLICATIONS 



145 



The keyboard is a two-of-eight type which codes the ten keys as follows: 



KEY 


CODE(HEX) 





EE 


1 


ED 


2 


EB 


3 


E7 


4 


DE 


5 


DD 


6 


DB 


7 


D7 


8 


BE 


9 


BD 



An inspection of the code reveals that each nibble has only one bit that is low for each 
key and that two of the eight bits are uniquely low for each key. If more than one key is 
pressed, then three or more bits go low, signaling an invalid condition. This popular 
scheme allows for up to 16 keys to be coded in this manner. Unlike the lead-per-key 
arrangement, only four of the lines must be active-low ORed to generate an interrupt. 

The hardware serves to detect when any number of keys are hit by using an AND gate 
to detect when any nibble bit goes low. The high-to-low transition then serves to interrupt 
the microcontroller on port 3.2 (INTO). The interrupt program reads the keys connected to 
port 1 and uses timer TO to generate the debounce time and Tl for the keys-up delay. The 
total delay possible at 16 megahertz for the timers is 49.15 milliseconds, which covers the 
delay times used in the previous examples. 

The program "Codekey" which is interrupt driven by a high-to-low transition on 
INTO. Timers TO and Tl generate the debounce and delay times in an interrupt mode. 
The INTO interrupt input is disabled until all keys have been seen up for the Tl delay. 
A lookup table is used to verify that only one key is pressed. 



ADDRESS 



codekey: 



keyint : 



timO: 



MNEMONIC 

.equ newkey,70h 
. equ base,400h 
.equ newflg.OOh 
.org OOOOh 
sjmp over 
.org 0003h 
sjmp keyint 
.org OOObh 
sjmp timO 
.org OOlbh 
sjmp timl 
mov tl0,#0d4h 
mov th0,#97h 
setb tcon.4 
clr ie.O 
reti 

push ace 
push dpi 



COMMENT 

; store a new key in RAM 

;base of lookup table 

; addressable bit 00 for new key flag 

;jump over interrupt locations 
;this is the INTO interrupt vector 

; timer TO interrupt vector 

; timer Tl interrupt vector 

;set TO for 20 ms delay 

; count from 97D4h to 0000 

; start timer TO 

; disable INTO interrupt 

; enable interrupt structure and 

; return 

; save registers used 

Continued 



146 



CHAPTER EIGHT 



ADDRESS 

Continued 



good: 



Timl: 



wait : 



over : 

simulate 
key: 



MNEMONIC 

push dph 

clr tcon.4 

mov a, pi 

mov dptr , #base 

move a, @a+dptr 

cjne a,#0ffh,good 

pop dph 

pop dpi 

pop ace 

setb ie.O 

reti 

mov newkey.a 
setb newflg 
anl tll,#00h 
anl thl.#00h 
setb tcon.6 
pop dph 
pop dpi 
pop ace 
reti 

push ace 

clr tcon.6 

mov a, pi 

cjne a,#Offh,wait 

setb ie.O 

pop ace 

reti 

anl tll,#00h 

anl thl,#00h 

setb tcon.6 

pop ace 

reti 

mov tcon,#01h 

mov ie,#8bh 

mov tmod,#llh 

jbc newflg, key 

sjmp simulate 

mov a.newkey 

sjmp simulate 

.org 04bdh 

.db 09h 
.db 08h 



COMMENT 



;stop TO 

;get key pattern 

;set DPTR to point to lookup table 

;not valid = FFh 



enable INTO interrupt 

enable interrupt structure and 

return 

store the newkey 

signal main program; new key present 

set Tl for maximum delay (49.1 ms) 

start timer Tl 
restore retgisters 



enable interrupt structure and 

return 

save A 

stop Tl 

see if keys up yet 

all inputs will be high if all up 

enable INTO for next key 



restart Tl and delay again 

start Tl 

return with interrupt enabled 
set IN TO fo r falling edge interrupt 
; enable INTO, TO, and Tl interrupts 
choose timer operation; mode 1 
see if there is a new key and get it 
simulate rest of program 
get key and simulate rest of program 

place lookup table here, keys 9 
and 8 



Continued 



APPLICATIONS 



147 



ADDRESS 



MNEMONIC 

.org 04d7h 
.db 07h 
.org 04dbh 
.db 06h 
.org 04ddh 
.db 05h 
.db 04h 
.org 04e7h 
.db 03h 
.org 04ebh 
.db 02h 
.org 04edh 
.db Olh 
.db OOh 
. end 



COMMENT 

;key 7 

;key 6 

;keys 5 and 4 

;key 3 
;key 2 
;keys 1 and 



COMMENT 



The lookup table will work only if every bit from 0400h to 04FFh that is not a .db assignment is 
FFh. Most EPROMS will be FFh when erased, and the assembler will not program unspecified 
locations. The table will have to be assembled so that an FFh is at every non-key location if this 
is not true. 

Key bounce down is eliminated by the TO delay, and key bounce up, by the T1 delay. More than 
two keys down is detected by th e self-coding nature of the keyboard. A held key does not 
interrupt the edge-triggered INTO input. 

Program for a Large Matrix Keyboard 

A 64-key keyboard, arranged as an 8-row by 8-column matrix will be interfaced to the 
8051 microcontroller, as shown in Figure 8.5. Port 1 will be used to bring each row low, 
one row at a time, using an 8-bit latch that is strobed by port 3.2. PI will then read the 
8-bit column pattern by enabling the tri-state buffer from port 3.3. A pressed key will have 
a unique row-column pattern of one row low, one column low. Multiple key presses are 
rejected by either an invalid pattern or a failure to match for three complete cycles. Each 
row is scanned at an interval of I millisecond, or an 8 millisecond cycle for the entire 
keyboard. A valid key must be seen to be the same key for 3 cycles (24 milliseconds). 
There must then be three cycles with no key down before a new key will be accepted. The 
1 millisecond delay between scans is generated by timer TO in an interrupt mode. 



Bigkey 

The "Bigkey" program scans an 8 x 8 keyboard matrix using TO to generate a periodic 
I ms delay in an interrupt mode. Each row is scanned via an external latch driven by port 1 
and strobed by port 3.2. Columns are read via a tri-state buffer under control of port 3.3. 
Keys found to be valid are passed to the main program by setting the flag "newflg" and 
placing the key identifiers in locations "newrow" and "newcol." The main program 
resets "newflg" when the new key is fetched. R4 is used as a cycle counter for successful 
matches and up time cycles. R5 is used to hold the row scan pattern: only one bit low. 



148 



CHAPTER EIGHT 



FIGURE 8.5 Circuit for "Bigkey" Program 



Matrix Switch Connection 



Row 

i 


1 

2 

3 

4 

5 

6 

7 



l_. 



Row 



Column 

8x8 Keyboard 

Column 
12 3 4 5 6 



23456789 
1817161514131211 



19 



2 

5 

6 

9 

12 

15 

16 

19 



1 
11 



- J WW 



Pullup Network 



Latch Row Pattern 



■373 Latch 



+ 5V 



'541 Tri- State Buffer 



12P3.2 

1P1.0 
2P1.1 
3P1.2 
4 PI. 3 
5P1.4 
6 PI. 5 
7P1.6 
8 PI. 7 



8031 



Hl-Z 



13P3.3 



Read 



Columns 



ADDRESS 



MNEMONIC 

. equ newrow,70h 
.equ newcol ,71h 
.equ newflg,00h 



COMMENT 

; store any valid key row address 
; store any valid key column address 
;use addressable bit as a new 
;key flag 

Continued 



APPLICATIONS 



149 



ADDRESS 



bigkey: 



MNEMONIC 

.equ upflg.Olh 

.org OOOOh 
sjmp over 



The interrupt program begins here 
the next interrupt in 1 ms 

.org OOObh 

mov tlO,#Ocbh 
mov thO,#Ofah 
push ace 
push psw 
mov pl,r5 
setb p3.2 
clr p3.2 
mov pl.#Offh 
clr p3.3 

mov a, pi 

setb p3.3 

jb upflg.upyet 

setb c 

mov r3,#08h 

look: rrc a 

jnc test 

djnz r3,look 

mov a,r5 

cjne a, newrow, goback 

mov newrow, #00h 





mov r4,#00h 




sjmp goback 


test : 


cjne a,#Offh,bad 


here: 


rrc a 




djnz r3,here 




cjne r4, #00h, match 


newone : 


mov newcol, a 




mov newrow, r5 




inc r4 




sjmp goback 


match: 


push ace 




mov a,r5 



COMMENT 

;upflag signals start of key up 
; delay 

;jump over TO interrupt to main 
; program 

TO is reloaded to permit 



vector location for TO overflow 

flag 

reload TO for next interrupt 

; save A and the flags 

;get row scan pattern to port 1 
[generate a strobe to the latch 

; set PI as an input port 

: read buffer and see if any 

;key down 

: get column pattern 

:disable buffer 

;if upflg = 1 then wait for 

;keys up 

;set C to 1 and rotate A to find 

;a low 

;8 rotates will restore A to 

[original 

; see if only one zero in A (valid) 

:if C = then see if A = FFh 
go until C = or rotate finished 
check for a key down previous scan 

if so then not repeated; zero 
newrow 

if so then zero R4 and scan again 
; return to main program 
if A not all ones then invalid key 
good pattern; restore A 

R4 counts pattern matches 

first time seen; see if it recurs 

R4 contains key detected count 

save A and check R5 for a new row 



Continued 



150 



CHAPTER EIGHT 



ADDRESS 

Continued 



good: 



unk: 
unkn: 

bad: 

upyet : 



notup: 
goback 



MNEMONIC 

cjne a, newrow.unk 
pop ace 

cjne a, newcol , unkn 

inc r4 

c j ne r4 , #04h , goback 

mov newrow,r5 

mov newcol, a 

setb newflg 

setb upflg 

mov r4,#00h 

sjmp goback 

pop ace 

mov r4,#00h 

sjmp newone 

mov r4,#00h 

sjmp goback 

cjne a, #0ffh, notup 

inc r4 

cjne r4,#18h, goback 

clr upflg 

mov r4.#00h 

mov a,r5 

rl a 

mov r5,a 

pop psw 

pop ace 

reti 



COMMENT 

;if no match then this is a new key 

; restore A and check for a new 

; column 

;if no match then this is a new key 

; match: see if 24 ms have expired 

;keep if seen for at least 3 cycles 

; save new key row and column 



;set up flag for 3 cycles up 

; reset R4 to count key up cycles 

; restore new column pattern to A 
; reset r4 to reflect a new key 
;look for matches on next cycles 
; reset match counter 

; look for A = FFh 

; R4 now counts 3 cycle of up time 

;look for 24d scans {3 cycles) 

; up time done, look for next key 

; reset R4 

; rotate R5 low bit to next row 



; restore PSW and A 



the interrupt program finishes here and the main program begins; 
the main program would normally get the new key row and column 
patterns and convert these to a single byte number 



over : 



main: 
simulate 



mov r5,#0feh 

mov tmod,#01h 

mov tl0,#0cbh 

mov th0,#0fah 

mov ie.#82h 

setb tcon.4 

mov r4,#00h 

clr upflg 

clr newflg 

jbc newflg, simulate 

sjmp main 

nop 

sjmp main 
.end 



initialize R5 for bottom row low 

set TO to mode 1 

set TO for a 1 ms delay 

count 1333d @ .75 /xs/count 

enable the TO interrupt 

start timer 

reset R4 for no valid key 

reset key up flag 

reset new key flag 

get key row and column addresses 

simulate main program 

main program would get addresses 

here 



APPLICATIONS 151 



COMMENT 



Displays 



Once begun by the main program, TO continues to time out and generate the row scan pattern 
in the interrupt program. To the main program, the keys appear in some unknown way; the 
interrupt program is said to run in the "background." 

There is considerable adjustment (tweak) in this program to accommodate keys with various 
bounce characteristics. The debounce time can be altered in a gross sense by changing the 
number of cycles (R4) for acceptance and in a fine way by changing the basic row scan time (TO). 

This same program can be used to monitor any multipoint array of binary data points. The array 
can be expanded easily to a 16 x 16 matrix by adding one more latch and tristate buffer and 
using two more port 3 pins to generate the latch and enable strobes. 

Note that only A can compare against memory contents in a CJNE instruction. 



If keyboards are the predominant means of interface to human input, then visible displays 
are the universal means of human output. Displays may be grouped into three broad 
categories: 

1. Single light(s) 

2. Single character(s) 

3. Intelligent alphanumeric 

Single light displays include incandescent and, more likely, LED indicators that are 
treated as single binary points to be switched off or on by the program. Single character 
displays include numeric and alphanumeric arrays. These may be as simple as a seven- 
segment numeric display up to intelligent dot matrix displays that accept an 8-bit ASCII 
character and convert the ASCII code to the corresponding alphanumeric pattern. Intelli- 
gent alphanumeric displays are equipped with a built-in microcontroller that has been op- 
timized for the application. Inexpensive displays are represented by multicharacter LCD 
windows, which are becoming increasingly popular in hand-held wands, factory floor ter- 
minals, and automotive dashboards. The high-cost end is represented by CRT ASCII 
terminals of the type commonly used to interface to a multi-user computer. 

The individual light and intelligent single-character displays are easy to use. A port 
presents a bit or a character then strobes the device. The intelligent ASCII terminals are 
normally serial devices, which are the subject of Chapter 9. 

The two examples in this section — seven-segment anfi intelligent LCD displays — 
require programs of some length. 

Seven-Segment Numeric Display 

Seven-segment displays commonly contain LED segments arranged as an "8," with one 
common lead (anode or cathode) and seven individual leads for each segment. Figure 8.6 
shows the pattern and an equivalent circuit representation of our example, a common cath- 
ode display. If more than one display is to be used, then they can be time multiplexed; the 
human eye can not detect the blinking if each display is relit every 10 milliseconds or so. 
The 10 milliseconds is divided by the number of displays used to find the interval between 
updating each display. 

The example examined here uses four seven-segment displays; the segment informa- 
tion is output on port 1 and the cathode selection is done on ports 3.2 to 3.5, as shown in 



152 CHAPTER EIGHT 



FIGURE 8.6 Seven-Segment LED Display and Circuit 




Segment Pattern 



a b c d e f g 

liiiiU 



Common Cathode 
Segment Circuit 



Figure 8.7. A segment will he lit only if the segment line is brought high and the common 
cathode is brought low. 

Transistors must be used to handle the currents required by the LEDs, typically 
10 milliamperes for each segment and 70 milliamperes for each cathode. These are aver- 
age current values; the peak currents will be four times as high for the 2.5 milliseconds 
each display is illuminated. 

The program is interrupt driven by TO in a manner similar to that used in the program 
"Bigkey." The interrupt program goes to one of four two-byte character locations and 
finds the cathode segment pattern to be latched to port l and the anode pattern to be latched 
to port 3. The main program uses a lookup table to convert from a hex number to the 
segment pattern for that number. In this way, the interrupt program automatically displays 
whatever number the main program has placed in the character locations. The main pro- 
gram loads the character locations and is not concerned with how they are displayed. 

Svnseg 

The program "svnseg" displays characters found in locations "chl" to "ch4" on four 
common-cathode seven-segment displays. Port I holds the segment pattern from the low 
byte of chx; port 3 holds the cathode pattern from the high byte of chx. TO generates a 
2.5 ms delay interval between characters in an interrupt mode. The main program uses a 
lookup table to convert from hex to a corresponding pattern. R0 of bank one is dedicated 
as a pointer to the displayed character. 



APPLICATIONS 153 



FIGURE 8.7 Seven-Segment Display Circuit Used for "Svnseg" Program 



+ 5V 



Choose R for 
Brightness. 



a b c d e f g 
Display 1 



a b c d e f g 
Display 2 



a b c d e f 
Display 3 



a b c d e f g 
Display 4 



Q1-Q4 
8 > 1000 



7 PI. 6 





8031 



12 


P3.2 


13 


P3.3 


14 


P3.4 


15 


P3.5 



ADDRESS 



svnseg: 



MNEMONIC 

.equ chl,50h 
.equ ch2,52h 
.equ ch3,54h 
.equ ch4,56h 
.org OOOOh 
mov sp,#0fh 
sjmp over 



COMMENT 

.'assign RAM character locations 
; two bytes per character 



jump over TO interrupt location 
get the stack above bank one 



Continued 



154 



CHAPTER EIGHT 



ADDRESS 

Continued 



MNEMONIC 



COMMENT 



begin the interrupt-driven program at the TO interrupt location 



.org OOObh 

mov tlO,#Ofbh 

mov th0,#0f2h 

setb psw.3 

mov pl,@rO 

inc rO 

mov p3,@r0 

inc rO 

cjne r0,#58h,nxt 

mov rO,#chl 
nxt: clr psw.3 

reti 
; the main program loads sample 
; interrupt . 

mov a.#00h 

acall convert 

mov chl, a 

mov a,#01h 

acall convert 

mov ch2,a 

mov a,#02h 

acall convert 

mov ch3,a 

mov a,#03h 

acall convert 

mov ch4,a 

setb psw.3 

mov rO,#chl 

inc rO 

mov @r0,#20h 

inc rO 

inc rO 

mov @r0,#10h 

inc rO 

inc rO 

mov @r0. #08h 

inc rO 

inc rO 

mov @r0,#04h 

mov rO.#chl 

mov tlO,#Ofbh 

mov th0,#0f2h 



; reload TO for next interrupt 

; select bank one 

;place segment pattern on port 1 

; point to accompanying cathode pattern 

;place cathode patten on port 3 

; check for fourth character 

;if ch4 just displayed go to chl 
; return to register bank 
; return to main program 
characters and starts the TO 

;use an example sequence of 0, 1, 2, 3 
; convert to segment pattern and store 



last segment pattern stored 

select register bank one 

set RO to point to chl RAM location 

now load anode pattern for chl 

set anode for character 1 only high 

point to next character and continue 

load ch2 pattern 



load ch3 pattern 



load ch4 pattern 

point to RAM address for chl 
load TO for first interrupt 



Continued 



APPLICATIONS 



155 



ADDRESS 



here : 



MNEMONIC 

mov tmod,#01h 
mov ie,#82h 
setb tcon.4 
clr psw.3 
sjmp here 



COMMENT 

;set TO to mode 1 

; enable TO interrupt 

;start timer 

; return to register bank 

;loop and simulate rest of program 



convert uses the PC to point to the base of the 16-byte table 



convert : 



inc a 

mov a,@pc + a 
ret 

.db cOh 
.db f9h 
.db a4h 
.db bOh 
.db 99h 
.db 92h 
.db 82h 
.db f8h 
.db fOh 
.db 98h 
.db 88h 
.db 83h 
.db c6h 
.db blh 
.db 86h 
.db 8eh 
. end 



compensate for RET byte 

get byte 

return with segment pattern in A 



1 

2 

3 

4 

5 

6 

7 

8 

9 

A 

b 

C 

d 

E 

F 



COMMENT 



Using bank 1 3S a dedicated bank for the interrupt routine cuts down on the need for pushes 
and pops. Bank 1 may be selected quickly, giving access to the eight registers while saving 
the bank registers. Note that the stack, at reset, points to RO of bank 1 , so that it must be 
relocated. 

The intensity of the display may also be varied by blanking the displays completely for some 
interval using the program. 



Intelligent LCD Display 

In this section, we examine an intelligent LCD display of two lines, 20 characters per line, 
that is interfaced to the 8051. The protocol (handshaking) for the display is shown in 
Figure 8.8, and the interface to the 8051 in Figure 8.9. 

The display contains two internal byte-wide registers, one for commands (RS = 0) and 
the second for characters to be displayed (RS = 1). It also contains a user-programmed 
RAM area (the character RAM) that can be programmed to generate any desired character 
that can be formed using a dot matrix. To distinguish between these two data areas, the 
hex command byte 80 will be used to signify that the display RAM address OOh is chosen. 



156 CHAPTER EIGHT 



FIGURE 8.8 Intelligent LCD Display 



G +5 -5 




11111111 111 



DO Dl 02 D3 D4 05 D6 D7 RS R/W EN 

Intelligent LCD Display 



BIT 



RS 


R/W D7 


D6 


D5 


D4 


D3 


D2 


D1 


DO 


























1 























1 























1 


1/0 


s 



DL 



S/C R/L 



N 












1 Character address 








1 


Display data address 





1 


BF 


Current address 


1 







Character byte 


1 


1 




Character byte 



Function 

Clear LCD and memory, home cursor 

Clear and home cursor only 

Screen action as display character written 

S = 1/0: Shift screen/cursor 

I/O = 1 /O: Cursor R/L, screen L/R 

D = 1/0: Screen on /off 

C = 1/0: Cursor on/off 

B = 1/0: Cursor Blink/Noblink 

S/C = 1/0: Screen/Cursor 

R/L = 1/0: Shift one space R/L 

DL = 1/0: 8/4 Bits per character 

N = 1/0; 2/1 Rows of characters 

F = 1/0; 5X10/5X7 Dots/Character 

Write to character RAM Address after ihr 

Write to display RAM Address after thr, 

BF = 1/0: Busy/Notbusy 

Write byte to last RAM chosen 

Read byte from last RAM chosen 



Port 1 is used to furnish the command or data byte, and ports 3.2 to 3.4 furnish rruK 
ter select and read/write levels. 

The display takes varying amounts of time to accomplish the functions listed in Hi* 
ure 8.8. LCD bit 7 is monitored for a logic high (busy) to ensure the display is not <m r 
written. A slightly more complicated LCD display (4 lines x 40 characters) is cunvntk 
being used in medical diagnostic systems to run a very similar program. 

Lcdisp 

The program "lcdisp" sends the message "hello" to an intelligent LCD display shown in 
Figure 8.8. Port 1 supplies the data byte. Port 3.2 selects the command (0) or dai;i 1 1 1 
registers. Port 3.3 enables a read (0) or write (1) level, and port 3.4 generates an actiw 
low-enable strobe. 



APPLICATIONS 157 



FIGURE 8.9 Intelligent LCD Circuit for "Lcdisp" Program 

_ +5V -5V 



Mi 



1 2 3 



Two Line x 20 Character 
Intelligent LCD Display 



14 13 12 11 10 9 



D7 



D6 



D5 



D4 



D3 



D2 



Dl 



DO 



R/W 



RS 



EN 



Enable Low 



14P3.4 



8031 



12P3.2 
13P3.3 

1P1.0 
2P1.1 
3P1.2 
4P1.3 
5P1.4 
6P1.5 
7P1.6 
8P1.7 



ADDRESS 

lcdisp: 



MNEMONIC 

.org OOOOh 
clr p3.2 
clr p3.3 
mov a,#3fh 
acall strobe 
mov a,#Oeh 
acall strobe 
mov a , #06h 
acall strobe 
mov a,#01h 
acall strobe 
setb p3.2 
mov a,#'h' 
acall strobe 
mov a,#'e' 
acall strobe 
mov a,#'l' 
acall strobe 
acall strobe 
mov a,#'o' 
acall strobe 



COMMENT 

;select the command register 

; select write level 

; command 8 bits/char., 2 rows, 5 x 10 

; strobe command to display 

; command screen and cursor on, no blink 

; command cursor right as data displayed 

; clear all and home cursor 

; select display data RAM register 
;say "hello" 



Continued 



158 



CHAPTER EIGHT 



ADDRESS MNEMONIC 

Continued 

here : sjmp here 



COMMENT 



; message sent 



the subroutine "strobe" is used to check for a display busy 
condition, and pulse P3.3 high-low-high to enable the display 
write or read 



strobe : 
wait : 



mov pl,#Offh 
setb p3.3 
setb p3.4 
clr p3.4 
jb pi. 7, wait 
setb p3.4 
clr p3.3 
setb p3.2 
mov pi, a 
clr p3 . 4 
setb p3.4 
clr p3.2 
ret 
. end 



configure port 1 as an input 
set read level 
generate read strobe 
: enable the display 
check for busy when BF = 1 
end of read strobe 
write character to display 
choose data RAM 
character to port 1 
generate write strobe 

return with display as before call 



{>— COMMENT 



If long character strings are to be displayed, then a subroutine could be written that receives 
the beginning address of the string. The subroutine then displays the characters until a unique 
"end-of-string" character is found. 



Pulse Measurement 



Sensors used for industrial and commercial control applications frequently produce pulses 
that contain information about the quantity sensed. Varying the sensor output frequency, 
using a constant duty cycle but variable frequency pulses to indicate changes in the mea- 
sured variable, is most common. Varying the duration of the pulse width, resulting in 
constant frequency but variable duty cycle, is also used. In this section, we examine pro- 
grams that deal with both techniques. 

Measuring Frequency 

Timers TO and Tl can be used to measure external frequencies by configuring one timer as 
a counter and using the second timer to generate a timing interval over which the first can 
count. The frequency of the counted pulse train is then 

Unknown frequency — Counter/timer 

For example, if the counter counts 200 pulses over an interval of . 1 second generated by 
the timer, the frequency is 



UF = 200/. 1 = 2000 Hz 



APPLICATIONS 159 

Certain fundamental limitations govern the range of frequencies that can be mea- 
sured. An input pulse must make a l-to-0 transition lasting two machine cycles, or f/24, 
to be counted. This restriction on pulse deviation yields a frequency of 667 kilohertz using 
our 16 megahertz crystal (assuming a square wave input). 

The lowest frequency that can be counted is limited by the duration of the time inter- 
val generated, which can be exceedingly long using all the RAM to count timer rollovers 
(49. 15 milliseconds x 2 A 32768). There is no practical limitation on the lowest frequency 
that can be counted. 

Happily, most frequency variable sensors generate signals that fall inside of to 
667 kilohertz. Usually the signals have a range of 1 ,000 to 10,000 hertz. 

Our example will use a sensor that measures dc voltage from to 5 volts. At V the 
sensor output is 1 ,000 hertz, and at full scale, or 5 volts, the sensor output is 6,000 hertz. 
The correspondence is 1 volt per 1 ,000 hertz, and we wish to be able to measure the volt- 
age to the nearest .01 V, or 10 hertz of resolution (assuming the sensor is this accurate). 
A timing interval of I second generates a frequency count accurate to the nearest 1 hertz, 
so an interval of . 1 s yields a count accurate to the nearest 10 hertz. 

Another way to arrive at the desired timing interval, T, is to note that the desired 
accuracy is 

.01 V I I 

= .002 = = — 

5 V 512 2 9 

and that the range of the counter is from T x fmin to T x fmax, or a range of T x 
(fmax — fmin) from zero to full scale. The resolution of each counter bit is then 

T x (fmax — fmin) 
LSB — 

2 n 

where n is the desired number of bits to be resolved. For our example, T = 512/5000 — 
. 1024 seconds; . I second yields a slightly better accuracy. 

From earlier tries at generating decimal time delays in Chapter 7, it has been amply 
demonstrated that these cannot be done perfectly using a 16 megahertz crystal (.75 micro- 
second count interval). We will be close enough to meet our requirements. 

Tl is used in the auto-reload mode 2 to generate overflow interrupts every 1 92 micro- 
seconds (256 x .75 microseconds). These overflows are counted using R4 and R5 until 
.100032 seconds have elapsed (521d overflows). For this example, TO is used as a counter 
to count the external frequency that is fed to the port 3.4 (TO) pin during the Tl interval. 
Using the interval chosen, the range of counts in TO becomes 

0V = 1000 Hz x .100032 s = lOOd counts 
5V = 6000 Hz x . 100032 s = 600d counts 
.01 V = 10Hz x .100032 s = 1 count 

which meets the desired accuracy specification. 

Freq 

The program "freq" uses TO to count an external pulse train that is known to vary in 
frequency from 1000 to 6000 hertz. Tl generates an exact time delay of 192 microseconds 
that is counted using registers R4 and R5 of bank I until Tl has overflowed 521d times, or 
a total delay of . 100032 seconds. 



160 



CHAPTER EIGHT 



ADDRESS 



freq: 



MNEMONIC 

.equ frqflg.Ofh 
.org OOOOh 
mov sp,#0fh 
sjmp over 



COMMENT 

;use addressable bit for a flag 

;set stack above register bank one 
; jump over the Tl interrupt location 



Tl will overflow and vector here; R4 and R5 will be used as a 
combined 16-bit counter to count the 52 Id overflows; the extra 
microseconds needed to detect end of count and stop TO will 
introduce a slight error 



timup 



go: 



.org OOlbh 
setb psw . 3 
djnz r4. timup 

dec r5 

cjne r5,#0fdh,go 
cjne r4,#0f7h, go 
clr tcon.4 
setb frqflg 

clr tcon.6 

clr psw. 3 
reti 



place program at Tl interrupt vector 
switch to register bank 1 
count R4 down and test for 521d 
counts 



count down from 0000 to FDF7h 

209h = 521d 

stop TO and set frqflg 

main program can now process 

frequency 

stop Tl 

return to register bank zero 

total extra time to stop TO = 

8.25 /is 



209h 



the main program sets up TO to be a counter and starts Tl ; the 
flag frqflg is then watched until it is set by the interrupt 
program; the main program must do this every time a frequency read 
is desired; if continuous frequency determinations are desired by 
the main program, then the interrupt program could call a subroutine 
frequency handling program inserted before "go" in place of the 
instruction that stops Tl. 



over : 



simulate 
getfrq: 



setb psw. 3 

mov r4,#00h 

mov r5,#00h 

clr psw. 3 

mov tmod,#25h 

mov tll,#00h 

mov thl,#00h 

mov tcon,#50h 

mov ie,#88h 

jbc frqflg, getfrq 

sjmp simulate 

nop 

sjmp simulate 

. end 



;select register bank one 
: reset R4 and R5 

: restore to register bank zero 
Tl mode 2 timer, TO mode 1 counter 
count up from 00 and reset 
reload with 00 
start TO and Tl 
enable Tl to interrupt 
simulate main program getting data 

place frequency subroutine here 



APPLICATIONS 161 



COMMENT 



The longer the time taken to count, the more accurate the frequency will be (but remember, it 
makes little sense to make the readout more accurate than the basic sensor). TO will overflow 
at 65,535 or at the end of an interval of 10.92 s at fmax, which can be generated in T1 and R4, 
R5. In this case, the accuracy would be to the nearest .09 hertz (.0001 volt). 

If you wish to generate a delay closer to .1 s than used in the example, make T1 cycle in a 
shorter period of time and count these shorter periods in R4, R5. Compensate for the 8.5 micro- 
seconds it takes for the interrupt routine to determine that time is up. 

Preloading TO with a number that causes TO to overflow to 0000 when fmin is present during T 
will enable TO to read the voltage directly. For our example, presetting TO to FF9Ch will have 
TO = 01F4h (500d) at fmax = 60,000 hertz for T = .1 s. 

Pulse Width Measurement 

Theoretically, if the input pulse is known to be a perfect square wave, the pulse frequency 
can be measured by finding the time the wave is high (Th). The frequency is then 

1 
UF - 



Th x 2 



If Th is 200 microseconds, for example, then UF is 2500 hertz. The accuracy of the mea- 
surement will fall as the input wave departs from a 50 percent duty cycle. 

Timer X may be configured so that the internal clock is counted only when the corre- 
sponding INTX pin is high by setting the GATE X bit in TMOD. The accuracy of the 
measurement is within approximately one-half of the timer clock period, or .375 micro- 
second for a 16 megahertz crystal. This accuracy can only be attained if the measurement 
is started when the input wave is low and stopped when the input next goes low. Pulse 
widths greater than the capacity of the counter, which is 49.152 milliseconds for a 
16 megahertz crystal, can be measured by counting the overflows of the timer flag and 
adding the final contents in the counter. 

For the example in this section, the sensor used to measure the volt to 5 volts dc 
voltage has a fixed frequency of !000 hertz or a period of 1 ms. For a volt input, the 
sensor is high for 400 microseconds and low for 600 microseconds; when the sensor input 
is 5 volts, the output is high for 900 microseconds and low for 100 microseconds. Each 
volt represents 100 microseconds of time; the accuracy of the measurement is ±.00325 
volts, which is within the specification of .01 volt. 

To make the measurement, TO will be configured to count the internal clock when 
INTO is high. The measurement is not started until INTOgoes from high to low, leaving a 
minimum of 100 m icrose conds to start TO. The measurement is made while INTO is high 
and stopped when INTO goes low again. The whole process can be interrupt driven by 
using the interrupt flag associated with INTO. The IE0 flag can be set whenever INTO goes 
from high to low to notify the program to start the pulse width timing and then to stop. A 
variation of this program is currently in use to measure fabric width by measuring the 
reflection time of a scanning laser. 

Width 



The program "Width" measures the width of pulses that are fed to the INTO pin, port 3.2 
and that are known to vary from 400 to 900 microseconds. The program starts when the 
interrupt flag IE0 is set and stops the next time the flag is set, indicating one complete 
cycle of the input wave. 



162 



CHAPTER EIGHT 



ADDRESS 



width: 



MNEMONIC 

.equ wflg.OOh 
.org OOOOh 
sjump over 



COMMENT 

; flag set to notify main program 



;jump over INTO flag vector location 



the INTO edge triggered flag will vector here 



stop: 



.org 0003h 

jbc tcon.4, stop 

setb tcon.4 

clr wflg 

reti 

setb wflg 

reti 



if TO is running, stop TO 

if TO is not running, enable TO 

reset wflg until next measurement 

return with TO enabled 

set flag for main program 

return with TO stopped 



the main program resumes here; the program monitors the flag that 
indicates that a width measurement has just been made 



over : 



simulate 

getw: 



;mov tmod,#09h 
mov tcon,#01h 
mov tlO,#0Oh 
mov thO,#0Oh 
mov ie,#81h 
jbc wflg, getw 
sjmp simulate 
nop 

mov tlO,#0Oh 
mov th0,#00h 
sjmp simulate 
. end 



;set TO to count when INTO high 
; enable edge trigger for INTO 
; reset TO 



; enable external interrupt 
;look. for wflg and get width 

; real program would read TO for width 
; reset TO 

; simulate main program 



£>^- COMMENT 



If there is a considerable amount of electrical noise present on the INTO pin, an average value 
of the pulse width could be found by measuring the widths of a number of consecutive pulses. 
A counter could be incremented at the end of each cycle and the sum of the widths divided by 
the counter contents. The noise should average to zero. 



Frequency can be measured by timing the interval of a number (M) of high-to-low INTX inter- 
rupts. Synchronize the timing by starting the timer at the first transition, and stop the timer at 
the Mth + 1 transition. The frequency is then 

M 
UF= T 

where T is the count in the timer. 



D/A and A/D Conversions 



Conversion between the analog and digital worlds requires the use of integrated circuits 
that have been designed to interface with computers. Highly intelligent converters are 
commercially available that all have the following essential characteristics: 



APPLICATIONS 



163 



Parallel data bus: tri-state, 8-bit 

Control bus: enable (chip select), read/write, ready/busy 

The choice the designer must make is whether to use the converter as a RAM memory 
location connected to the memory busses or as an I/O device connected to the ports. Once 
that choice is made, the set of instructions available to the programmer becomes limited. 
The memory location assignment is the most restrictive, having only MOVX available. 
The design could use the additional 32K RAM address space with the addition of circuitry 
for A 15. By enabling the RAM when A15 is low, and the converter when A 1 5 is high, the 
designer could use the upper 32K RAM address space for the converter, as was done to 
expand port capacity by memory mapping in Chapter 7. All of the examples examined 
here are connected to the ports. 

D/A Conversions 

A generic R-2R type D/A converter, based on several commercial models, is connected to 
ports 1 and 3 as shown in Figure 8. 10. Port 1 furnishes the digital byte to be converted to 
an analog voltage; port 3 controls the conversion process. The converter has these features: 

Vout = -Vref X (byte in/lOOH), Vref = ±10 V 
Conversion time: 5 jas 



Control sequence: CS then WR 

For this example, a 1000 hertz sine wave that will be generated can have a program- 
mable frequency. Vref is chosen to be —10 volts, and the wave will swing from +9.96 
volts to volt around a midpoint of 4.48 volts. The program uses a lookup table to gener- 
ate the amplitude of each point of the sine wave; the time interval at which the converter is 
fed bytes from the table determines the wave frequency. 

The conversion time limits the highest frequency that can be generated using S sample 
point. In this example, the shortest period that can be used is 



Tmin = S x 5 /its — 5S fxs, fmax = 



200,000 
S 



FIGURE 8.10 D/A Converter Circuit for "Davcon" Program 

Reference 



P3.3 13 
P3.2 12 



8031 



P1.0 1 

Pl.l 2 

PI. 2 3 

P1.3 4 

Pl.4 5 

PI. 5 6 

PI. 6 7 

PI. 7 8 



WR 




T 












| Rfb 






CS 


1 








12 8 < 

To A Converter 
7 6 5 4 16 15 14 1 


, \. 1 Out 


r\ 




19 ^ - 


\ 




/ ' 




3 jS* 




l*"^ 


VO 


1 


Dl 


D2 


03 


D4 


D5 


D6 


D7 


Operational 
Amplifier 




00 











































































164 



' IIAI'll K II' >!ll 



The design tension is high frequency versus high resolution. For a I000 hertz wave, 
S could be 200d samples. In reality, we cannot use this many samples; the program cannot 
fetch the data, latch it to port I , and strobe port 3.3 in 5 microseconds. An inspection of 
the program will show that the time needed for a single wave point is 6 microseconds, and 
setting up for the next wave takes another 2.25 microseconds. S becomes I66d samples 
using the 6 microseconds interval, and the addition of 2.25 microseconds at the end of 
every wave yields a true frequency of lOOl .75 hertz. 

Davcon 

The D/A converter program "Davcon" generates a I000 hertz sine wave using an 8-bit 
converter. I66d samples are stored in a lookup table and fed to the converter at a rate of 
one sample every 6 microseconds. The lookup table is pointed to in external ROM by the 
DPTR, and Rl is used to count the samples. Numbers in parentheses indicate the number 
of cycles. 



ADDRESS 

davcon: 

repeat : 

next : 



MNEMONIC 

.org OOOOh 

clr p3.2 

mov dptr , #table 

mov rl,#0a6h 

mov a, rl 

move a, (?£a + dptr 

mov pi, a 

clr p3.3 

setb p3.3 

djnz rl.next 

sjmp repeat 



COMMENT 

; enable chip select to converter 

;get base address to DPTR 

;initialize Rl to 166d (1) 

; offset into table (1) 

; get sample (2 ) 

; sample to port 1 ( 1 ) 

; write strobe low ( 1 ) 

; write strobe high ( 1 ) 

; loop for 166D samples (2) 

; reload Rl and generate next wave (2 



the lookup table begins here; a cosine wave is chosen to make the 
table readable; the first 83 samples cover the wave from maximum to 
1 less than 0; the next 83 cover the wave from to maximum. 83 
samples per half-cycle means a sample every 2.17 degrees 



table : 



.db OOh 

. db ffh 

.db feh 

.db feh 

.db fdh 

.db fdh 

;and so on un 

.db 81h 

.db 7ch 

; near 180 deg 

db Olh 

db OOh 

db OOh 

db OOh 

db OOh 

db OOh 



;no entry at A = OOh 
;FFhcos - FFh. si 
;7Fh + 7Fhcos 2 . 17 = FEh. s2 
;7Fh + 7Fhcos 4 . 34 = FEh. s3 
; sample 4 
; sample 5 
til we near 90 degrees: 

;7Fh + 7Fhcos 88.9 = 81h. s42 
;7Fh + 7Fhcos 91 . 1 = 7Ch. s43 
rees we have: 

7Fh + 7Fh cos 173.5 = Olh. s81 
7Fh + 7Fh cos 175.7 - OOh. s82 
7Fh + 7Fh cos 177.8 = OOh. s83 
7Fh + 7Fh cos 180 = OOh. s84. 
7Fh + 7Fh cos 182.2 - OOh. s85 
7Fh + 7Fh cos 184.33 = OOh. s86 



Continued 



APPLICATIONS 



165 



ADDRESS MNEMONIC COMMENT 

.db Olh ;7Fh + 7Fh cos 186.5 = Olh. s87 
; finally, close to 360 degrees the table contains: 

.db fbh ;s 161 

.db fch ;s 162 

.db fdh ;s 163 

.db fdh ;s 164 

.db feh ;s 165 

.db feh ;s 166 
. end 



{>^- COMMENT 



The program retrieves the data from the highest to the lowest address. 

A/D Conversion 

The easiest A/D converters to use are the "flash" types, which make conversions hased 
upon an array of interna] comparators. The conversion is very fast, typically in less than 
I microsecond. Thus, the converter can be told to start, and the digital equivalent of the 
input analog value will be read one or two instructions later. Modern successive approxi- 
mation register (SAR) converters do not lag far behind, however, with conversion times in 
the 2-4 microsecond range for eight bits. 

At this writing, flash converters are more expensive (by a factor of two) than the tradi- 
tional SAR types, but this cost differential should disappear within four years. Typical 
features of an eight-bit flash converter are 

Data: Vin = Vref(-), data = OOh; Vin = Vref( + ), data = FFh 
Conversion time: 1 /as 



Control sequence: CS then WR then RD 

An example circuit, using a generic flash converter, is shown in Figure 8.11. Port 1 is 
used to read the byte value of the input analog voltage, and port 3 controls the conversion. 

FIGURE 8.11 A/D Converter Circuit for "Adconv" Program 



P3.4 14 
P3.3 13 
P3.2 12 



8031 



P1.0 


1 


Pl.l 


2 


PI. 2 


3 


PI. 3 


4 


P1.4 


5 


PI. 5 


6 


PI. 6 


7 


PI. 7 


8 



+ VREF - 



CS 



WR 



V Input 



RD 



13 6 8 12 11 

1 Flash A To D Converter 

2 3 4 5 14 15 16 



DO 



Dl 



D2 



D3 



D4 



D5 




166 



CHAPTER EIGHT 



A conversion is started by pulsing the write line low, and the data is read by bringing the 
read line low. 

Our example involves the digitizing of an input waveform every lOOd microseconds 
until lOOOd samples have been stored in external RAM. 

Adconv 

The program "Adconv" will digitize an input voltage by sampling the input every 100 fxs 
and storing the digitized values in external RAM locations 4000h to 43E7h (lOOOd 
samples). Numbers in parentheses are cycles. The actual delay between samples is 99.75 
microseconds. 



COMMENT 

start storage at 4000h 
delay in DJNZ loop for 87 usee 
high byte of ending address 
low byte of ending address 

point to starting address in RAM 
generate &3 to ADC 
generate WR pulse (1) 

(1) _ 
generate RD pulse (1) 
get data fl) 

end of RD pulse ( 1) 

store in external RAM (2) 

point to next and see if done (2 

(1) 
(2) 

(1) 

(2) 

finished if both tests pass 

delay for 87d /us 

(2) x .75 /is x H6d = 87 fis 
(2) 17d cycles (12.75 /as) 
simulate rest of program 



Using this program, we cou)d fill up the RAM in 3.2 s, which illustrates the volumes oi data that 
can be gathered quickly by such a circuit. Realistic applications would feature some data reduc- 
tion at the microcontroller before the reduced (massaged) data were relayed to a host computer. 



ADDRESS 


MNEMONIC 




. equ begin, 4000h 




. equ delay, 74h 




.equ endl ,43h 




.equ end2,e8h 




.org OOOOh 


adconv: 


mov dptr , #begin 




clr p3.2 


next : 


clr p3.3 




setb p3.3 




clr p3.4 




mov a, pi 




setb p3.4 




movx @dptr , a 




inc dptr 




mov a.dph 




cjne a, #endl , wait 




mov a, dpi 




cjne a,#end2,wait 




sjmp done 


wait : 


mov rl,#delay 


here : 


djnz rl.here 




sjmp next 


done : 


sjmp done 




. end 


— r^ 


COMMENT 



Multiple Interrupts 



The 8051 is equipped with two external interrupt input pins: INTO and INTl (P3.2 and 
P3.3). These are sufficient for small systems, but the need may arise for more than two 
interrupt points. There are many schemes available to multiply the number of interrupt 
points; they all depend upon the following strategies: 



APPLICATIONS 



167 



Connect the interrupt sources to a common line 
Identify the interrupting source using software 

Because the external interrupts are active low, the connections from the interrupt source to 
the INTX pin must use open-collector or tri-state devices. 

An example of increasing the INTO from one to eight points is shown in Figure 8. 1 2. 
Each source goes to active low when an interrupt is desired. A corresponding pin on port 1 
receives the identity of the interrupter. Once the interrupt program has handled the inter- 
rupt situation, the interrupter must receive an acknowledgment so that the interrupt line 
for that source can be brought back to a high state. Port 3 pins 3.3, 3.4, and 3.5 supply, 
via a 3-to-8 decoder, the acknowledgment feedback signal to the proper interrupt source. 
The decoder is enabled by port pin 3.0. 

Multiple and simultaneous interrupts can be handled by the program in as complex a 
manner as is desired. If there is no particular urgency attached to any of the interrupts then 
they can be handled as the port 1 pins are scanned sequentially for a low. 

A simple priority system can be established whereby the most important interrupt 
sources are examined in the priority order, and the associated interrupt program is run 
until finished. An elaborate priority system involves ordering the priority of each source. 
The elaborate system acknowledges an interrupt immediately, thus resetting that source's 
interrupt line, and begins executing the particular interrupt program for that source. A 
new interrupt from a higher priority source forces the current interrupt program to be sus- 
pended and the new interrupter to be serviced. 

To acknowledge the current interrupt in anticipation of another, it is necessary to also 
re-arm the INTX interrupt by issuing a "dummy" RET1 instruction. The mechanism for 
accomplishing this task is illustrated in the program named "hipri." First, a low priority 
scheme is considered. 



FIGURE 8.12 Multiple-Source Interrupt Circuit Used in "Lopri" and "Hipri" Programs 

+ 5V 



Interrupt Routine Signals Source When Finished 



Interrupt 
Sources 

-AAAr 

+ 5V 




rTrTrTrTrTrTrTT 



o.c. 

Output 



Identifier Output 



INTO 



13 


P3.3 


14 


P3.4 


15 


P3.5 




8031 


10 


P3.0 



12 P3.2 



1 


P1.0 


2 


Pl.l 


3 


PI. 2 


4 


PI. 3 


5 


P1.4 


6 


PI. 5 


7 


PI. 6 


8 


PI. 7 



168 



CHAPTER EIGHT 



Lopri 



The program "Lopri" scans port PI for the source of an interrupt that has triggered INTO. 
The pins are scanned for a low and the scan resumed after any interrupt is found and 
serviced. The interrupt source is acknowledged prior to a RETI instruction. R5 of bank 1 
is used to store the next pin to be scanned, and R6 is used to scan the pins for a low. A 
jump table is used to select the interrupt routine that matches the particular interrupt. Each 
interrupt routine supplies the 3-to-8 decoder a unique acknowledge pattern before a RETI. 



ADDRESS 



lopri: 



MNEMONIC 

. equ ack,70h 

.org OOOOh 
sjmp over 



COMMENT 

; each interrupt routine loads its 
; unique acknowledge byte in ack 



;jump over the INTO interrupt address 



The INTO interrupt will vector the program here 



which: 



low: 



goback: 



.org 0003h 

mov ack,#0ffh 

push ace 

push dpi 

push dph 

setb psw.3 

mov a,r5 

orl a, pi 

mov r6,#08h 

rrc a 

jnc low 

djnz r6, which 

sjmp goback 

mov a,r6 

subb a,#01h 

rl a 

mov dptr,#jmptbl 

jmp (aa + dptr 

mov a,r5 

rl a 

mov r5,a 

clr psw.3 

pop dph 

pop dpi 

pop ace 

mov p3,ack 

nop 

nop 

nop 

mov p3,#0ffh 

reti 



pin 



INTO vector address 
place enable pattern in ack 
save A 
save DPTR 

select register bank one 

get pattern in R5 to A 

OR the single zero in A with PI 

rotate A through C eight times 

find the zero starting at P1.0 

keep rotating until low found 

if not found then it was not this 

return with no action taken 

convert from l-of-8 low to number 

A was 8 to 1, now 07 to 00 

A is now OEh to 00 {two bytes/sjmp) 

DPTR points to the base of jump table 

jump to the matching interrupt 

routine 

rotate r5 to the next pin position 



select register bank zero 

restore register used in subroutine 



each routine loads proper P3 pattern 
give the interrupt circuit a few 
microseconds to respond and remove 
the low level before returning 
enable the next interrupt to occur 

Continued 



APPLICATIONS 



169 



ADDRESS 



MNEMONIC 



COMMENT 



the main program starts here followed by the interrupt routine jump 
table (simulated) 



over : 



simulate 
jmptbl : 



mov sp,#Ofh 
mov p3,#0ffh 
setb psw.3 
mov r5,#0feh 
clr psw.3 
mov ie,#81h 
mov tcon,#00h 
sjmp simulate 
sjmp goback 
sjmp goback 
sjmp goback 
sjmp goback 
sjmp goback 
sjmp goback 
sjmp goback 
sjmp goback 
. end 



; move stack above register bank one 

;set port 3 to disable 3/8 all high 

; select bank one and set R5 to one low 

;port pin 1.0 selected 

; return to ba nk zero 

; enable INTO interrupt 

; enable level trigger for INTO 

; simulate main program 

;simulate interrupt programs; pin 7 

;6 

;5 

;4 

;3 

;2 

;l 

;0 



COMMENT 



The instruction JMP @A+DPTR has been used to select one of a number of jump addresses, 
depending upon the number found in A. The simulated subroutines could be an SJMP to the 
actual interrupt handling subroutine. Because each SJMP takes two bytes to execute, A has to 
be doubled to point to every other byte in the jump table. When this action is not convenient, A 
can use a lookup table to get a new A, which then accesses a jump address. 

R5 has one bit low, and that bit acts as a mask when ORed with PI to find the low bit in P1 . 
When the low pin does not match the R5 pattern, the RET) will immediately cause INTO to 
interrupt again, and R5 will be set to the next pin position. The worst-case response time, if 
eight pins must be searched before the low pin is found, will be in the order of 600 microseconds. 



If INTO is triggered by noise, the routine returns after the first fruitless search with no action 
taken and re-arms the interrupt structure. 

The external interrupt flags are cleared when the program vectors to the interrupt address only 
when the external interrupt is edge triggered. Level triggered interrupts must have the low 
level removed before the RETI, or an immediate interrupt is regenerated. Each interrupt routine 
loads the internal RAM location "ack" with the proper bit pattern to the decoder to enable and 
decode the proper line to reset the interrupting source. 

Hipri 

Suppose that we wish to have a priority system by which the priority of each input pin is 
assigned at a different level — that is, there are eight priority levels, and each higher level 
can interrupt one at a lower level. Theoretically, this leads to at least nine return addresses 
being pushed on the stack (plus any other registers saved), so the stack should be expected 
to grow more than 18d bytes; it is set above the addressable bits at location 2Fh. 

In order to enable the interrupt structure in anticipation of a higher level interrupt, it is 
necessary to issue a RETI instruction without actually leaving the interrupt routine that 



170 



CHAPTER EIGHT 



currently has the highest priority. One way to accomplish this task is to push on the stack 
the address of the current interrupt routine to be done. Then, use a RETT that will return 
to the address on the stack, the desired current interrupt subroutine, and also re-arm the 
interrupt structure should another interrupt occur. The addresses of each subroutine can be 
known before assembly by originating each at a known address, or the program can find 
each address in a lookup table and push it on the stack, as illustrated in the example 
program. 

For this example, the priority of each interrupt source is equivalent to the port 1 pin to 
which its identity line is connected. PI .0 has the highest priority, and PI .7, the lowest. A 
lookup table is used t o find t he address of the subroutine to be pushed on the stack. 

External interrupt INTO is connected to the common interrupt line from all sources. It 
is enabled edge triggered whenever an interrupt routine is running so that any higher pri- 
ority interrupt will be immediately acknowledged. If a lower priority interrupt occurs, it 
will interrupt the program in progress long enough to determine the priority. The inter- 
rupted subroutine will resume, and the lower level interrupt source priority will be saved 
until the subroutine in progress is finished. All interrupting sources maintain their identity 
lines low until they are acknowledged. The common interrupt line is reset immediately to 
enable any other source to interrupt the 805 1 . 

If a higher level source interrupts a lower priority interrupt, then the high priority 
routine will interrupt the lower priority routine. The priority of the lower level interrupt 
will be saved. 

The program "Hipri*' assigns eight levels of priority to the interrupt sources con- 
nected to port I . A lookup table is used to find the address of the interrupt handling sub- 
routine that is pushed on the stack. A RETI instruction is then used to "return" to the 
desired subroutine and re-arm the interrupt hardware on the 8051 . 



ADDRESS 



hipri ; 



MNEMONIC 

.org OOOOh 
ljmp over 



COMMENT 



;jump over the INTO routine 



the INTO interrupt will vector here to find the identity and 
priority of the interrupt source 



int : 



.org 0003h 
push dph 
push dpi 
push ace 
setb psw.3 
clr p3.0 
setb p3.0 
mov dptr,#base 
mov a,R5 
orl a, PI 

cjne a, #0ffh, higher 
pop ace 

pop dpi 
pop dph 
reti 



INTO interrupt vectors here 
save registers used 



use register bank one 

reset common INT line by strobing 

pin 3.0 

get base address of address table 

get priority of current interrupt 

determine if new interrupt is 

higher 

A will be FFh if new < old 

not higher priority; return to 

current 



Continued 



APPLICATIONS 



171 



ADDRESS MNEMONIC 

higher: push Odh 

jnb ace .0 , first 
jnb ace. 1, second 
jnb acc.2,third 
jnb ace .3, fourth 
jnb ace. 4, fifth 
jnb ace. 5, sixth 
jnb ace .6, seventh 
jnb ace. 7, eighth 
sjmp goback 

first: mov r5>#0ffh 

mov a,#00h 

sjmp pushadd 

second: mov r5,#0feh 

mov a,#02h 
sjmp pushadd 

third: mov r5,#0fch 

mov a,#04h 
sjmp pushadd 

fourth: mov r5,#0f8h 

mov a,#06h 
sjmp pushadd 

fifth: mov r5,#0f0h 

mov a,#08h 
sjmp pushadd 

sixth: mov r5,#0e0h 

mov a,#0ah 
sjmp pushadd 

seventh: mov r5, #0c0h 
mov a,#0ch 
sjmp pushadd 

eighth: mov r5,#80h 

mov a,#0eh 

pushadd: mov r6,a 
inc a 

move a,@a+dptr 

push ace 

mov a,r6 

move a,@a+dptr 

push ace 

reti 

goback: pop Odh 
mov a, pi 
cjne a,#0ffh,old 



COMMENT 

;higher priority; save old (R5) 
;find higher priority interrupt 



noise; return with no new interrupt 

highest priority 

load A with offset into lookup 

table 

' ' pushadd " will push the address 

may only be interrupted by P1.0 

load A with offset for next program 

interrupt by 0-1 



interrupt by 0—2 



interrupt by 0—3 



interrupt .by 0—4 



interrupt by 0—5 



; interrupt by 0—6 

:save A for second byte fetch 
point to the low byte of the 

; address 
get first program address low byte 

;push the low byte 

:get A back 

;get the high byte of the address 
push the high byte 
execute subroutine; enable 
interrupt 

restore old priority mask 
look at PI for more interrupts 
see if any are waiting, or in 
progress 

Continued 



172 



CHAPTER EIGHT 



ADDRESS 

Continued 



old: 



next : 



MNEMONIC 

pop ace 
pop dpi 
pop dph 
clr psw.3 
reti 
orl a,r5 

cjne a.#Offh,next 

pop ace 

pop dpi 

pop dph 

reti 

pop ace 

pop dpi 

pop dph 

ljmp int 



COMMENT 

;if none waiting then return to main 
; program 

; return to register bank 

; return to main program 

;A = FFh if next interrupt 

; waiting was 

; itself interrupted 

; get old interrupt values 



; return to old interrupt in progress 
; the waiting interrupt is a new one 
;that has never begun to execu te 
;jump to "int" as if an INTO has 
;occured 



the lookup table that contains the addresses of the eight interrupt 
programs is assembled here ; the assembler knows all the actual 
numbers at assembly time 



progx is the actual interrupt 
routine 



base : 


.dw 


progl 




.dw 


prog2 




.dw 


prog3 




.dw 


prog4 




.dw 


prog5 




.dw 


prog6 




.dw 


prog7 




.dw 


prog8 


progl: 


nop 






ljmp 


goback 


prog2: 


nop 






ljmp 


goback 


prog3: 


nop 






ljmp 


goback 


prog4: 


nop 






ljmp 


goback 


prog5: 


nop 






ljmp 


goback 


prog6: 


nop 






ljmp 


goback 


prog7: 


nop 






ljmp 


goback 


prog8: 


nop 






ljmp 


goback 



simulate interrupt program. 

be sure to acknowledge before ljmp 

after subroutine has finished 



Continued 



APPLICATIONS 



173 



ADDRESS 



MNEMONIC 



COMMENT 



the main program starts here; "progx 
after the main program if desired 



could have been assembled 



over 



here 



mov sp,#2fh 
setb tcon.O 
setb psw.3 
mov r5,#00h 
mov ie,#81h 
clr psw.3 
sjmp here 
. end 



;set sta ck ab ove addressable bits 

;enable INTO edge-triggered 

; choose register bank one 

;set for interrupt at all levels 

; enable INTO 

; return to bank zero 

; simulate main program 



COMMENT 



The .dw assembler directive will store the high byte of the two-byte word at the lower address 
in memory. For the RETI in "pushadd" to work properly, the low address byte must be placed 
on the stack first. 

If interrupt A has just gone l ow, a nd interrupt B, which is of a higher priority, occurs after the 
system has vectored to the INTO address, interrupt B will be accessed if the B line goes low 
before the polling software starts (JN8 ACC.x). If the polling has caused A to be chosen, then B 
will be recognized after the RETI in "pushadd" causes the A address to be POPed from the 
stack. One instruction of A will be executed, then the IE0 flag in TCON will cause an interrupt. 

The 8051 interrupt system will generate an interrupt unless any of the following conditions 
are true: 

Another routine of equal or greater priority is running. 
The current instruction is not finished. 
The instruction is a RETI or any IE/IP access. 

The edge-triggered interrupt sets the IE0 fiag, and the interrupt that generated the edge ser- 
viced after any of the listed conditions are cleared. 

Hardware Circuits for Multiple Interrupts 

Solutions to the expanded interrupt problem proposed to this point have emphasized using 
a minimal amount of external circuitry to handle multiple, overlapping interrupts. A hard- 
ware strategy, which can be expanded to cover up to 256 interrupt sources, is shown in 
Figure 8.13. This circuit is a version of the "daisy chain" approach, which has long been 
popular. 

The overall philosophy of the design is as follows: 

1. The most important interrupt source is physically connected first in the chain, 
with those of lesser importance next in line. Lower priority interrupt sources are 
"behind" (connected further from INTO) those of a higher priority. 

2. Each interrupting source can disable all signals from sources that are wired 
behind it. All sources that lose the INACTOUT signal (a low level) from the 
source(s) ahead of it will place their source address buffer in a tri-state mode 
until INACTOUT is restored. 



■J3][oa)uoooJORu e Xq pdpiAOjd sq iq3iiu sb qons aDuaSiipiui sums uibiuoo 30Jnos sqj jEqj 
jo xojdujoo oq AJjiiiDjp sojnos aqj jcqj ssjmbai aDusnbss idausiu; siqj 3uiqsqdiuo3Dy 

duijnojqns )dn_uoiui sqj oj sssdde 
pidEJ so|qRU3 | uod uo sssjppE sojnos oq] pUB 'Suiuutu a\ou 3tio oqi ueq) Xjuoud J3q3iq 
jo sabmib si p3Ai3D3j )dou3iui Aiiy auiaqos siqj joj. ojdiuis a\i3a s; sjemijos sqx 

01NI uo uoijis 
-ubjj MO[-oj-q§iq jxsu 3qj sziuSodsj ueo sjnpruis jdrujsjui i£08 3l l B MJ os sp^ 3 
suiqoeui suo )SE3| jb joj qSjq suq XQCXINI ^41 Suuq jsniu aoanos 3uijdaiJ3iui 
sqj 'pa3p3|MOU5|DB si )dnjj3jui ub uoq,\\ ssajppe 3ainos uq-g sqi pUB xflOXNI 
S3AOIU3J usqj SDjnos aqj .'auiwojqns aqj jo pus aqj je (£Qg 3l tf "^J aamos 
aqi oj (3S[nd [3a3[-a\o| b) [BuSis NIMDV ue S3JBJ3U3S auijnojqns idraiajui sqx 'p 

ajnjonjjs jdrujsiui sqi ujjb-3J pUB suiinoj jeqj oj o3 01 psjno 
-3X3 IXH^I B P UE 3p«is sqj uo psDBfd si ssaJppB aqx jdnjj3]ui jeqj sajpuEq JEqj 
suunojqns sqj jo ssajppB 3iJj spuy '3[qBj dn^ooj b Suisn 'pus jj spB3J uoijedoj 
jopsA OJLNI 3 M* > B sunnoj idauaiui sqx ' l uod oj pspsuuoa snq ajejs-ui 3qi 
uo j3yi)U3p! iiq-g sii saocjd puB a\o[ suq XflOJLNI S M s Iind aainos Suqssnbsj v "t 



L'U 


8 


9Id 


L 


9Id 


9 


frld 


9 


ru 


P 


Z'U 


£ 


rid 


Z 


Old 


I 


EEd 


ei 


114 


21 























































































ZV 


















9V 
























SV 






























fV 






































ev 












































2V 


















































IV 


































































OV 








ui>pv ino>pv 
inojui ut)U| 
uipeui jnopeut 




inojui ui;ui 
uipeui inopeui 




inojui ui)ui 
uipeui ;nopeu| 




ui>pv jno^Dv 
inojui ui)u| 
ujpeui inopcui 






01NI — 






1 






4m 


10$ 

ou 




njj 


8!h 


1 
4 


















































aminos idnjjajui 





33JD0S 3AIPV 



aojnos 3A!peu| 



Uj)(DV 



inojui 



uipeui 




ino^Dtf 



u;>ptf 



U|}U| 



jnopeui 



;no;u 



uipeuj 




ino>pv 



UI)U| 



inopeuj 



M jUjpjeH M JO^ pesn vp^O u.ieqD AsieQ £f8 aanDId 



1HDI3 HdldVHD 



wt 



APPLICATIONS 



175 



ADDRESS 

hardint : 



The additional source hardware will entail considerable relative expense for each source. 
As the number of interrupt sources increases, system costs rise rapidly. At some point the 
designer should consider another microcontroller that has extensive interrupt capability. 

Hardint 

The program "Hardint" is used with daisy-chained interrupt sources to service 16 inter- 
rupt sources. An interrupt is falling-edge triggered on INTO and the interrupt address read 
on PI. A lookup table then finds the address of the interrupt routine that is pushed on the 
stack and the RETI "returns" to the interrupt subroutine. The interrupt subroutine issues 
an acknowledgment on port 3.3, which resets the interrupting source. 



MNEMONIC 

.org OOOOh 
ljmp over 



COMMENT 



the interrupt program located at the INTO vector address will read 
the source address on port 1, and push that address for a RETI to 
the interrupt subroutine for that address 



less: 



goback 



base : 



.org 0003h 

setb psw.3 

push ace 

push dpi 

push dph 

mov a, pi 

cjne a,#10h,less 

jnc goback 

rl a 

diov r6,a 

mov dptr, #base 

inc a 

move a, (aa+dptr 

push ace 

mov a,r6 

move a , @a+dptr 

push ace 

reti 

pop dph 

pop dpi 

pop ace 

clr psw.3 

reti 

.dw progO 

.dw progl 

.dw prog2 

.dw prog3 

.dw prog4 

.dw prog5 



choose register bank one 
save registers used 



read port 1 for source address 

valid addresses are OOh to OFh 

invalid, return 

valid address, adjust A for addresses 

save A for low byte fetch 

point to program address lookup table 

point to low byte 

get low byte 

get high byte offset 



execute subroutine; enable interrupt 
return to program in progress 



back to register bank zero 

make lookup table for subroutines 



Continued 



176 



CHAPTER EIGHT 



ADDRESS 

Continued 



progO: 
progl: 
prog2: 
prog3: 
prog4: 
prog5: 
prog6: 
prog7: 
prog8: 
prog9: 
proga: 
progb: 
progc: 
progd: 
proge: 
progf: 



MNEMONIC 

.dw prog6 

.dw prog7 

.dw prog8 

.dw prog9 

.dw proga 

.dw progb 

.dw progc 

.dw progd 

.dw proge 

.dw progf 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 

nop 

ljmp goback 



COMMENT 



; simulate 

; simulate 

; simulate 

; simulate 

; simulate 

; simulate 

; simulate 

; simulate 

; simulate 

simulate 

simulate 

simulate 

simulate 

simulate 

simulate 

simulate 



interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 
interrupt 



subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 
subroutine 



place the main routine here 



Continued 



APPLICATIONS 



177 



ADDRESS 


MNEMONIC 


over : 


mov sp,#2fh 




setb tcon.O 




mov ie,#81h 


here : 


sjmp here 




. end 



COMMENT 

;set stack above addressable bits 

;set IN TO fo r edge triggered 

; enable INTO 

; simulate main program 



■£>— COMMENT 



If the fookup table goes beyond 128 addresses, or 256 bytes, then DPH is incremented by one 
to point to a second complete table. 

Each interrupt subroutine must contain an acknowledge byte that is placed on P3 to reset each 
source. 

Note the use of CJNE and the carry flag to determine relative sizes of two bytes at label "less." 



Putting it all Together 



All of the examples presented to this point have used the free ports (PI and parts of P3) 
that the "cheap" design affords. It is clear that to do a real-world design requires the use 
of additional port chips to enable several functions to be interfaced to the 8051 at one 
time. Such a design is illustrated in this section, using an 8255 programmable port chip 
memory mapped at external RAM location 8000h to 8003h. A review of memory map- 
ping found in Chapter 7 shows that the required address decoding can be done using an 
inverter to enable external RAM whenever A 15 is low, and the 8255 whenever A 15 is 
high. Actually, any address that begins with A15 high can address the 8255; 8000h seems 
convenient. 



Ant 

The example program uses the intelligent LCD display, a coded J 6-key keypad, and is 
capable of serial data communications. This type of design is suitable for many applica- 
tions where a small, inexpensive, alphanumeric terminal (dubbed the ANT) is needed for 
the factory floor or the student lab. 

The design is shown in Figure 8.14. Port A of the 8255 is connected to the keypad. 
Port B supplies data bytes to the LCD and the lower half of port C controls the display. 
The program is interrupt driven by the keypad and the serial port. INTO is used to detect a 
keypress via the AND gate array while the serial interrupt is internal to the 8051. The 
serial port has the highest priority. This type of program is often called "multi-tasking" 
because the routines are called by the interrupt structure, and the computer appears to be 
doing many things simultaneously. 

A keypad program developed in this chapter combined with a serial communication 
program from Chapter 9 completes the design. 

The program "Ant" controls the actions of an 805 1 configured as a terminal with a 
LCD display and hexadecimal keypad. The serial port is enabled, and has the highest 
priority of any function. The coded keyboard is a two-of-eight type which can use a 
lookup table to detect valid key presses. A shift key capability is possible because unique 
patterns are possible if one key is held down while another is pressed. 



178 



CHAPTER EIGHT 



FIGURE 8.14 A Multi-Tasking Circuit Using Memory-mapped I/O 



8031 



12 



28 



17 
16 



39 
38 
37 
36 
35 
34 
33 
32 



10 
11 



INTO 



P3.2 



To RAM CS Pin 



A15 



P2.7 




'373 Latch 



P3.0 



P3.1 



RXD 
TXD 



CS 



Reset 



AO 



Al 
W 



Serial Data 



P3.7 


m 


P3.6 
PO.O 


DO 


PO.l 


01 


P0.2 


D2 


P0.3 


D3 


P0.4 


04 


P0.5 


05 


P0.6 


06 


P0.7 


07 



6 

35 

9 

8 

5 

36 



34 
33 
32 
31 
30 
29 
28 
27 



PAO 



Port A 



8255 
PortB 



PortC 



4 

3 

2 

1 

40 

39 

38 

37 



PBO 18 
19 
20 
21 
22 
23 
24 
25 

PCO 14 
15 
16 
17 
13 
12 
11 
10 



00 



Dl 



D2 



D3 



D4 



D5 



D6 



D7 



R/W 



RS 



EN 



- PC3 
PC4 

— PC5 

- PC6 

— PC7 



Two -Of -Eight 

Coded 

Keyboard 



7 

8 

9 

10 

11 

12 

13 

14 

5 
4 
6 



Hi' 



LCD 
Display 



8255 I/O Ports Mapped At 8000, 8001, And 8002 



ADDRESS 



MNEMONIC 

.equ con,8003h 
.equ prta,8000h 
.equ prtb,8001h 
.equ prtc,8002h 
. equ conant , 98h 
.equ bf,0f3h 
.equ wrd,0f2h 
.equ wrc.OfOh 
.equ setlcd,3fh 
.equ curs,06h 
.equ lcdon.Oeh 



COMMENT 

address of 8255 mode control register 

address of 8255 port A 

address of 8255 port B 

address of 8255 port C 

A = input, B and lower C = output 

C pattern to read LCD busy flag 

C pattern to write data to LCD 

C pattern to write control to -LCD 

initialize LCD to 2 lines, 5 x 10 dots 

LCD cursor blinks, moves left 

LCD on 

Continued 



APPLICATIONS 



179 



ADDRESS 



ant : 



MNEMONIC 

.equ clr,01h 
.org OOOOh 
ljmp over 



COMMENT 

; clear LCD and home cursor 

; jump over the interrupt locations 



when a key is pressed, or a serial data character is sent or 
received, the program vectors to the interrupt address locations; 
dummy routines will be written here; refer to the key routines in 
this chapter and the serial data routines in Chapter 9 for examples 
of these programs 



origin the keypad program here 
jump to keypad handling program 
origin serial interrupt program here 



keypad 



serial 



• org 


0003h 


sjmp 


keypad 


• org 


0023h 


sjmp 


serial 


push 


dph 


push 


dpi 


mov 


dptr , #prta 


movx 


a, @dptr 


pop 


ipl 


pop 


iph 


reti 




nop 




reti 





dummy keypad program, get the key 

read the key value 

insert a key handling routine next 



dummy serial program 



the main program begins here; All the interrupts are initialized, 
the main program sends a "hello" to the display and waits for an 
interrupt 



over: 



here: 
serset 



setb tcon.O 
setb ip.4 
acall serset 
mov dptr,#con 
mov a,#conant 
movx @dptr , a 
mov a,#setlcd 
lcall lcdcon 
mov a,#curs 
lcall lcdcon 
mov a, #lcdon 
lcall lcdcon 
mov a,#clr 
lcall lcdcon 
mov dptr, #msg 
lcall lcddta 
mov ie,#91h 
sjmp here 
ret 



set INTO for edge triggered operation 
set serial interrupt high priority 
call the serial port setup routine 
initialize 8255 mode to basic I/O 
set A = input, B and C = output 
initialize 8255 mode register 
initialize the LCD and say "hello" 



LCD is now initialzed and blank 
use DPTR to point to "hello" 
send the message to the LCD 
enable serial and INTO interrupts 
simulate the rest of the program 
dummy serial setup routine 

Continued 



180 CHAPTER EIGHT 

APDRESS . MNEMONIC COMMENT 

Continued 

The subroutine lcddta sends data characters to the LCD until the 
character ~ is found; the beginning of the message is passed to the 
subroutine in the DPTR by the calling program 

lcddta: movx a,@dptr ; get first character of message 

cjne a,#3eh,mod ;stop when - (3Eh) is found 

ret ; message sent 

mod : acall data ; send data character 

sjmp lcddta ;loop until done 

the subroutine that sends control characters passed in A to the LCD 
display, via the 8255 

lcdcon: push dph .save registers used 

push dpi 

mov dptr,#prtb ;get control data in A to port B 
movx @dptr,a 

mov dptr,#prtc ;point to port C for LCD control 
mov a,#wrc ; strobe character to LCD using port C 
movx @dptr,a 

mov a,#0ffh ;end strobe 
movx @dptr,a 

acall dun ;wait for LCD to finish 
pop dpi ; restore registers 

pop dph 
ret 

the subroutine "data" sends data characters passed in A to the 
LCD screen for display 

data : push dph ; save registers used 

push dpi 

mov dptr,#prtb ;get character data in A to port B 
movx @dptr ,a 
mov dptr,#prtc 

mov a,#wrd ;strobe character to LCD using port C 
movx @dptr ,a 

mov a,#0ffh ;end strobe 
movx @dptr,a 

acall dun ;wait for LCD to finish 

pop dpi ; restore registers 

pop dph 
ret 

;"dun" reads the busy flag on the LCD and returns the flag is low 

Continued 



APPLICATIONS 



181 



ADDRESS MNEMONIC 



COMMENT 



dun: mov dptr,#con 

mov a,#9ah 
movx @dptr,a 
mov dptr.#prtc 
mov a,#bf 
movx @dptr,a 
mov dptr ( #prtb 
movx a,@dptr 
jnb ace. 7, go 
mov dptr.#prtc 
mov a.#Offh 
movx @dptr,a 
sjmp dun 

go: mov a.#Offh 

mov dptr,#prtc 
movx @dptr,a 
mov dptr, #con 
mov a,#98h 
movx @dptr ,a 
ret 
the message "hello" is asse 
messages, each with a unique 

msg: .db "hello-" 



configure port B as an input 



set port C for a read command 

send command to read flag 

read port B 

the busy flag is bit 7 

done when BF = 

if still busy then read again 



finished, remove strobe 



reset port B as an output 



mbled here ; a great number of 
label, can be sent in this way 



£>— COMMENT 



The LCD example shows the extensive use of the DPTR and MOVX command when dealing 
with a memory mapped external port. 

Forgetting to terminate every message with a - results in a very confused LCD as the remainder 
of ROM is written to the LCD. 

There will be no interference between any of these programs if the serial interrupts always have 
priority. Serial data is received as it occurs, and the keypad program and any messages to the 
LCD are suspended for the few microseconds it takes to read the senal port. The suspended 
programs can resume until the next serial character, which is normally an interval of one or 
more milliseconds. 



Summary 



Hardware designs and programs have been illustrated to solve several common application 
problems that are especially suitable for solution using a microcontroller. These hardware 
circuits are 

Keyboards: Lead-per-key, X-Y matrix, coded 
Displays: 7-segment LED, intelligent LCD 
Pulse measurement: frequency, pulse width 



182 CHAPTER EIGHT 



Data converters: R/2R digital to analog, flash analog to digital 
Interrupts: multi-source, daisy chain 
Expanded 8051 system: memory-mapped I/O 

The programs in this chapter interface the 8051 to these circuits. New programming 
concepts introduced are 

Interrupt handling 

Register bank switching in "Svnseg" 

Jump tables in "Lopri" 

Stack RETI in "Hipri" 

Using ONE for relative size in "Hardint" 

Multitasking in "Ant" 

These programs can be used as the kernels for more comprehensive applications. 

Problems 

1. List the most likely effects if a keyboard program docs not accomplish the following: 

a. Debounce keys when pressed down 

b. Check for a valid key code 

c. Wait for all keys up before ending keyboard routine 

d. Debounce keys when released 

2. A keyboard has two keys: run and stop. Write a program that is interrupt driven by these 
two keys using INTO for the run key, and INTI for the stop key. If run is selected, set 
pin P3.0 high; if stop is selected, set the pin low. Bounce time is 10 milliseconds for 
the keys. 

3. Determine why it is important to employ some kind of debounce subroutine in a key- 
board program, particularly for interrupt driven programs, even if keys with absolutely 
no bounce are used. 

4. The lookup table used in the program "Codekey" is very inefficient, using 256 bytes to 
form a table for the valid keys and using an FFh in all other locations for invalid keys. 
Write a subroutine using a series of CJNE instructions that will obtain the same result. 

5. Repeat problem 4 by converting the keycode number in A from the codes B7h-EEh to 
00-09h. One way to do this is to convert the first and second nibbles to the following 
numbers and then adding the nibbles to get a unique number: 



CHANGE 




First Nibble 


Second Nibble 


Add Converted Nil 


E toO 


EtoO 


EE to 00 DD to 05 


D to 4 


D to 1 


ED to 01 DBto06 


B to 8 


Bto2 


EB to 02 D7 to 07 




7 to 3 


E7 to 03 BE to 08 
DE to 04 BD to 09 



Note: Lookup tables can be used for each conversion, with invalid codes in both nibble 
lookup tables set to return numbers that, when added, sum to greater than 09. 

6. Write a lookup table subroutine for the program "Bigkey" that will convert the row and 
column bytes for each key to a single byte number. 



APPLICATIONS 183 



7. Expand the lookup table "convert" in the program "Svnseg" to include these characters: 
G, H, I, J, L, O. P, S, T, and U. 

8. Write a program that will display the following message on the intelligent display: 

"Hello! 
Please Enter Command. " 

Center each line of the display. 

9. Write a subroutine that is past the starting address of an ASCII string in ROM and then 
displays the string on the intelligent display. The string length is fixed. 

10. Repeat Problem 9 for a string of any length. 

11. Write a program for the LCD display that will display the contents of register Rl as 
follows: 

Rf = XX 

XX is the Rl contents in hex. Center the display. (Hint: Remember the contents are in 
hex, and the display speaks ASCII.) 

12. Write a program using timer that will delay exactly . 100000 milliseconds ± I micro- 
second from the time the timer starts until it is stopped. (The crystal frequency is 

16 megahertz). 

13. Make a table that shows the accuracy of pulse width measurements as a function of 
multiples of count periods (.75 microseconds). The table should be arranged as follows: 

PULSE WIDTH (x.75 fj,s) ACCURACY (%) 1 

2 

3 

4 

5 

6 

7 

8 

9 

10 

20 

50 

100 

14. Write a program that can use the stack to "return" to any of 256 subroutines pointed to 
by the number 00 to FFh in A. 

15. Compose a 40-value lookup table that will generate a sawtooth wave using a D/A 
converter. 

16. Repeat Problem 15 without using a lookup table of any kind. 

17. Repeat Problem 15 for a rectified sine wave. 

18. Outline a method of measuring the frequency of a sine wave using a flash A/D 
converter. Estimate the highest frequency that can be measured to an accuracy of 1 
percent. 

19. In the section on measuring frequency, an expression was found for n bit resolution of a 
frequency measured over time, T: 



184 CHAPTER EIGHT 

T x (fmax - fmin) 



LSB = 



2" 



Derive an equivalent expression for the resolution of a frequency to n bits by measuring 
the period of M of the cycles. 

20. Write a program that finds frequency by measuring the time for M cycles of the unknown 
periodic wave. Estimate the highest frequency that can be measured to an accuracy of 
1 percent if the crystal is 16 megahertz. 

2T. Write a program that performs all of the functions of an intelligent daisy chain interrupt 
source controller. 

22. Write a lookup table program for the "Ant" program that will allow the F key of a 

two-of-eight coded keypad to be used as a shift key. A shift key makes possible 31 valid 
key combinations. The key codes are 



KEY 


OUTPUT 


PIN 








1 2 


3 


4 


5 


6 


7 8 


9 





X 






X 






X 


1 


X 








X 




X 


2 


X 










X 


X 


3 


X 










X 


X 


4 


X 






X 






X 


5 


X 








X 




X 


6 


X 










X 


X 


7 


X 










X 


X 


8 




X 




X 






X 


9 




X 






X 




X 


A 




X 








X 


X 


B 




X 








X 


X 


C 






X 


X 






X 


D 






X 




X 




X 


E 






X 






X 


X 


F 






X 






X 


X 



x means a connection is made; pin 9 is the common pin for all codes. 




Serial Data Communication 



Chapter Outline 

Introduction 

Network Configurations 



8051 Data Communication Modes 
Summary 



Introduction 



185 



Chapter 2 contained an extensive review of serial data communication concepts and the 
hardware and software that is built into the 805 1 for enabling serial data transfers. Chapter 7 
contained some brief programming examples of how this capability may be used. Serial 
data transmission has become so important to the overall computing strategy of industrial 
and commercial applications that a separate chapter on this crucial subject is appropriate. 

One hallmark of contemporary computer systems is interconnectivity; the joining of 
computers via data networks that link the computers to each other and to shared resources, 
such as disk drives, printers, and other I/O devices. The beginning of the "computer age" 
saw isolated CPUs connected to their peripherals using manufacturer-specific data trans- 
mission configurations. One of the peripherals, however, was the teletype that had been 
borrowed from the telephone industry for use as a human interface to the computer, using 
the built-in keyboard and printer. 

The teletype was designed to communicate using standard voice grade telephone lines 
via a modem (Modulator demodulator) that converts digital signals to analog frequencies 
and analog frequencies to digital signals. The data, by the very nature of telephone voice 
transmission, is sent and received serially. Various computer manufacturers adapted their 
equipment to fit the teletype, and, perhaps, the first "standard" interface in the industry 
was born. 

This standard was enhanced in the early I960's with the establishment of an electrical/ 
mechanical specification for serial data transmission that was assigned the number RS 232 



186 CHAPTER NINE 



by the Electronics Industry Association. A standard data code was also defined for all the 
characters in the alphabet, decimal numbers, punctuation marks, and control characters. 
Based on earlier telephonic codes, the standard became known as the American Standard 
Code for Information Interchange (ASCII). 

The establishment of RS 232 and ASCII coincided with the development of multi- 
user computer organizations wherein a number of users were linked to a host mainframe 
via serial data links. By now, the CRT terminal had replaced the slower teletype, but the 
RS 232 serial plug remained, and serial data was encoded in ASCII. Peripheral devices, 
such as printers, adopted the same standards in order to access the growing market for 
serial devices. 

Serial data transmission using ASCII became so universal that specialized integrated 
circuits, Universal Asynchronous Receiver Transmitters (UARTS) were developed to per- 
form the tasks of converting an 8-bit parallel data byte to a 10-bit serial stream and con- 
verting 10-bit serial data to an 8-bit parallel byte. When the second -gene rat ion 8051 
microcontroller was designed, the UART became part of the circuit. 

Chapter 7 introduced the basic programming concepts concerning transmitting and 
receiving data using the serial port of the 8051. In this chapter, we study the serial data 
modes available to the programmer and develop programs that use these modes. The four 
modes are as follows: 

Mode 0; Shift register mode 
Mode 1 : Standard UART mode 
Mode 2: Multiprocessor fixed mode 
Mode 3: Multiprocessor variable mode 

In this chapter, we also identify multiprocessor configurations that are appropriate for 
each mode and write sample programs to enable data communication between 8051 
microcontrollers. 



Network Configurations 



The first problem faced by the network system designer is how to physically hook the 
computers together. The two possible basic configurations are the star and the loop, which 
are shown in Figure 9. 1 . 

The star features one line from a central computer to each remote computer, or from 
"host" to "node." This configuration is often used in time-sharing applications when a 
central mainframe computer is connected to remote terminals or personal computers using 
a dedicated line for each node. Each node sees only the data on its line; all communication 
is private from host to node. 

The loop uses one communication line to connect all of the computers together. There 
may be a single host that controls all actions on the loop, or any computer may be enabled 
to be the host at any given time. The loop configuration is often used in data-gathering 
applications where the host periodically interrogates each node to collect the latest infor- 
mation about the monitored process. All nodes see all data; the communication is public 
between host and nodes. 

Choosing the configuration to use depends upon many external factors that are often 
beyond the control of the system designer. Some genera! guidelines for selection are 
shown in the following table: 



SERIAL DATA COMMUNICATION 187 



FIGURE 9.1 Communication Configurations 




Star Configuration 



Node 



Node 



Node 

X 



Node 

X 



Node 

X 



Node 

X 



Node 



Node 



Host 



Loop Configuration 



Objective Network Comments 

Reliability Star Single node loss per line loss 

Fault isolation Star Fault traceable to node and line 

Speed Star Each node has complete line use 

Cost Loop Single line for all nodes 

The star is a good choice when the number of nodes is small, or the physical distance 
from host to node is short. But, as the number of nodes grows, the cost and physical space 
represented by the cables from host to nodes begins to represent the major cost item in the 
system budget. The loop configuration becomes attractive as cost constraints begin to out- 
weigh other considerations. 

Microcontrollers are usually applied in industrial systems in large numbers distributed 
over long distances. Loop networks are advantageous in these situations, often with a host 
controlling data transmission on the loop. Host software is used to expedite fault isolation 



188 CHAPTER NINE 



FIGURE 9.2 Hybrid Communication Configurations 



Node -I 



Node - > 



Node 



H 



Node 

n: 



Node 



Host 



Node 



Node 




Node 



Node 



Node 



■— Node 



Star -Loop 



Node 




Node 




Node j 




\ 






J 


Node 




Loop 
Host 




Node 



Node 




Node 




Node 




\ 






? 




Node 




Loop 
Host 




Node 



Node 



Node 



Node 



Node 



\jy 



Loop 
Host 



Node 



Host 



Loop -Star 



and, thus, improve system reliability. High speed data transmission schemes can be em- 
ployed to enhance system response time where necessary. 

The old racing adage "Speed costs money: How fast do you want to go?" should be 
kept in mind when designing a loop system. Successors to RS 232, most notably RS 485, 
have given the system designer 1 00 kilobaud rates over 4000-foot distances using inexpen- 
sive twisted-pair transmission lines. Faster data rates are possible at shorter distances, or 
more expensive transmission lines, such as coaxial cable, can be employed. Remember 
that wiring costs are often the major constraint in the design of large distributed systems. 

Many hybrid network arrangements have evolved from the star and the loop. Fig- 
ure 9.2 shows two of the more popular types that contain features found in both basic 
configurations. 



SERIAL DATA COMMUNICATION 189 

8051 Data Communication Modes 

The 8051 has one serial port — port pins 3.0 (RXD) and 3.1 (TXD) — that receives and 
transmits data. All data is transmitted or received in two registers with one name: SBUF. 
Writing to SBUF results in data transmission; reading SBUF accesses received data. 
Transmission and reception can take place simultaneously, and the receiver can be in the 
process of receiving a byte while a previous byte is still in SBUF. The first byte must be 
read before the reception is complete, or the second byte will be lost. 

Physically the data is a series of voltage levels that are sampled, in the center of the 
bit period, at a frequency that is determined by the serial data mode and the program that 
controls that mode. All devices that wish to communicate must use the same voltage 
levels, mode, character code, and sampling frequency (baud rate). The wires that connect 
the ports must also have the same polarity so that the idle state, logic high, is seen by 
all ports. 

The installation and checkout of a large distributed system are subject to violations of 
all of the "same" constraints listed previously. Careful planning is essential if cost and 
time overruns are to be avoided. 

The four communication modes possible with the 8051 present the system designer 
and programmer with opportunities to conduct very sophisticated data communication 
networks. 

Mode 0: Shift Register Mode 

Mode is not suitable for the interchange of data between 8051 microcontrollers. Mode 
uses SBUF as an 8-bit shift register that transmits and receives data on port pin 3.0, while 
using pin 3. 1 to output the shift clock. The data and the shift clock are synchronized using 
the six internal machine states, and even for microcontrollers using the same crystal fre- 
quency, they can be slightly out of phase due to differences in reset and start-up times. 
Figure 9.3 shows the timing for the transmission and reception of a data character. 
Remember that the shift clock is generated internally and is always from the 8051 to the 
externa] shift register. The clock runs at the machine cycle frequency of f/12. Note that 
transmission is enabled any time SBUF is the destination of a write operation, regardless 
of the state of the transmitter empty flag, SCON bit 1 (TI). 

FIGURE 9.3 Mode Timing 

Shift Data Out 
S6P2 

| I | I 1 I I | 

I DO I 01 ' D2 ' 03 i D4 I D5 I D6 I 07 | External Data Bits Shifted Out 

1 — H — ri — ,i. i . 1 — n ■ 



RXD Data Out 



TXD Clock 



1 1 I 2 | 3 | 4 , 5 ] 6 1 7 1 8 
S3P1 l s6P1 I 1 i 1 ) 1 1 

RXD Data In | DO || 01 f| 02 | 03 f P4 1 1 P5 j | P6 1 1 D7| 



External Data Bits Shifted In 



S5P2 
Shift Data In 



190 CHAPTER NINE 



Data is transmitted, LSB first, when the program writes to SBUF. Data is shifted 
right during S6P2, or 24/f seconds after the rising edge of the shift clock at S6P1 . Data is 
stable from just after S6P2 for one cycle. Good design practice dictates that the data be 
shifted into the external shift register during the high-to-low transition of the shift clock, 
at S3PI , to avoid problems with clock skew. 

The receiver is enabled when SCON bit 5 (REN) is enabled by software and SCON 
bit (RI) is set to 0. At the end of reception RI will set, inhibiting any form of character 
reception until reset by the software. The condition of RI cleared to is unique for mode 
0; all other modes are enabled to receive when REN is set without regard as to the state of 
RI. The reason is clear: Mode is the only mode that controls when reception can take 
place. Enabling reception also enables the clock pulses that shift the received data into the 
receiver. 

Reception begins, LSB first, with the data that is present during S5P2, or 24/f sec- 
onds before the rising edge of the shift clock at S6P1 . The incoming data is shifted to the 
right. Incoming data should be stable during the low state of the shift clock, and good 
design practice indicates that the data be shifted from the external shift register during the 
low-to-high transition of the shift clock, at S6P1 , so that the data is stable up to one clock 
period before it is sampled. 

A serial data transmission interrupt is generated at the end of the transmission or re- 
ception of bit eight if enabled by the ES interrupt bit EI. 4 of the enable interrupt register. 
Software must reset the interrupting bit RI or TI. As the same physical pin is used for 
transmission and reception, simultaneous interrupts are not possible. 

Mode is well suited for rapid data collection and control of multi-point systems that 
use a simple two-wire system for data interchange. Multiple external shift registers can 
expand the external points to an almost infinite number, limited only by the response time 
desired for the application. For instance, at f — 16 megahertz, each point of a 10,000 
point system could be monitored every 60 milliseconds. Common industrial systems do 
not require rates this high, and a reasonable rate of one point per second would leave 
adequate time for processing by the program. 

Modezero 

A small system that features 16 points of monitored data and 16 points of control is shown 
in Figure 9.4. Data from the process is converted from parallel to serial in the '166 type 
registers. Data to the process is converted from serial to parallel in the type '164 registers 
and latched into the *373 latches. 

It is important that the data be "frozen" before the shifting begins. The bits shifted in 
could be changed before reaching the microcontroller, or a control bit might be changed, 
momentarily, as it shifts through the output shift registers. Port pin 3.2 is used to disable 
the input registers from the process when high and to enable loading input values when low. 

To read the inputs, P3.2 is brought high and the receiver is enabled (twice) to generate 
16 input shift clocks. The high level on P3.2 prevents the shift clocks from reaching the 
output registers. At the end of the read, P3.2 is brought low to enable loading input values 
into the input registers. No clock pulses are generated, so the output control registers do 
not change state. 

Control bits to the output registers are transmitted when P3.2 is low and SBUF has 
two data bytes written in succession. The two bytes generate 16 clock pulses that fill the 
output registers with the SBUF data. Port pin 3.3 is used to latch the newly shifted control 
data to the process by strobing the output data latches. A program that monitors and con- 
trols the points follows. 



SERIAL DATA COMMUNICATION 191 



FIGURE 9.4 Shift Register Circuit Used with Modezero Program 



Monitored Data 



+ 5V 




18 17 14 13 8 7 4 3 

' 373 1 1 11 

Latch J 1.11 

19 16 15 12 9 6 5 2 



I I I I I I I I 



18 17 14 13 8 7 4 3 

'^l X l.H 

Latch T 

19 16 15 12 9 6 5 2 



I I I I 1 I 1 I 



+ 5V 



Latch 



12 


P3.2 


11 


P3.1 


10 


P3.0 



8031 



13 P3.3 



Controlled Points 



ADDRESS 



modezero 



The program "modezero" monitors 16 bits and controls the state of 16 bits. The 
system can be expanded indefinitely by expanding the shift register configurations shown 
in Figure 9.4. In this example program, whatever data is read on the monitored points is 
written to the control points. The direction of data flow to/from the 8051 is controlled 
by P3.2, (high = in). P3.3 latches new data to the process. 



MNEMONIC 

.org OOOOh 
.equ monl,70h 
.equ mon2,71h 
clr p3.2 

setb p3.2 
acall monit 
mov monl.a 
acall monit 
mov mon2,a 
clr p3.2 



COMMENT 

;store first 8 monitored points 

;store second 8 monitored points 

;load data from process to input 

; registers 

;enable data shift in 

;get first byte 

; store first byte 

;get second byte 

; store second byte 

;enable data to be shifted out 



Continued 



192 



CHAPTER NINE 



ADDRESS 

Continued 



MNEMONIC 

acall conit 
mov a.monl 
acall conit 
c 1 r p3 . 3 
setb p3.3 
sjmp modezero 



COMMENT 

; start sending data, second byte first 

; get first byte 

;send first byte 

; latch data to output latches 

; end latch strobe 

;loop for any new input 



the routine that reads the monitored points follows 



monit : 
here : 



mov scon.#10h 

jnb scon.O, here 
mov scon, #00h 
mov a.sbuf 
ret 



; set mode and enable reception 

; reset RI 

;wait for end of reception 

; clear receive enable and interrupt bit 

; read byte received 

; return to calling program 



the routine that sends the control data follows 



conit : 


mov scon,#00h 




mov sbuf.a 


wait : 


jnb scon . 1 , wait 




ret 


r\ 


. end 
mMMCMT 



set mode and clear all interrupt bits 
start transmission 
wait until transmission complete 
return to calling program 



Note that in both the transmit and receive cases the interrupt bit must go high before the 

subroutine can be ended. 

The data transmit and reception time is so short that interrupt-driven schemes are not efficient. 

Mode 1 : Standard 8-Bit UART Mode 

In Chapter 7, several simple communication programs are studied that use the serial port 
configured as mode 1, the standard UART mode normally used to communicate in 8-bit 
ASCII code. Only seven bits are needed to encode the entire set of ASCII characters. The 
eighth bit can be used for even or odd parity or ignored completely. Asynchronous data 
transmission requires a start and stop bit to enable the receiving circuitry to detect the start 
and finish of a complete character. A total of ten bits is needed to transmit the 7-bit ASCII 
character, as shown in Figure 9.5. 

Transmission begins whenever data is written to SBUF. It is the responsibility of the 
programmer to ensure that any previous character has been transmitted by inspecting the 
TI bit in SCON for a set condition. Data transmission begins with a high-to-low start bit 
transition on TXD that signals receiving circuitry that a new character is about to arrive. 
The 8-bit character follows, LSB first and MSB parity bit last, and then the stop bit, which 
is high for one bit period. If another character follows immediately, a new start bit is 
signaled by a high-to-low transition; otherwise, the line remains high. The width of each 
transmitted data bit is controlled by the baud rate clock used. The receiver must use the 
same baud rate as the transmitter, or it reads the data at the wrong time in the character 
stream. 



SERIAL DATA COMMUNICATION 193 



FIGURE 9.5 Asynchronous 8-Bit Character Used in Mode 1 



Idle State Idle State 

I F 1 T 1 T T T T 

Ill2l3l4l5l6l7l8l 
L J. J_____L I L L L I 



Start -* fc~ Data Bits S *?P 

Bit i Bit 



f 



Reception begins if the REN bit is set in SCON and a high-to-low transition is sensed 
on RXD. Data bits are sampled at the baud rate in the center of the bit duration period. 
The received character is loaded into SBUF and the stop bit into SCON bit 2 (RB8) //the 
RI bit in SCON is cleared, indicating that the program has read the previous character; 
and either SM2 in SCON is cleared or SM2 is set and the received stop bit is high, which 
is the normal state for stop bits. 

If these conditions are met, then SBUF is loaded with the received character, and RI 
is set. If the conditions are not met, the character is ignored, RI is not set, and the receive 
circuitry awaits the next start bit. 

The restriction that a new character is not accepted unless RI is cleared seems reason- 
able. Data is lost if either the previous byte is overwritten or the new byte discarded, 
which is the action taken by the 8051 . The restriction on SM2 and the stop bit are not as 
obvious. Normally, SM2 will be set to 0, and the character will be accepted no matter 
what the state of the stop bit. Software can check RB8 to ensure that the stop bit is correct 
before accepting the character if that is thought to be important. 

Possible reasons for setting SM2 to force reception only when the stop bit is a 1 could 
be useful if the transmitter has the ability to change the stop bit from the normal high state. 
If the transmitter has this capability, then the stop bit can serve as an address bit in a 
multiprocessor environment where many loop microcontrollers are all receiving the same 
transmission. Only the microcontroller that has SM2 cleared can receive characters end- 
ing in either of the stop bit states. If all the microcontrollers but one have SM2 set, then all 
data transmissions ending in a low stop bit interrupt the unit with SM2 = 0; the rest ignore 
the data. Transmissions ending in a high stop bit can interrupt all microcontrollers. 

Transmitters with the capability to alter the stop bit state are not standard. The 8051 
communication modes 2 and 3 use the SM2 bit for multiprocessing. Mode 1 is not needed 
for this use. 

In summary, mode 1 should be used with SM2 cleared, as a standard 8-bit UART, 
with software checks for proper stop bit magnitude if needed. As discussed in Chapter 7, 
the baud rate for modes 1 and 3 are determined by the overflow rate of timer 1 , which is 
usually configured as an auto-reload timer. PCON bit 7 (SMOD) can double the baud rate 
when set. 

Modeone 

Mode I is most likely to be used in a dedicated system where the 805 1 serial port is con- 
nected to a single similar port. A program that transmits and receives large blocks of data on 
an interrupt-driven basis is developed to investigate some problems common to data inter- 
change programs. 

To the main program, interrupt-driven communication routines are transparent: Data 
appears in RAM as it is received and disappears from RAM as it is transmitted. In both 
cases, the link between the main program and the interrupt-driven communication sub- 



194 CHAPTER NINE 



routines are areas of RAM called buffers. These buffers serve to store messages that are to 
be sent and messages that are received. 

Each buffer area is defined by two memory pointers. One pointer contains the address 
of the top of the buffer, or the location in RAM where the next character is to be stored, 
and the second contains the address of the next character to be read. The buffers are 
named "inbuf," for use in storing characters as they are received, and "outbuf," for stor- 
ing characters that are to be sent. The pointers to the tops of the buffers are named "intop" 
and "outop," respectively, while the pointers to the next character to be read are named 
"inplace" and "outplace." 

The two buffers work in exactly the same way. The receive subroutine fills inbuf as 
characters are received and updates intop as it operates. The main program empties inbuf 
as it can and keeps inplace pointing to the next character to be read. The main program 
fills outbuf, while keeping outop updated to point to the next character to be stored. The 
transmission subroutine empties outbuf as it can and keeps outplace pointing to the next 
character to be read from outbuf. 

These actions continue until the pointer to the top of the buffer equals the pointer to 
the next character. The buffer is now empty, and the pointers can be reset to the bottom of 
the buffer. 

The buffer areas and pointers may be summarized as follows: 

Outbuf: An area of RAM that holds characters to be transmitted 

Outop: Pointer to outbuf that holds the address of the next character to be stored by 
the main program for transmission 

Outplace: Pointer to outbuf that holds the address of the next character to be trans- 
mitted by the transmit subroutine 

Inbuf: An area of RAM that holds received characters 

Intop: Pointer to inbuf that holds the address of the next character received by the 
receive subroutine 

Inplace: Pointer to inbuf that holds the address of the next character to be read by the 
main program 

The main program and the transmit subroutine does not read data from a buffer when- 
ever the place pointer equals the top pointer, which indicates that the buffer is empty. 

The programmer has to make an estimate of how large the buffers need to be. Some- 
times the general nature of the data is known when the system is in the design phase. The 
programmer(s) for the two computers that are communicating can define message length 
and frequency, arriving at a worst-case buffer size. 

If the 8051 is part of a peripheral, such as a printer, that randomly receives large 
quantities of data, then the buffer size is fixed at an economic and competitive number 
using external RAM. For short and infrequent messages, internal RAM may suffice. In 
both cases, the receiving subroutine should have a means of communicating to the source 
of data when inbuf is becoming full so that the data flow can be suspended while inbuf is 
emptied. Our example program falls somewhere between these extremes; some external 
RAM will be needed, but not 32 kilobytes. 

Registers R0 and Rl of register banks and 1 are used effectively as pointers to the 
first 256d bytes of external RAM using MOVX instructions. For this example, the buffer 
sizes are fixed at I28d bytes each, although there is no need for them to be of equal size. 
Larger buffers can be constructed using the DPTR. 

A program named "Modeone" handles communications between the 8051 and another 
computer using serial data mode 1 . Two 1 28d byte buffers in external RAM store charac- 



SERIAL DATA COMMUNICATION 



195 



ters to be transmitted or received. RO and R I of register bank keep track of data flow for 
the receive buffer inbuf, located in external RAM addresses OOh to 7Fh. RO and RI of 
register bank I serve the transmit buffer outbuf, external RAM addresses 80h to FFh. RO 
is the place pointer, R l the top pointer to the buffers. The baud rate is set by timer I in the 
auto-reload mode to 1200 bits per second. Port pin 3.2 is set high when inbuf is I byte 
from a full condition. 



ADDRESS 

modeone : 



rcve : 



rok: 
full 



xmit 



mor: 



go: 



MNEMONIC 

.org OOOOh 
sjmp over 
.org 0023h 

push psw 

push ace 

jbc scon.O , rcve 

jbc scon . 1 ,xmit 

sjmp go 

clr psw. 3 

mov a.sbuf 

movx (Srl.a 

inc rl 

cjne rl ,#7eh, rok 

setb p3 . 2 

sjmp full 

clr p3.2 

jbc scon. 1 ,xmit 

sjmp go 
setb psw. 3 
mov a.rO 
cjne a,09h, mor 

mov r0,#80h 

mov rl.rO 
sjmp go 
movx a,(5r0 
mov sbuf.a 
inc rO 
pop ace 
pop psw 
reti 



COMMENT 

jump over serial interrupt address 

serial interrupt vectors to this 

address 

save register bank status 

save A 

serve the received data first 

transmit data as a second priority 

should never get to this jump 

select register bank pointers to 

inbuf 

get received character 

store character at top of inbuf 

increment top address of inbuf 

see if inbuf is almost full 

signal data source of full condition 

remove full signal to source 
see if transmit interrupt also 
occurred 

if not then return 
select bank 1 pointers to outbuf 
compare RO and Rl for equality 
internal RAM address 09h = Rl, 
bank one 

reset both pointers to bottom of 
, outbuf 

buffer is empty; return 

get next character to be transmitted 

begin transmission 

point to next transmit character 

restore A and PSW, return 



the main program begins here; for the purpose of this example, the 
main program will send the character T repeatedly 



over: 



mov sp,#10h 
mov rO,#OOh 



;set SP above register bank one 
;set inbuf pointers to bottom of 



Continued 



196 



CHAPTER NINE 



ADDRESS 

Continued 



loop 



rd: 
send 

sd: 



MNEMONIC 



mov rl,#00h 
setb psw.3 

mov r0,#80h 
mov rl,#80h 
clr p3.2 
mov scon,#50h 

mov thl,#0bbh 
orl pcon,#80h 
mov tmod,#20h 
mov tcon, #40h 
mov ie,#90h 
clr psw.3 

mov a,rO 
cjne a.Olh.rd 
mov rO,#OOh 

mov rl,#00h 

sjmp send 

movx a,@rO 

inc rO 

setb psw.3 

cjne rl,#O0h,sd 

sjmp loop 

mov a,#'T' 

movx (a rl , a 

inc rl 

cjne rl , #81h, loop 

setb scon. 1 

sjmp loop 
. end 



COMMENT 



buffer 



set outbuf pointers to bottom of 
buffer 



; signal source that inbuf is not full 
; set serial port mode 1 ; enable 
; receiver 

;set TH1 for 187d (baud rate = 1208) 
;set SMOD to double baud rate 
set timer 1 to auto-reload mode 
start Tl to generate baud clock 
; enable only serial interrupt 
set pointers to inbuf and get 
any data 

inbuf is empty when intop = inplace 
Rl of bank is direct address Olh 
buffer empty, reset pointers to 
bottom 

send the character T 

get character 

point to next character 

set pointers to outbuf and store data 

see if outbuf is full and loop if so 

Rl rolls over from FFh to OOh if full 

put the character T in outbuf 

store a T in outbuf 

point to top of outbuf 

initiate transmission if first T 

start transmission process for first 

T 

continue 



COMMENT 



Note that the program has to initiate the first interrupt for the first character that is stored in a 
previously empty outbuf. If the first interrupt action were not done, transmission would never 
take place, as the Tl bit would remain a 0. The state of the Tl bit is ambiguous: It can mean 
that the transmitter is busy sending a byte or that no activity is taking place at all. The 1 state of 
Tl is specific: A byte has been transmitted, and SBUF can receive the next byte. 

The example program fills outbuf quickly, until outop rolls over to OOh. Outbuf is emptied until 
outplace rolls over also, and outbuf is re-initialized to 80h. Received data is always read before 
inbuf can fill up, as there is very little for the program to do. Adding a time delay in the program 
ensures that inbuf grows beyond one byte. 



Continued 



SERIAL DATA COMMUNICATION 197 

COMMENT 

The data source should cease sending data to the 8051 until port 3.2 goes low. In this example, 
"full" is arbitrarily set at one byte below the maximum capacity of inbuf. The actual number 
for a full condition should be set at maximum capacity less the response time of the source 
expressed in characters. 

No feedback from the source to the 8051 has been provided for halting transmission of data 
from the 8051. Feedback can be accomplished by using one of the INT lines as an input from 
the source to signal a full condition. 

Modes 2 and 3: Multiprocessor 

Modes 2 and 3 are identical except for the baud rate. Mode 2 uses a baud rate of f/32 if 
SMOD (PCON.7) is cleared or f/64 if SMOD is set. For our 16 megahertz example, this 
results in baud rates of 500000 and 250000 bits per second, respectively. Pulse rates of 
these frequencies require care in the selection and installation of the transmission lines 
used to carry the data. 

Baud rates for mode 3 are programmable using the overflows of timer 1 exactly as for 
data mode 1. Baud rates as high as 83333 bits per second are possible using a 16 mega- 
hertz crystal. These rates are compatible with RS 485 twisted-pair transmission lines. 

Data transmission using modes 2 and 3 features eleven bits per character, as shown in 
Figure 9.6. A character begins with a start bit, which is a high-to-low transition that lasts 
one bit period, followed by 8 data bits, LSB first. The tenth bit of this character is a pro- 
grammable bit that is followed by a stop bit. The stop bit remains in a high state for a 
minimum of one bit period. 

Inspection of Figures 9.5 and 9.6 reveals that the only difference between mode 1 and 
mode 2 and 3 data transmission is the addition of the programmable tenth bit in mode 
2 and 3. 

When the 8051 transmits a character in mode 2 and 3, the eight data bits are whatever 
value is loaded in SBUF. The tenth bit is the value of bit SCON. 3, named TD8. This bit 
can be cleared or set by the program. Interrupt bit TI (SCON. 1 ) is set after a character has 
been transmitted and must be reset by program action. 

Characters received using mode 2 and 3 have the eight data bits placed in SBUF and 
the tenth bit is in SCON. 2, called RB8, if certain conditions are true. Two conditions 
apply to receive a character. First, interrupt bit RI (SCON.O) must be cleared before the 
last bit of the character is received, and second, bit SM2 (SCON. 5) must be a or the 
tenth bit must be a I. If these conditions are met, then the eight data bits are loaded in 
SBUF, the tenth bit is placed in RB8, and the receive interrupt bit RI is set. If these con- 
ditions are not met, the character is ignored, and the receiving circuitry awaits the next 
start bit. 

The significant condition is the second. If RI is set, then the software has not read 
the previous data (or forgot to reset RI), and it would serve no purpose to overwrite the 

FIGURE 9.6 Asynchronous 9-Bit Character Used in Modes 2 and 3 

Idle State Idle State 

1 | T T T T T T 1 1 1 

Ill2l3l4l5l6l7l8l9 (TB8) I 

I I X I I L J J I J I 

Start t » Data Bits st °P 

Bit 1 Bit 

f t *~ 



198- CHAPTER NINE 



data. Clearing SM2 to allows the reception of multiprocessor characters transmitted in 
mode 2 and 3. Setting SM2 to I prevents the reception of those characters that have bit ten 
equal to 0. Put another way, if bit ten is a 1 , then reception always takes place; SM2 is 
ignored, //bit ten is a then only those receivers with SM2 set to are interrupted. 

Mode 2 and 3 has been included in the 8051 specifically to enhance the use of mul- 
tiple 8051s that are connected to a common loop in a multiprocessor configuration. The 
term multiprocessing implies many processors acting in some unified manner and con- 
nected so that data can be interchanged between them. When the processors are connected 
in a loop configuration, then there is generally a controlling or "talker" processor that 
directs the activities of the remainder of the loop units, or "listeners." 

One particular characteristic of a talker-listener loop is the frequent transmission 
of data between the talker and individual listeners. All data broadcast by the talker is 
received by all the listeners, although often the data is intended only for one or a few 
listeners. At times, data is broadcast that is meant to be used by alt the listeners. 

There are many ways to handle the addressing problem. Systems that use standard 
UART technology, such as mode 1 , can assign unique addresses to all the listeners. Each 
message from the talker can begin with the address of the particular listener for which it is 
intended. When a message is sent, all the listeners process the message and react only if 
the address that begins the message matches their assigned addresses. If messages are sent 
frequently, the listeners will waste a lot of processing time rejecting those messages not 
addressed to them. 

Mode 2 and 3 reduces processing time by enabling character reception based upon the 
state of SM2 in a listener and the state of bit ten in the transmitted character. A single 
strategy is used to enable a few listeners to receive data while the majority ignore the 
transmissions. 

All listeners initially have SM2 set to 0, the normal reset state, and receive all multi- 
processor messages. Each listener has a unique address. The talker addresses each of the 
listeners that are not of interest and commands them to set SM2 to 1 , leaving the listeners 
to which communication is desired with SM2 cleared to 0. All characters from the talker 
to the unique listeners are then sent with bit ten set to 0. The listener(s) with SM2 cleared 
receive the data; those with SM2 set ignore the data due to the condition of bit ten. Com- 
munication with all listeners is done by setting bit ten to I , which enables reception of 
characters with no regard as to the state of SM2. 

A variation of this strategy is to have all listeners set SM2 to 1 upon power-up. All 
address messages have a I in bit position ten, so all listeners receive and process any address 
message to see whether action is required. Listeners chosen are commanded in the address 
message to set SM2 to 0, and data communication proceeds with bit ten cleared to 0. 

The multiprocessing strategy works best when there is extensive data interchange 
between the talker and each individual listener. Frequent changes of listeners with little 
data flow results in heavy address usage and subsequent interruption of all listeners to 
process the address messages. 

Modethree 

A multiprocessor configuration that demonstrates, the use of mode 3 is shown in Figure 
9.7. An RS 485 twisted-pair transmission line is used to form a loop that has 15d 8051 
microprocessors connected to the lines so that all data on the loop is common to all serial 
ports. The 8051 has been programmed to be the talker, and the rest are listeners. 

The purpose of the loop is to collect ten data bytes from each listener, in sequential 
order. All listeners initialize SM2 to 1 after power-up, and the talker configures all address 



SERIAL DATA COMMUNICATION 



199 



FIGURE 9.7 Communication Loop Used for Modethree Program 

SM2 - 1 







Listener 
01 




Listener 
02 




Listener 
03 




Listener 
04 




Listener 
05 




Listener 
06 




Listener 
07 




























































Talker 
(8051) 






































RS485 






























SM2 =0 
















































Listener 
08 




Listener 
09 




Listener 
OA 




Listener 
OB 




Listener 
OC 




Listener 
00 




Listener 
OE 



messages using a 1 in bit ten. Addressed listeners transmit ten data characters to the talker 
with bit ten set to 0. The talker has SM2 set to so that all communications from listeners 
are acknowledged. Data characters from a listener to the talker are ignored by the remain- 
ing listeners. At the end of the ten data bytes, the addressed listener resets SM2 to 1 . The 
data rate is set by timer 1 in the auto-reload mode to be 83333 baud. That portion of the 
talker and listener program that has to do with setting up the multiprocessor environment 
will be programmed. 

The messages that are sent from the talker to the listeners are called "canned" because 
the contents of each is known when the program is written; the messages can be placed in 
ROM for later use. The subroutine "sendit" in the talker program can send canned mes- 
sages of arbitrary length, as long as each message ends in the character $. 

Message contents from the listeners to the talker are not known when the program is 
written. A version of sendit, "sndat," can still be used if the message is constructed in the 
same manner as the canned messages in the ROM of the talker program. 

The program "Modethree" sends a canned address message to each of Fh listeners on 
a party-line loop using serial data mode 3. All canned messages are transmitted with bit 
ten set to 1; all received data from the addressed listener has bit ten set to 0. SM2 is set in 
all listeners and reset in the talker. 



ADDRESS 

modethree 



talker: 



MNEMONIC 

.org OOOOh 
mov scon,#0dah 

mov thl,#0ffh 
orl pcon,#80h 
mov tmod,#20h 
mov tcon,#40h 
mov dptr,#addl 
acall sendit 
acall getit 

mov dptr,#add2 
acall sendit 



COMMENT 

;set mode 3, REN, TB8 and TI , 

; clear SM2 

;set TH1 for 83333d overflow rate 

;set SMOD 

;set timer 1 to auto-reload mode 

; start Tl to generate baud clock 

; send first listener message 

"getit" is a data reception 

routine 

send second listener message 



Continued 



200 



CHAPTER NINE 



ADDRESS 

Continued 



get it : 



MNEMONIC 

acall getit 



sjmp over 
ret 



COMMENT 

; continue until all data is gathered 

; dummy routine for this example 



the subroutine " sendit " will transmit characters starting at the 
address passed in DPTR until a $ character is found 



sendit : 
here : 



out : 



clr a 

jnb scon. 1 , here 
move a, (5)a + dptr 
mov sbuf,a 
cjne a,#'S' .out 

ret 

inc dptr 

sjmp sendit 



;zero offset for MOVC 

; wait for transmitter not busy 

;get character of message 

; send character 

;if a $ then return to calling 

; program 

;point to next character 
;continue until done 



the canned address messages are assembled in ROM next 

addl: . db "01®" ;address message for listener 1 

add2 : . db "02$" .-address message for listener 2 

; ;continue for all listeners 

addlS: .db "0f$" 
. end 
the program "listener" recognizes its address and responds with 
10 data characters; the data message is built in RAM, and ends 
with a $ character; for this example, the data is gotten by reading 
port 1 ten times and storing the data; this is the program for 
listener 01 



listener : 



who 



nxt 



org OOOOh 

mov scon, #0f2h 

mov thl,#0ffh 
orl peon, #80h 
mov tmod, #20h 
mov tcon, #40h 
jnb scon.O.who 

clr scon.O 
mov a,sbuf 
cjne a, #'0 ' , no 
jnb scon.O, nxt 
clr scon.O 



set mode3, SM2, REN, TI ; clear TB8, 

RI, RB8 

set TH1 for 83333d overflow rate 

set SM0D to double baud rate 

set timer 1 to auto-reload mode 

start Tl to generate baud clock 

look for the first address 

character 

first character, clear receive flag 

get character 

compare against expected address 

first character correct, get second 

second character, clear receive 

flag 

Continued 



SERIAL DATA COMMUNICATION 



201 



ADDRESS 



ok: 



no : 



sendata: 



indat : 



sndat : 



MNEMONIC 

mov a.sbuf 
cjne a, #' 1' , no 
jnb scon.O, ok 
clr scon.O 
cjne a, #'$' , no 
sjmp sendata 
jnb scon.O, no 
clr scon.O 
mov a.sbuf 
cjne a,#'$' , no 
sjmp who 
mov r0,#50h 

mov rl,#0ah 

mov @rO,pl 
inc rO 

djnz rl , indat 
mov @r0,#'$' 

mov r0,#50h 

jnb scon. 1 , sndat 

mov a,@rO 

mov sbuf,a 

inc rO 

cjne a, #'$' , sndat 

sjmp listener 

.end 



COMMENT 

; check next character 

;wait for $ and then send data 



if not 



then reset 



wait for $ and then loop 

get character 

loop until $ found 

loop until proper address sent 

build the message in RAM starting 

at 50h 

set Rl to count data bytes from 

port 1 

get data from port 1 to RAM 

point to next RAM location 

continue until lOd bytes are stored 

finish data string with a 

$ character 

reset RO to point to start of 

message 

wait for transmitter empty 

get character from message 

load SBUF for transmission 

point to next character 

look for $ then stop transmission 

loop for next cycle 



{>— COMMENT 



The inclusion of the $ character in each message is useful both as a check for the end of a 
message and to reset a listener that somehow misses one of the three characters expected in 
an address. If a listener misses a character, due to noise for example, it will get to the "no" label 
within one or two characters. The next $ will reset the listener program back to the "who" 
label. 

Programs that interchange data must be written to eliminate any chance of a receiving unit 
getting caught in a trap waiting for a predetermined number of characters. Common schemes 
that accomplish this goal use special "end-of -message" characters, as in the case of Modethree, 
or set timers to interrupt the receiving program if the data is not received within a certain period 
of time. 

Much more elaborate protocols than those used here in this example would be used by the 
listeners when sending data to the talker. There is always the possibility that errors will occur 
due to noise or the improper operation of another listener interfering. The talker may store 
these errors. Error -checking bytes may be added to the data stream so that the talker can verify 
that the string of characters is error free. 



202 CHAPTER NINE 



Summary 



Four serial data communication modes for the 8051 are covered in this chapter: 

Mode 0: High-speed, 8-bit shift register; one baud rate of f/12 

Mode I: Standard 8-bit UART; variable baud rate using timer 1 overflows 

Mode 2: Multiprocessor 9-bit UART; two baud rates of f/32 and f/64 

Mode 3: Multiprocessor 9-bit UART; variable baud rate using timer 1 overflows 

Programs in this chapter use these modes and feature several standard communication 
techniques: 

High-speed shift register data gathering 
Interrupt-driven transmit and receive buffers 
Sending preprogrammed, or canned, messages 

Problems 

1. Explain why mode is not suitable for 8051 communications. 

2. How much clock skew, in terms of clock period, can transmitted data using mode have 
before data is shifted in error? 

3. Repeat Problem 2 for data reception. 

4. Assume you are determined to use mode as a communication mode from one 8051 
to another. Outline a system of hardware and software that would allow this. Hint: 
A "buffer" is needed. 

5. Sketch the mode 1 no parity ASCII serial characters U, 0, and w. 

6. Many communication terminals can determine the baud rate of standard (mode 1) char- 
acters by making measurements on the first few "fill" characters received. Outline a 
program strategy that would set the 8051 baud rate automatically based upon the first 
character received. 

7. Character transmission can be done by using a time delay greater than the character time 
before moving a new byte to SBUF. Explain why character reception must use an inter- 
rupt flag if all characters are to be received. 

8. ASCII characters can have even (number of ones), odd, or no parity using bit 7 as a 
parity bit. Write a program that checks the incoming data for odd parity and sets a flag 
if the parity is incorrect. 

9. Write a program that converts odd parity bytes to even parity bytes (bit 7 is the parity bit). 

10. An overrun is said to occur in data reception whenever a new byte of data is received 
before the previously received byte has been read. Discuss two methods by which over- 
runs might be detected by the 8051 program. 

11. List two reasons why stop bits are used in asynchronous communications. 

12. A framing error is said to have occurred if the stop bit is not a logic high. What mode(s) 
can detect a framing error? 

13. Why is it necessary for the main program (see "Modeone") to set the TI bit to begin the 
transmission of a string of characters using interrupt-driven routines? Name another way 
for the main program to initiate transmission. 

14. Determine if an 8051 in mode 1 can communicate with an 8051 in mode 3. 

15. Modify the "Modeone" program to use 4K byte buffers. 




8051 Operational 
Code Mnemonics 



Appendix A lists two arrangements of mnemonics for the 8051: by function, and alpha- 
betically. The mnemonic definitions differ from that of the original manufacturer (Intel 
Corporation) by the names used for addresses or data; for example, "add" is used to repre- 
sent an address in internal RAM, while Intel uses the name "direct." The author believes 
that the names used are clearer than those used by Intel. Appendix A also includes an 
alphabetical listing of the mnemonics using Intel names. There is no difference between 
the mnemonics when real numbers replace the names. For example; MOV add,#n and 
MOV direct, #data become MOV 10h,#40h when the number lOh replaces the internal 
RAM address (add/direct), and 40h replaces the number (#n/# data). 



Mnemonics, Arranged by Function 



Arithmetic 




MNEMONIC 


DESCRIPTION 


ADD A,Rr 


A+Rr-> A 


ADD A.add 


A+(add) -> A 


ADD A,(aRp 


A+(Rp)^ A 


ADD A,#n 


A + n-> A 


ADDC A,Rr 


A+Rr+C — A 


ADDC A,add 


A+(add) + C^ A 


ADDC A,(5Rp 


A+(Rp)+C^ A 


ADDC A,#n 


A+n + C ~» A 


DA A 


Abin — » Adec 


DEC A 


A-1 -> A 


DEC Rr 


Rr-1 -n-Rr 


DEC add 


(add)-l ->(add) 


DEC <«.'Rp 


(Rp)-1->(Rp) 



BYTES CYCLES FLAGS 


1 


C OV AC 


2 


C OVAC 


1 


C OVAC 


2 


C OVAC 


1 


C OVAC 


2 


C OVAC 


1 


C OVAC 


2 


COVAC 


1 


C 


1 




1 




2 




1 






Continued 




203 



204 



APPENDIX A 



Arithmetic 

MNEMONIC 



DIV AB 
INC A 
INC Rr 
INC add 
INC (frRp 
INC DPTR 
MUL AB 
SUBB A,Rr 
SUBB A,add 
SUBB A,(fiRp 
SUBB A,#n 



Logic 



MNEMONIC 

ANL A.Rr 
ANL A,add 
ANL A.ftt-Rp 
ANL A,#n 
ANL add.A 
ANL add,#n 
ORL A,Rr 
ORL A,add 
ORL A,(fi;Rp 
ORL A,#n 
ORL add,A 
ORL add,#n 
XRL A,Rr 
XRL A,add 
XRL A,(?/. ! Rp 
XRL A,#n 
XRL add,A 
XRL add,#n 
CLR A 
CPL A 
NOP 
RL A 
RLC A 
RR A 
RRC A 
SWAP A 

Data Moves 

MNEMONIC 

MOV A.Rr 
MOV A,add 
MOV A,(a>Rp 



DESCRIPTION 

A/B-* AB 
A+l -» A 
Rr+1 -» Rr 
(add)+1 ~^(add) 
(Rp)+1 -»(Rp) 
DPTR+1 -* DPTR 
AxB— AB 
A-Rr-C-» A 
A-(add)-C -> A 
A-(Rp)-C -» A 
A-n-C -* A 



DESCRIPTION 

A AND Rr-> A 

A AND (add) -» A 

A AND (Rp) -» A 

A AND n -» A 

(add) AND A -* (add) 

(add) AND n -» (add) 

A OR Rr -* A 

A OR (add) -» A 

A OR (Rp) -> A 

A OR n -» A 

(add) OR A — (add) 

(add) OR n -» (add) 

AXOR Rr— A 

A XOR (add) -> A 

A XOR (Rp) -> A 

A XOR n -» A 

(add) XOR A -> (add) 

(add) XOR n -» (add) 

00-^ A 

A-> A 

PC+1 -» PC 

A0*-A7«-A6. .«-A1 ^-AO 

C«_A7<-A6..^-A0<-C 

A0->A ->A6..-+A1-»A0 

C^A7->A6. .-*A0— C 

Alsn <-» Amsn 



DESCRIPTION 

Rr-* A 
(add) -» A 
(Rp) — A 



BYTES CYCLES 



FLAGS 

Continued 

ov 



ov 

COVAC 
COVAC 
C OVAC 
C OVAC 



BYTES CYCLES FLAGS 

1 
2 
1 
2 

2 

3 

1 

2 

1 

2 

2 

3 

1 

2 

1 

2 

2 

3 

1 

1 

1 

1 

1 1 C 

1 

1 1 c 

1 



BYTES CYCLES FLAGS 

1 1 

2 1 
1 1 

Continued 



8051 OPERATIONAL CODE MNEMONICS 



205 



MNEMONIC 

MOV A,#n 
MOV Rr,A 
MOV Rr.add 
MOV Rr,#n 
MOV add,A 
MOV add.Rr 
MOVadd1,add2 
MOV add,@Rp 
MOV add,#n 
MOV @Rp,A 
MOV @Rp,add 
MOV @Rp,#n 
MOV DPTR,#nn 
MOVC A,@A+DPTR 
MOVC A,@A+PC 
MOVX A,@DPTR 
MOVX A,(o)Rp 
MOVX @Rp,A 
MOVX @DPTR,A 
POP add 
PUSH add 
XCH A,Rr 
XCH A,add 
XCH A,@Rp 
XCHD A,(SRp 

Calls and Jumps 

MNEMONIC 

ACALL sadd 
ONE A,add,radd 
CJNE A,#n,radd 
CJNE Rr,#n,radd 
CJNE @Rp,#n,radd 
DJNZ Rr,radd 
DJNZ add.radd 
LCALL ladd 
AJMP sadd 
UMP ladd 
SJMP radd 
JMP@A + DPTR 
JC radd 
JNC radd 
JB b.radd 
JNB b,radd 
JBC b,radd 
JZ radd 
JNZ radd 
RET 
RETI 



DESCRIPTION 

n-> A 
A->Rr 
(add) -» Rr 
n~> Rr 
A — (add) 
Rr -» (add) 
(add2)-»(add1) 
(Rp)-(add) 
n — (add) 
A -» (Rp) 
(add) — (Rp) 
n - (Rp) 
nn — DPTR 
(A+DPTR) — A 
(A+PC)-> A 
(DPTR) A -> A 
(Rp)A -► A 
A -► (Rp) A 
A -> (DPTR)A 
(SP)-(add) 
(add)-(SP) 
A <-» Rr 
A ++ (add) 
A <-»■ (Rp) 
Alsn <h. (Rp)lsn 



DESCRIPTION 

PC + 2-»(SP); sadd —PC 

(Ao(add)): PC + 3 + radd— PC 

[Aon|: PC + 3 + radd — PC 

[Rron]: PC + 3 + radd -» PC 

[(Rp)on]: PC+3 + radd — PC 

[Rr-1<>001: PC + 2 + radd — PC 

Kadd)-1<>00]: PC + 3 + radd — PC 

PC + 3 — (SP); ladd — PC 

sadd — PC 

ladd -* PC 

PC + 2 + radd — PC 

DPTR+A — PC 

|C = 1]: PC + 2 + radd — PC 

IC = 0]: PC + 2 + radd — PC 

lb=1]: PC + 3 + radd — PC 

[b=0]; PC + 3 + radd — PC 

[b=1|: PC + 3 + radd — PC; — b 

[A=00]: PC + 2 + radd — PC 

(A>001: PC + 2 + radd — PC 

(SP) — PC 

(SP) — PC; El 



BYTES CYCLES FLAGS 

2 1 

1 1 

2 2 
2 1 
2 1 

2 2 

3 2 

2 2 

3 2 

1 1 

2 2 

2 1 

3 2 
1 2 
1 2 
1 2 
1 2 
1 2 

1 2 

2 2 
2 2 

1 1 

2 1 
1 1 
1 1 



BYTES CYCLES FLAGS 

2 2 

3 2 C 
3 2 C 
3 2 C 
3 2 C 

2 2 

3 2 
3 2 

2 2 

3 2 
2 2 

1 2 

2 2 

2 2 

3 2 
3 2 
3 2 
2 2 
2 2 
1 2 
1 2 



206 



APPENDfX A 



Boolean 

MNEMONIC 

ANL C£ 
ANL C.b 
CLRC 
CLRb 
CPL C 
CPL b 
ORL C.b 
ORLC.b 
MOV C,b 
MOV b,C 
SETB C 
SETB b 



DESCRIPTION 



C AND^~» 
C AND b -» 
0->C 
0_-+b 

b-*b 
C OR b -> C 
C OR b -» C 
b — C 
C-b 
1 ->C 
1 -»b 



BYTES CYCLES FLAGS 



2 


2 


C 


2 


2 


C 


1 


1 





2 


1 




1 


1 


c 


2 


1 




2 


2 


c 


2 


2 


c 


2 


1 


c 


2 


2 




1 


1 


1 


2 


1 





Mnemonics, Arranged Alphabetically 



MNEMONIC 

AC ALL sadd 

ADD A,add 

ADD A,@Rp 

ADD A,#n 

ADD A,Rr 

ADDC A.add 

ADDC A,@Rp 

ADDC A,#n 

ADDC A,Rr 

AJMP sadd 

ANL A.add 

ANL A,@Rp 

ANL A,#n 

ANL A,Rr 

ANL add,A 

ANL add,#n 

ANL C,_b 

ANL C,b 

ONE A,add,radd 

ONE A,#n,radd 

CJNE @Rp,#n,radd 

CJNE Rr,#n,radd 

CLR A 

CLR b 

CLRC 

CPL A 

CPL b 

CPL C 

DA A 

DEC A 

DEC add 

DEC @Rp 

DEC Rr 



DESCRIPTION 

PC + 2^(SP);sadd-^PC 

A+(add) -*■ A 

A + (Rp)-> A 

A + n -*■ A 

A + Rr-> A 

A+(add) + C -*• A 

A + {Rp) + C-^ A 

A + n + C -> A 

A + Rr+C -> A 

sadd -» PC 

A AND (add) -> A 

A AND (Rp) -» A 

A AND n -> A 

A AND Rr -> A 

(add) AND A -> (add) 

(add) AND n -> (add) 

C AND b_-» C 

C AND b -» C 

(Ao(add)I: PC+3 + radd — PC 

[A<>n|: PC + 3 + radd-> PC 

[(Rp)on]: PC + 3 + radd -* PC 

fRrOnl: PC + 3 + radd-» PC 



BYTES CYCLES FLAGS 





0^ 
A 

b 
c 

Abin — » 
A-1~» 
(add)-1 
(Rp)-1 ■ 
Rr-1 -• 



A 

b 

C 
• A 

b 
■C 



Adec 

A 

-» (add) 

-►(Rp) 
Rr 



2 


2 




2 




C OVAC 


1 




COVAC 


2 




COVAC 


1 




C OVAC 


2 




C OVAC 


1 




COVAC 


2 




COVAC 


1 




C OVAC 


2 


2 




2 






1 






2 






1 






2 






3 


2 




2 


2 


C 


2 


2 


C 


3 


2 


C 


3 


2 


C 


3 


2 


C 


3 


2 


C 


1 






2 







Continued 



8051 OPERATIONAL CODE MNEMONICS 



207 



MNEMONIC 

DIV A8 

DJNZ add.radd 

DJNZ Rr.radd 

INC A 

INC add 

INC DPTR 

INC @Rp 

INC Rr 

JB b.radd 

JBC b.radd 

JC radd 

JMP@A + DPTR 

JNB b,radd 

JNC radd 

JNZ radd 

JZ radd 

LCALL ladd 

UMP ladd 

MOV A,add 

MOV A,@Rp 

MOV A,#n 

MOV A,Rr 

MOV add.A 

M0Vaddl,add2 

MOV add,(&Rp 

MOV add,#n 

MOV add.Rr 

MOV b,C 

MOV C,b 

MOV @Rp,A 

MOV @Rp,add 

MOV (a)Rp,#n 

MOV DPTR,#nn 

MOV Rr.A 

MOV Rr,add 

MOV Rr,#n 

MOVC A,@A+DPTR 

MOVC A,@A+PC 

MOVX A,@DPTR 

MOVX A,@Rp 

MOVX @DPTR,A 

MOVX <5>Rp,A 

NOP 

MULAB 

ORL A,add 

ORL A,@Rp 

ORL A,#n 

ORL A,Rr 

ORL add,A 

ORL add,#n 

ORL C.b 

ORLC.b 



DESCRIPTION 

A/B -> AB 

Kadd)-1<>00]: PC+3+radd-» PC 

[Rr-1<>00]: PC + 2 + radd-* PC 

A+1 -* A 

(add)+1 ->(add) 

DPTR+1 -» DPTR 

(Rp)+1-»(Rp) 

Rr+1 -* Rr 

[b=1]: PC + 3 + radd-> PC 

[b=1]: PC + 3 + radd — PC; O^b 

[C = l]: PC + 2 + radd-> PC 

DPTR + A->PC 

[b=0]: PC + 3 + radd — PC 

[C=0J: PC + 2 + radd-> PC 

[A>00]: PC + 2 + radd-»PC 

[A=00]: PC + 2 + radd— PC* 

PC+3 — (SP); ladd -^ PC 

ladd -> PC 

(add) — A 

(Rp) -> A 

n-» A 

Rr-* A 

A ->• (add) 

(add2)->(add1) 

(Rp)-*(add) 

n -> (add) 

Rr -+ (add) 

C^b 

b— C 

A -* (Rp) 

(add)^(Rp) 

n -> (Rp) 

nn -» DPTR 

A-» Rr 

(add) -+ Rr 

n-» Rr 

(A+DPTR)-* A 

(A+PC)-» A 

(DPTR)a -» A 

(Rp)A -» A 

A -♦ (DPTR)a 

A - (Rp)A 

PC+1 -> PC 

AxB — AB 

A OR (add) -> A 

A OR (Rp) -+ A 

AORn->A 

A OR Rr -> A 

(add) OR A -> (add) 

(add) OR n -* (add) 

C OR b-> C 

CORb-^C 



BYTES CYCLES FLAGS 



oov 



oov 



c 
c 

Continued 



208 



APPENDIX A 



MNEMONIC. 

POP add 
PUSH add 
RET 
RET! 
RL A 
RLC A 
RR A 
RRC A 
SETB b 
SETB C 
SJMP radd 
SUBB A.add 
SUBB A,@Rp 
SUBB A,#n 
SUBB A.Rr 
SWAP A 
XCH A,add 
XCH A,(|)Rp 
XCH A,Rr 
XCHD A,@Rp 
XRL A,3dd 
XRL A,@Rp 
XRL A,#n 
XRL A,Rr 
XRL add.A 
XRL add.#n 

MNEMONIC ACRONYMS 



DESCRIPTION 


(SP)^(add) 




(add)-(SP) 




(SP) -* PC 




(SP)-*PC; El 




AO<-A7*-A6. 


<^-AT«-A0 


C^-A7^-A6. .+■ 


-AO^C 


AO->A7->A6. 


^A1— AO 


C^A7^A6. .- 


*AO->C 


1 ->b 




1 -» C 




PC + 2 + radd- 


► PC 


A-(add)-C — 


A 


A-(Rp)-C — 


A 


A-n-C -» A 




A-Rr-C — A 




A/sn *+ Amsn 




A « (add) 




A ** (Rp) 




A«Rr 




Alsn <-> (Rp)lsn 




A XOR (add) ^ 


-A 


A XOR (Rp) -» 


A 


A XOR n -» A 




A XOR Rr -» A 




(add) XOR A -> 


(add) 


(add) XOR n -» 


(add) 



BYTES 


CYCLES 


FLAGS 

Continued 


2 


2 




2 


2 




1 


2 




1 


2 




1 






1 




C 


1 






1 




C 


2 






1 




1 


2 


2 




2 




COVAC 


1 




COVAC 


2 




C OV AC 


1 




C OVAC 


1 






2 






1 






1 






1 






2 






1 






2 






1 






2 






3 


2 





add 

iadd 

radd 

sadd 

b 

C 

Isn 

msn 

n 

Rr 

Rp 



A 
{) 



Address of the internal RAM from OOh to FFh. 

Long address of 16 bits from OOOOh to FFFFh. 

Relative address, a signed number from -128d to +127d. 

Short address of 1 1 bits; complete address = PC 1 1 - PC 1 5 and sadd. 

Addressable bit in internal RAM or a SFR. 

The carry flag. 

Least significant nibble. 

Most significant nibble. 

Any immediate 8 bit number from OOh to FFh. 

Any of the eight registers, RO to R7 in the selected bank. 

Either of the pointing registers RO or R1 in the selected bank. 

IF the condition inside the brackets is true, THEN the action listed will occur; ELSE go to the next 

instruction. 
External memory location. 
Contents of the location inside the parentheses. 



Note that flags affected by each instruction are shown where appropriate; any operations that affect the PSW 
address may also affect the flags. 



8051 OPERATIONAL CODE MNEMONICS 



209 



Intel Corporation Mnemonics, 
Arranged Alphabetically 



MNEMONIC 


DESCRIPTION 




BYTES 


CYCLES 


FLAGS 


ACALL addrl 1 


PC + 2->(SP); addrl 1 -* PC 


2 


2 




ADD A,direct 


A-t-(direct)-*- A 




2 




C OVAC 


ADD A,@Ri 


A+(Ri)^ A 




1 




C OVAC 


ADD A,#data 


A + #data -* A 




2 




C OVAC 


ADD A,Rn 


A + Rn-* A 




1 




COVAC 


ADDC A.direct 


A+(direct) + C-* A 




2 




COVAC 


ADDC A,(&Ri 


A+(Ri)+C-> A 




1 




COVAC 


ADDC A,#data 


A+#data + C^> A 




2 




C OVAC 


ADDC A,Rn 


A+Rn + C~> A 




1 




C OVAC 


AJMP addrl 1 


addrl 1 -* PC 




2 


2 




ANL A.direct 


A AND (direct) -> A 




2 






ANL A,@Ri 


A AND (Ri) -* A 




1 






ANL A,#data 


A AND #data -» A 




2 






ANL A.Rn 


A ANDRn-> A 




1 






ANL direct.A 


(direct) AND A -> (direct) 


2 






ANL direct,#data 


(direct) AND #data - 


» (direct) 


3 


2 




ANL C.bit 


C AND bit -h> C 




2 


2 


C 


ANL C.bit 


C AND bit -> C 




2 


2 


C 


CJNE A.direct.rel 


(Ao(direct)]: PC + 3 + rel -> PC 


3 


2 


C 


CJNE A,#data,rel 


[AOnJ: PC + 3 + rel- 


-PC 


3 


2 


c 


CJNE <£>Ri,#data,rel 


[(Ri)on]: PC + 3 + re 


-> PC 


3 


2 


c 


CJNE Rn,#data,rel 


(Rnon): PC + 3 + rel 


— PC 


3 


2 


c 


CLR A 


0-* A 




1 






CLR bit 


0-> bit 




2 






CLRC 


0-* C 




1 







CPL A 


A-> A 




1 






CPL bit 


bit -> bit 




2 






CPL C 


C -* C 




1 




c 


DA A 


Abin —» Adec 




1 




c 


DEC A 


A~1 ~» A 




1 






DEC direct 


(direct)- 1 -> (direct) 




2 






DEC (wR\ 


(Ri)-l-MRi) 




1 






DEC Rn 


Rn-1 -> Rn 




1 






DtV AB 


A/B -» AB 




1 


4 


oov 


DJNZ direct.rel 


[(direct)- K>00]: PC + 3 + rel~> PC 


3 


2 




DJNZ Rn.rel 


[Rn-1<>00]: PC + 2 + rel -> PC 


2 


2 




INC A 


A+1 -> A 




1 


1 




INC direct 


(direct)-*- 1 — > (direct) 




2 


1 




INC DPTR 


DPTR+1 -> DPTR 




1 


2 




INC cm 


(Ri)+1->(Ri) 




1 


1 




INC Rn 


Rn + 1 -» Rn 




1 


1 




JB bit, rel 


[b=1]: PC + 3 + rel-> 


PC 


3 


2 




JBC bit.rel 


[b=1]: PC + 3 + rel-» 


PC; 0— ♦ bit 


3 


2 




JC rel 


|C=1]: PC + 2 + rel~> 


PC 


2 


2 




JMP(??A + DPTR 


DPTR+A-* PC 




1 


2 




JNB bit.rel 


[b=0]: PC + 3 + rel-» 


PC 


3 


2 




JNC rel 


[C=0]: PC + 2 + rel^- 


PC 


2 


2 




JNZ rel 


[A>00]: PC + 2 + rel- 


>PC 


2 


2 




JZrel 


[A=00]: PC + 2 + rel~» PC 


2 


2 














Continued 



210 



APPENDIX A 



MNEMONIC 

LCALL addr16 

UMPaddr16 

MOV A.direct 

MOV A.fojRi 

MOV A,#data 

MOV A.Rn 

MOV direct.A 

MOV direct.direct 

MOV direct.ffr'Ri 

MOV direct,#data 

MOV direct.Rn 

MOV bit,C 

MOV C,bit 

MOV @Ri,A 

MOV @Ri,direct 

MOV @Ri,#data 

MOVDPTR,#data16 

MOV Rn,A 

MOV Rn.direct 

MOV Rn,#data 

MOVC A,@A+DPTR 

MOVC A,@A + PC 

MOVX A,@DPTR 

MOVX A,@Ri 

MOVX @DPTR,A 

MOVX @Ri,A 

NOP 

MUL AB 

ORL A.direct 

ORL A,@Ri 

ORL A,#data 

ORL A,Rn 

ORL direct.A 

ORL direct,#data 

ORL C.bit 

ORL C, bit 

POP direct 

PUSH direct 

RET 

RETI 

RL A 

RLC A 

RR A 

RRC A 

SETB bit 

SETS C 

5JMP ret 

SUBB A,direct 

SUBB A,@Ri 

SUBB A,#data 

SUBB A.Rn 



DESCRIPTION 

PC + 3~*(SP); addr16-^PC 

addr16^ PC 

(direct) -» A 

(Ri) -» A 

#data -> A 

Rn-> A 

A -* (direct) 

(direct) — > (direct) 

(Ri) -+ (direct) 

#data -» (direct) 

Rn -* (direct) 

C -* bit 

bit->C 

A -> (Ri) 

(direct) -* (Ri) 

#data -> (Ri) 

#data16-> DPTR 

A-» Rn 

(direct) -> Rn 

#data -» Rn 

(A + DPTR)-* A 

(A + PC)-> A 

(DPTR)a -> A 

(Ri)A -* A 

A -> (DPTR) ^ 

A -> (Ri)A 

PC+1 -» PC 

AxB-» AB 

A OR (direct) -» A 

A OR (Ri) -» A 

A OR #data -* A 

A OR Rn -*■ A 

(direct) OR A -» (direct) 

(direct) OR #data -> (direct) 

CORbrt~>C 

C OR bit -* C 

(SP) -> (direct) 

(direct) -*■ (SP) 

(SP) -» PC 

(SP)-* PC; El 

A0<~A7<-A6. .«-A1 <-AO 

C*~A7-^A6..*-A0«-C 

A0-»A7-»A6. ,-+A1-*A0 

C-»A7-*A6. .-*A0-*C 

1 -> bit 

1 -» C 

PC + 2 + rel->PC 

A-(direct)-C^ A 

A~(Ri)~C -> A 

A-#data-C-» A 

A-Rn-C-* A 



BYTES 


CYCLES 


FLAGS 


3 


2 




3 


2 




2 






1 






2 






1 






2 






3 


2 




2 


2 




3 


2 




2 


2 




2 


2 




2 


1 


C 


1 


1 




2 


2 




2 


1 




3 


2 




1 


1 




2 


2 




2 


1 




1 


2 




1 


2 




1 


2 




1 


2 




1 


2 




1 


2 




1 


1 




1 


4 


oov 


2 






1 






2 






1 






2 






3 


2 




2 


2 


c 


2 


2 


c 


2 


2 




2 


2 




1 


2 




1 


2 




1 






1 




c 


1 






1 




c 


2 






1 




1 


2 


2 




2 




COVAC 


1 




COVAC 


2 




COVAC 


1 




COVAC 
Continued 



8051 OPERATIONAL CODE MNEMONICS 



211 



MNEMONIC 

SWAP A 
XCH A,direct 
XCH A,@Ri 
XCH A,Rn 
XCHD A,@Ri 
XRL A,direct 
XRL A,@Ri 
XRL A,#data 
XRL A,Rn 
XRL direct.A 
XRL direct,#data 



DESCRIPTION 

A!sn <-> Amsn 

A *-* (direct) 

A +* (Ri) 

A «• Rn 

Alsn ++ (Ri)lsn 

A XOR (direct) -► A 

A XOR (Ri) -> A 

A XOR #data -► A 

A XOR Rn -+ A 

(direct) XOR A -> (direct) 

(direct) XOR #data -> (direct) 



BYTES CYCLES FLAGS 

1 
2 
1 
1 
1 
2 
1 
2 
1 
2 
3 



ACRONYMS 



addrl 1 

addr16 

bit 

C 

#data 

#data16 

direct 

Isn 

msn 

rel 

Rn 
(ffiRi 



() 



Page address of 1 1 bits, which is in the same 2K page as the address of the following instruction. 

Address for any location in the 64K memory space. 

The address of a bit in the internal RAM bit address area or a bit in an 5FR. 

The carry flag. 

An 8-bit binary number from 00 to FFh. 

A 16-bit binary number from 0000 to FFFFh. 

An internal RAM address or an SFR byte address. 

Least significant nibble. 

Most significant nibble. 

Number that is added to the address of the next instruction to form an address + 1 27d or - 1 28d 

from the address of the next instruction. 
Any of registers R0 to R7 of the current register bank. 
Indirect address using the contents of R0 or RI. 
IF the condition inside the brackets is true, THEN the action listed will occur; ELSE go to the next 

instruction. 
EXTERNAL memory location. 
Contents of the location inside the parentheses. 



Note that flags affected by each instruction are shown where appropriate; any operations which affect the PSW 
address may also affect the flags. 




How to Use the A51 Assembler 



Introduction 



In the early days of digital computing, (the 1940's), computers were programed in binary, 
resulting in programs that appeared as 



1001001010101111 
1111010111010110 
0001011011110010 
1100010101000101 



and are generally unintelligible to anyone. Early in this process, programmers became 
tired of typing all those l's and 0's, so a shorthand notation for binary (hexadecimal) was 
adopted to shorten the typing effort: 

92AF 
F5D6 
16F2 
C545 



using 0-9 for binary 0000 to 1001, and A-F for binary 1010 to II II. The result is still 
unintelligible, but more compact. 

Each line of code is an instruction to the computer, and the programmers composed 
descriptions for the instructions that could be written as 

Load the accumulator with a number 
Move the accumulator to register 1 
Move memory location 3 to location 2 



212 



HOW TO USE THE A51 ASSEMBLER 213 

The programmers translated these descriptions to the equivalent hex codes using pencil 
and paper. Very soon these long descriptions were shortened to 

LODE A,NUM 
MOVE 1,A 
MOVE 2,3 



Mnemonics were born to speed up the programming process by retaining the essence of 
the instruction. Finally, programs became so long, and computing so inexpensive, pro- 
grams that translated the mnemonics into their equivalent hex codes were written to facili- 
tate the programming process. 

The translation programs go by many names: 

Interpreter: Translate each line of the program independently to an abbreviated 
ASCII (non-hex) equivalent 

Assembler: Translate the entire program, as a whole, to hex 

Compiler: Convert an Interpreter translation to hex 

Then there are the "Cross" varieties, which assemble or compile code on computer A 
for use on computer B. This type of assembler is included with this book: A Cross — 
Assembler for the 805 1 , which runs on PC type computers. The assembler was written by 
David Akey of Pseudocode, Newport News, Virginia. The assembler is a file on the pro- 
gramming disk named A5I.EXE. 



Using the Assembler 



The assembler included with this book is a student model that has been adapted from 
Pseudocodes' professional version. The student assembler has most of the capabilities of 
the professional version with these limitations: 

No macro features 
No options 

The intent is to supply an assembler that is easy to use, enabling the student to get to the 
business of writing programs with a minimum of delay. 



The Big Picture 

An assembler is a translator machine. Computer programs, written using a defined set of 
rules (the syntax) are put into the assembler, and hex code pops out (if the syntax has been 
followed). 

First, prepare a disk with the assembler program, A51.EXE. Next, place any input 
program you wish to have assembled on this disk. 

The input program is in an ASCII text disk file that has been prepared by an editor 
program and that must obey these rules: 

1. The file name has the extension .ASM (example: myfile.asm). 

2. The file must be "pure" ASCII. 



214 



APPENDIX B 



Many editor programs save text files using strange and potentially troublesome control 
characters. Save your text files in ASCII form. An editor ED. EXE is included with the 
book disk and will save any programs created in pure ASCII. 
The assembler produces two output files: 

1. A file with the same name as the input ASCII text file, which has the extension 
.LST, is the assembled file complete with line numbers, memory addresses, hex 
codes, mnemonics, and comments. Any ERRORS found during assembly will 
be noted in the .LST file, at the point in the program where they occur. 

2. A file with the same name as the input ASCII text file, which has the extension 
.OBJ, is the hex format file that can be loaded into the simulator and run. 

Example: 

A small program that blinks LEDs on an 8051 system is edited and saved as an ASCII file 
named try. asm. 





.org 4000h 




loop: 


mov 90h,#0ffh 


;LEDs off 




acall time 


; delay 




mov 90h.#7fh 


;turn on LED one 




acall time 






mov 90h.#0bfh 


;turn on LED two 




acall time 






mov 90h,#3fh 


;both LEDs on 




acall time 






sjmp loop 




time: 


mov r0.#03h 




inl: 


mov rl,#00h 




in2: 


mov r2,#00h 




wait : 


djnz r2,wait 
djnz rl,in2 
djnz rO , inl 
ret 
. end 





The .LST file, which is produced by the assembler, has these features: 



Line 


Address 


Hex 


Label 


Mnemonics 


Comments 


000001 


4000 






.org 4000h 




000002 


4000 


7590FF 


loop: 


mov90h,#0ffh 


;LEDs off 


000003 


4003 


1116 




acall time 


;delay 


000004 


4005 


75907F 




mov 90h,#7fh 


;turn on LED one Line 


000005 


4008 


1116 




acall time 




000006 


400A 


7590BF 




mov 90h,#0bfh 


;turn on LED two 


000007 


400D 


1116 




acall time 




000008 


400F 


75903F 




mov 90h,#3fli 


;both LEDs on 


000009 


4012 


If 16 




acall time 




000010 


4014 


80EA 




sjmp loop 




000011 


4016 


7803 


time: 


mov r0,#03h 





Continued 



HOW TO USE THE A51 ASSEMBLER 



215 



Line 


Address 


Hex 


Label 


Mnemonics 


Comments 


000012 


4018 


7900 


inl: 


mov rl,#00h 




000013 


401A 


7A00 


in2: 


mov r2,#00h 




000014 


401C 


DAFE 


wait: 


djnz r2,wait 




000015 


401 E 


D9FA 




djnz rl,in2 




000016 


4020 


D8F6 




djnz r0,inl 




000017 


4022 


22 




ret 




000018 


4023 






.end 





The .OBJ file contains the hex code from the .LST file, together with special leading 
(:xxxxxxxx) and trailing characters (the last byte in each line which is a checksum) that 
can be loaded into the simulator or an EPROM burner: 



104000007590FF111675907F11167590BF1116757A 

10401000903F111680EA780379007AOODAFED9FA27 

03402000D8F622AD 

00000001FF 



How to Assemble 

After you have written your program using the mnemonics from Appendix A and saved 
the program in an ASCII text file, type: 

A51 -s yourfile {Note: No .ASM) 



Where yourfile is the name of your ASCII program file. The -s prevents the assembler 
from including the symbol table at the end of your program. For the example program, we 
type: a5I -s try. The result is TRY.LST and TRY.OBJ 

The assembler will assemble your program and inform you of any errors that are 
found. You can type the .LST file to the computer screen or print the listing to a printer. 
All errors in syntax will be shown by the assembler in the .LST file. Keep in mind that a 
program that has been successfully assembled is not guaranteed to work; it is only gram- 
matically correct. (One can write sentences in English that are grammatically correct but 
make no sense, such as "see any government form"). Re-edit your program until assem- 
bly is successful. 



Assembler Directives 

An assembler is a program and has instructions just as any program. These are called 
"directives" or "pseudo operations" because they inform the assembler what to do with 
the mnemonics that it is to assemble. The pseudo ops are distinctly different from the 
mnemonics of the computer code being assembled so that they stand out in the program 
listing. For the Pseudocode assembler, they are 

.org xxxx ORiGinate the following code starting at address xxxx . 

Example Program Address Hex 

.org 0400h becomes: 0400 79 

MOV r2,#00h 0401 00 



216 



APPENDIX B 



The .org pseudo op lets you put code and data anywhere in program memory you wish. 
Normally the program starts at OOOOh using a .org OOOOh. 

equ label, xxxx EQUate the label name to the number xxxx. 

Example Program Address Hex 

.org OOOOh becomes: 0000 74 

,equfred,12h 0001 12 

mov a,#fred 

.equ turns numbers into names; it makes the program much more readable because the 
name chosen for the label can have some meaning in the program, whereas the number 
will not. 

db xx Define a Byte: place the 8-bit number xx next in memory. 

Example Program Address Hex 

.org 0100h becomes: 0100 34 

.db 34h 0101 56 

.db 56h 

db "abc" 



Example Program 


Address 


Hex 


.org 0200h becomes: 


0200 


31 


db "123 " 


0201 


32 




0202 


33 




0203 


20 



.db xx takes the number xx (from to 255d) and converts it to hex in the next memory 
location, .db "abc" will convert any character that can be typed into the space between 
the quote marks into the equivalent ASCII (no parity) hex code for that character, and 
place them sequentially in memory, .db permits the programmer to place any hex byte 
anywhere in memory. 

dw xxxx Define a Word. Place the 16-bit number xxxx in memory. 

Example Program Address Hex 

.org Oabcdh becomes: ABCD 12 

dw 1234h ABCE 34 

.dw is a 16 bit version of .db. 



end The End. Tells the assembler to stop assembling. 

Other directives exist that are rarely used by student programmers. Refer to the assem- 
bler documentation contained in the disk file under the name LEVELI.DOC. The file 
INTELl.ASM contains some .opdef directives which let .anything become anything 
(no .) for those programs written with directives which do not use the period. 



HOW TO USE THE A51 ASSEMBLER 



217 



Numbers 



Labels 



Numbers follow one simple rule: They must start with a number from to 9. For example, 

1234 
Oabcdh 
Offh 
5aceh 

Numbers in the program can be written in decimal or hex form as 

1234 = 1234 decimal 
h'Odd = DD hexadecimal 
Oddh = DD hexadecimal 

The first form of the hexadecimal number (h'Odd) is a Unix standard, while the second 
form (Oddh) is a common assembly language standard. 



Labels are names invented by the programmer that stand for a number in the program, 
such as a constant in the .equ directive above, or a number which represents a memory 
location in the program. Labels used for memory locations follow two simple rules: 

1. All labels must START with an alphabetic character and END with : (colon). 

2. No more than 8 characters. 

The following are examples: 

fred: 
ml: 
p1234: 
xyz: 

The restriction that all numbers begin with a number is now apparent; hexadecimal num- 
bers beginning with A to F would be mistaken by the assembler as a label and chaos would 
result. 



COMMENTS 



Anything that follows a semicolon (;) in a line of a program is ignored by the assembler. Com- 
ments must start with a ; . For example, 

; this is a comment and will be ignored by the assembler 

If you are assembling a program and get a LOT of syntax errors, you probably forgot to include 
a semicolon in your comments. 

Typing a Line 

To make the program readable, it is recommended that you type all opcodes about 10 
spaces or so to the right of the left margin of your text. Start all labels at the left margin of 
text, and place any comments to the right of the opcode entry. The finished line should 
appear as follows: 

label: opcode ; comment 



218 



APPENDIX B 



Symbols 



Inspection of the programs included with the text will provide many clues as to what 
syntax is acceptable to the assembler. Experiment with the assembler by writing short 
programs to get a clear understanding of what each output file contains. 



David Akey has very thoughtfully included a complete symbol table for the assembler that 
lets the programmer use symbolic names for the 805 1 Special Function Registers and indi- 
vidual register bits. These are called "reserved" symbols; so do not use any of these sym- 
bols for a label, or you will get an error message in the .LST file. Forgetting to type -s 
when you invoke A51.EXE will get you this table and all of your labels — at the end of 
your .LST file. 



SYMBOL 


ADDR. 


SYMBOL 


ADDR. 


SYMBOL 


ADDR. 


AC 




=O0D6 


P0.7 


= 0087 


SM2 


= 009D 


ACC 




= 00E0 


PI 


= 0090 


SP 


= 0081 


ACC. 





= 0OE0 


P1.0 


= 0090 


T2C0N 


= 00C8 


ACC. 


1 


= 0OEl 


Pl.l 


=0091 


T2C0N.0 


=00C8 


ACC. 


2 


= 00E2 


PI. 2 


= 0092 


T2C0N.1 


= 0OC9 


ACC. 


3 


= 00E3 


PI. 3 


= 0093 


T2C0N.2 


=00CA 


ACC. 


4 


=00E4 


PI. 4 


= 0094 


T2C0N.3 


=00CB 


ACC. 


5 


=00E5 


PI. 5 


= 0095 


T2C0N.4 


=00CC 


ACC. 


6 


= 00E6 


PI. 6 


= 0096 


T2C0N.5 


=00CD 


ACC. 


7 


=00E7 


PI. 7 


=0097 


T2C0N.6 


= 00CE 


B 




= 00F0 


P2 


=0OA0 


T2C0N.7 


=00CF 


BO 




=00F0 


P2.0 


=00A0 


TB8 


=009B 


B.l 




= 00F1 


P2.1 


= 00A1 


TCLK 


=00CC 


B.2 




=00F2 


P2.2 


=00A2 


TCON 


= 0088 


B.3 




=00F3 


P2.3 


=00A3 


TCON . 


= 0088 


B.4 




= 00F4 


P2.4 


=00A4 


TCON . 1 


= 0089 


B.5 




=00F5 


P2.5 


=00A5 


TCON. 2 


= 008A 


B.6 




=00F6 


P2.6 


=00A6 


TCON. 3 


= 008B 


B.7 




= 00F7 


P2.7 


=00A7 


TCON. 4 


= 008C 


CPRL2 


=00C8 


P3 


= 0OB0 


TCON. 5 


= 008D 


CT2 




=00C9 


P3.0 


=00B0 


TCON . 6 


=008E 


CY 




=00D7 


P3.1 


=00B1 


TCON . 7 


=008F 


DPH 




=0083 


P3.2 


= 0OB2 


TFO 


= 008D 


DPL 




-0082 


P3.3 


= 0OB3 


TF1 


=008F 


EA 




=00AF 


P3.4 


= 00B4 


TF2 


=00CF 


ES 




= 00AC 


P3.5 


=00B5 


THO 


= 008C 


ETO 




=00A9 


P3.6 


= 00B6 


TH1 


= 008D 


ET1 




=00AB 


P3.7 


=00B7 


TH2 


= 0OCD 


ET2 




= 00AD 


PCON 


=0087 


TI 


=0099 


EXO 




= 00A8 


PS 


=0OBC 


TLO 


= 008A 


EX1 




= 00AA 


PSW 


=00D0 


TL1 


= 008B 


EXEN2 


= 00CB 


PSW.O 


= 00D0 


TL2 


= 00CC 


EXF2 




= 00CE 


PSW. 1 


=00D1 


TMOD 


= 0089 


F0 




= 00D5 


PSW. 2 


= 00D2 


TRO 


=008C 

Continued 



HOW TO USE THE A51 ASSEMBLER 219 



SYMBOL 


ADDR. 


SYMBOL 


ADDR. 


SYMBOL 


ADDR. 


IE 


=00A8 


PSW.3 


=00D3 


TR1 


=008E 


IE.O 


=OOA8 


PSW.4 


=0004 


TR2 


= 00CA 


IE.l 


= 00A9 


PSW.5 


= 00D5 


TXD 


=00B1 


IE. 2 


=OOAA 


PSW.6 


=00D6 






IE. 3 


=OOAB 


PSW.7 


=00D7 






IE. 4 


=OOAC 


PTO 


=00B9 






IE. 5 


=OOAD 


PT1 


=00BB 






IE. 7 


=OOAF 


PT2 


=OOBD 






IEO 


-0089 


PXO 


=00B8 






IE1 


=008B 


PX1 


=00BA 






INTO 


=00B2 


RB8 


=009A 






INT1 


=00B3 


RCAP2H 


=0OCB 






IP 


=00B8 


RCAP2L 


= 00CA 






IP.O 


=0OB8 


RCLK 


=00CD 






IP.l 


= 00B9 


REN 


= 009C 






IP. 2 


= 00BA 


RI 


=0098 






IP. 3 


=OOBB 


RSO 


=00D3 






IP. 4 


=OOBC 


RSI 


=00D4 






IP. 5 


=OOBD 


RXD 


=0OB0 






ITO 


-0088 


SBUF 


=0099 






IT1 


= 008A 


SCON 


=0098 






OV 


=00D2 


SCON.O 


=0098 






P 


=00D0 


SCON.l 


=0099 






PO 


=0080 


SCON . 2 


=009A 






PO.O 


=0080 


SCON. 3 


=009B 






PO.l 


=0081 


SCON. 4 


=009C 






P0.2 


=0082 


SCON. 5 


=009D 






P0.3 


=0083 


SCON. 6 


=009E 






PO.4 


=0084 


SCON. 7 


=0O9F 






P0.5 


=0085 


SMO 


= 009F 






P0.6 


=0086 


SMI 


=009E 








How to Use the Simulator 



Introduction 



One learns to program by writing and testing programs. There are many ways to test a 
program; the most traditional is to load the program into a hardware specific target system 
that uses the computer under study and execute the program. Loading can range from 
transferring the object file from the development system computer to the target system 
RAM for execution via a serial data link, or programming an EPROM with the object file 
and inserting the EPROM into a target system memory socket for testing. 

Both of these approaches use some sort of monitor program that is found in ROM in 
the target system. The monitors are usually adequate for simple program tests: 

Instruction single step or run 
Display register and memory contents 
Stop at selected program addresses 

This capability allows programs to be debugged in a methodical way but requires consid- 
erable skill and time by the programmer. 

With the advent of affordable personal computers, programs have appeared that use 
personal computer resources to simulate the operation of the target computer; the program- 
mer now has a unique view of the computer registers and memory as the program runs. 

Simulators usually show the internal register and memory locations on the screen of 
the personal computer and allow the programmer to perform all of the operations listed 
above for a monitor with the added advantage of watching the data change as the program 
operates. This saves considerable time because the register and memory contents do not 
have to be displayed using separate monitor commands. The visual representation also 
gives the programmer a better "feel" for what is taking place in the program. 

The program under test can also be loaded quickly from the same file that contains the 
simulator, assembler, and editor program. If the personal computer has sufficient RAM to 
enable RAM disk structures to be created, the process of edit, assemble, and simulate can 
be done in a very timely manner. Finally, the expense of buying special target systems is 
avoided enabling the user to "try" many different computers at minimal cost. 



220 



HOW TO USE THE SIMULATOR 221 

Simulators do not, however, generally have the ability to perform actual I/O or inter- 
nal hardware operations such as timing or data transmission and reception. You must, at 
last, try the program in a target system when doing an actual application. 

The 8051 simulator used with this book is the PseudoMax 51 written by David Akey 
of Pseudocode, Newport News, Virginia. David also supplied the PseudoSam 51 A51 
assembler, which has been used to write all of the programs in the text and is included on 
the book disk. 



Computer Configuration Needed 
to Run the Simulator 



Features 



The 8051 Simulator runs on IBM PC and compatible computers. Requirements for the 
PC are 

512K RAM 

DOS version 2. 1 or newer 

IBM Mono, CGA, EGA, or compatible monitor 

Two disk drives (One must be 5 I /4") 



The outstanding feature of the simulator is the ability of the user to construct screens that 
show various parts of an 805 1 system . Each screen is made up of separate windows that dis- 
play internal CPU registers and code and data memory areas. The screen set can be saved 
as a disk file and used for one type of problem; another screen set can be configured for a 
different type of problem and loaded when needed. 

The user may construct up to ten screens, each made up of a mixture of the 42 avail- 
able register and memory windows. Not all 42 windows can fit on one screen, so different 
screens must be used to show the total set of windows needed for a particular program 
simulation. 

To run a simulation, the screen set file is loaded into the simulator first, followed by a 
program in object code format. The program is then run using these simulator commands: 

1. Reset the program counter to OOOOh 

2. Single step the program 

3. Free run the program 

4. Free run until breakpoint is reached 

5. Stop free run 

The contents of any location in code ROM and internal RAM (including the special- 
function registers) and external memory may be changed by the user while the program 
runs. Port I/O may be simulated by changing the value of the port special function regis- 
ters. Interrupts are simulated by striking function keys on the PC keyboard. 

The simulator included with the text is a student version that is identical to the profes- 
sional version with the exception that memory is limited to 3FFh bytes each of code and 
data address space. A professional version, which has the full memory address capability, 
can be obtained from Pseudocode or other authors of simulator programs. 



222 APPENDIX C 



The Simulator Programs 



The disk contains two simulator program files: S5I.EXE and BOOK.BSS. S51 is the 
PseudoMax 8051 simulator, and BOOK.BSS is a sample simulator file that contains four 
screens. BOOK.BSS has been used to simulate all of the programs in the text using the 
professional simulator version. BOOK.BSS may be used, as is, to simulate programs 
written in response to problems in the text; the student is encouraged to create other .BSS 
files once operation of the simulator has been mastered. 

Starting the Simulator 

Before using the simulator you should have an object file ready to simulate. Write a small 
program (5 or 6 lines) assemble it, and you will have a .OBJ program for trial use in the 
simulator. You may name it what you will; it will be identified as yourfile.obj in the in- 
structions that follow. 

After booting up your DOS system, place the disk containing the simulator in drive B, 
and your disk with the .OBJ file in drive A. The simulator must be loaded with two files: 
the screen file, Book.bss, and your object file, yourfile.obj, before it is run: 

1. Go to the B> prompt and type: s5l <return> 

The program will load, and display the menu screen shown in Figure C. 1 . The 
status line will ask you to Select. 

2. Type L for Load 

The status line will ask you to Select an Object file or Previous machine. 

3. Type P for Previous machine. 

The status line will ask for the saved filename. 

4. Type book.bss <return> 

book.bss will be loaded into the simulator, and the status line will ask you to 
Select. 

5. Type L for Load 

The status line will ask you to Select an Object file or Previous machine. 

6. Type O for Object file 

The status line will ask for the saved filename. 

7. Type in a:yourfile.obj <return> 

Yourfile.obj will be loaded into the simulator, and the status line ask you to 
Select. 

8. Type R for Run 

The simulator will display the first Screen, shown in Figure C.2, and await your 
commands. 

Running the Simulation of YOURFILE.OBJ 

Once the object file is loaded, you can 

1. Reset the system by typing CTRL-Home. 

2. Step the program by pressing the left arrow <— key. (The screen is updated after 
each step.) 

3. Free run the program by pressing the right arrow ~* key. (The screen updates 

constantly.) 

4. Speed up the free run execution time by stopping updating using function key 
F10. F9 restores updating. 



HOW TO USE THE SIMULATOR 223 

5. Stop free run by pressing the END key or the left arrow (step) key. 

6. Make changes in memory or register contents by typing commands on the screen 
status line. 

7. Exit the Run mode, and return to the menu screen by pressing the CTRL END 
keys. 

BOOK.BSS Simulator Screens 

Four simulator screens, shown in Figures C.2 to C.5, are defined on BOOK.BSS. These 
screens have been designed to offer a view of many different areas of an 8031 system. 
A screen is chosen by pressing the alternate key and a function key simultaneously. Every 
screen has a status line at the bottom for typing various memory and register configuration 
commands. 

Screen 1: (ALT-F1) The Main Screen. 

The viewer can observe the operations of the PC, SP, IE, and A registers, and ports PI and 
P3 in individual windows. Special-function registers DPL, DPH, PCON, TCON, TMOD, 
TLO, TL1 , THO, and TH1 can be found in the internal RAM window 2, which displays a 
portion of the SFR area. Internal RAM window 1 shows register banks and 1. An in- 
struction execution window will display program mnemonics as the program is operated. 

Screen 2: (ALT-F2) The Internal RAM Screen. 

Internal RAM windows 3 to 5 display internal RAM from lOh to 3Fh. Window 6 shows 
the SFR area, which includes SCON and SBUF. The SP, DPTR, A, and PC are also shown. 

Screen 3: (ALT-F3) The ROM Screen. 

Program code addresses from OOOOh to OOBFh are displayed in code memory windows 
1 to 3. The PC, A, DPTR, and instruction execution windows are also part of this screen. 

Screen 4: (ALT-F4) The External RAM Screen. 

External RAM from addresses OOOOh to OOBFh are displayed in external data memory 
windows I to 3. The PC, A, DPTR, and instruction execution windows are also part of 
this screen. 

Changing Register and Memory Contents 

As the program runs you may wish to change the contents of a register or memory address: 

1 . Change any register contents by typing REGNAM = XX <return> on the status 
line (where REGNAM is one of the register names given in Appendix B.3 and 
XX is any hexadecimal data). For example, PI=AA will load the PI Window 
with the data A Ah. 

2. Change External RAM contents by typing &ADDRESS = XX 

3. Change Internal RAM contents by typing: *ADDRESS = XX 

4. Change Code ROM contents by typing: @ADDRESS = XX 

Here, ADDRESS is any legal address from 0000 to 03FF, and the following are examples: 

&0040= BC loads external address 40 with data BCh. 
*01 = 12 loads internal address 01 with data 12h. 



224 APPENDfX C 



(You could also type Rl — 1 2 IF Bank is selected) 
@00C0= B6 changes code address CO contents to B6h. 

To change entire blocks of memory, do not enter the =XX part of the line. 

Setting Breakpoints 

Breakpoints are memory addresses that cause the program to stop when in the free run 
operating mode. The program will free run until a breakpoint address is accessed in any 
way (read from it, write to it, or fetch it for program execution) and then stop. 

The program can be started in free run again and will run until the next breakpoint 
address is reached. Breakpoints are typed on the status line. 

1. Set a breakpoint in code memory by typing: !Address = +b 

2. Set a breakpoint in internal RAM by typing: #Address = +b 

3. Set a breakpoint in external memory by typing: % Address = +b 

4. Disable a breakpoint in memory by typing: (!,#,%)Address = — b 

Here, Address = 0000 to 03FF. For example, !0040 = +b will set a breakpoint at pro- 
gram address 40, while 10040 — — b will clear it. Note that I/O ports are internal RAM 
and can set with the breakpoint attribute. I/O operations automatically stop the Free Run. 

Generating Interrupts 

All of the 8051 interrupts can be simulated by using the function keys while pressing the 
shift key: 

IE0 = SHIFT F1 
TF0 = SHIFT F2 
IE1 - SHIFT F3 
TF1 = SHIFT F4 

RI.TI = SHIFT F5 

Saving a Session 

To save the present state of a session, exit the run mode by using the CTRL END keys 
and return to the main menu. Press the S key and save your simulation state by following 
the prompts and naming the program yourfile.bss. When re-starting the simulator, use the 
name yourfile.bss instead of book.bss when loading the Previous machine file. The .obj 
program has been saved also, so you may proceed directly to run after loading yourfile.bss. 



Creating Your Own Screens 



To create custom screens you should invoke s5l and load BOOK.BSS. Then, when 
prompted by the status line, press P for "Profile." Profile is the process of creating your own 
screens. While in the profile mode the status line for each screen will display your choices: 
Add, Delete, Move, Copy, Quit. 

The first Screen of BOOK.BSS will appear, and you can begin to configure your first 
screen by (D)eleting windows and (A)dding windows, then (M)oving them around. Use 
the ALT-FX keys to go to screens 1 to 10. 

Windows are deleted by positioning the cursor box on an undesired window (using 
the right and left arrow keys) and pressing the D key. Windows are added by pressing the 
A key and typing in a window number at the prompt on the status line. 



HOW TO USE THE SIMULATOR 



225 



The numbers for each Window are as follows: 



Window 

A register 

B register 

Data pointer 

Port 1 

Port 3 

IE register 

Stack 

Code ROM 1 

PSW register 

TCON 



Number 

16 

18 

22 

24 

26 

28 

30 

39-46 

55 

58 



Window 

Program counter 
Stack pointer 
Port 
Port 2 
IP register 
PCON register 
External RAM 1 - 
Internal RAM I-! 
SCON register 
Execution 



Number 

17 
21 

23 

25 

27 

29 

31-38 

47-54 

57 

59 



For example, screen 1 of BOOK. BSS consists of windows 16, 17,59,28,55,24,26,30, 
47, and 48. 

The window can be moved anywhere on the screen by pressing the M key and using 
the cursor keys (up, down, left, right) to position the window at the desired screen loca- 
tion. A return key fixes the new location chosen. 

When a screen is done, go to the next screen and repeat the same steps. Pressing the 
Q key will return to the original s51 menu. 

The copy command will copy the screen number typed in response to the status line 
query to the current screen. Normally the current screen will be empty and a previously 
done screen copied to it. 

Setting RAM and ROM Window Starting Addresses 

After making your screens you may also select the beginning address of each memory 
window. An inspection of BOOK. BSS internal RAM window 2 of screen 1 shows that the 
beginning address is 82h, which is the internal address of the DPL special-function register. 
To set a memory beginning address you must be in the (R)un mode. Select a screen 
with the memory window of interest and type on the status line: 



.mw# = xxxx 



.irw# = xx 



. edw# = xxxx 



Here, # = 1 to 8, ,mw is code memory window, ,irw is internal RAM window, and .edw 
is external data window. For example, to set Internal Ram Window 2 to start at address 
82h on screen 1 of BOOK. BSS, the command typed on the status line of screen I when in 
the run mode is: 



.irw2 = 82 <return> 

Setting Memory Attributes 

The last task to be performed is to determine the type of memory access for each byte of 
memory. Memory can have these attributes: 

r read 

w write 

e execute 

io input/output 



226 APPENDIX C 

b breakpoint 

n ignore the rest (memory-type dependent) 

An attribute can be enabled by typing a + (plus) in front of it. The section on setting 
breakpoints shows any memory address can cause the program to stop in free run by a +b. 
Attributes are disabled by a - (minus) in front of the attribute letter; — b removes a break- 
point from an address. 

BOOK.BSS has the following attributes assigned: 

Code memory + r -w +e -io -b — n 

(+n = +r +w +e — io -b) 
Internal RAM +r +w +io -b -n 

( + n = +r +w -Ho — b) 
External data +r +w -e -io -b — n 

( + n = +r + w + e -io -b) 

To view these attributes (you must be in the run mode), type ! for code, # for internal 
RAM, or % for external data followed by a return. A window will pop up on the screen 
showing the memory addresses and attributes. The page up and page down keys can scan 
lengthy memory attribute windows. 

To change an attribute of one address or a range of addresses, type: 

! start address. . end address = +/— rweiobn for the Code addresses 
#start address. .end address = +/— rwiobn for the Internal Ram 
%Start address, .end address - +/- rweiobn for External Data 

For example, BOOK.BSS memory attributes were set by typing: 

10000. .03ff = + r -w +e -io -b -n for Code Memory 

#00. . f f = +r +w -io -b -n for Internal Ram 

#80. .80 = +io for Port of internal Ram 

#90. .90 = + io for Port 1 of internal Ram 

#A0. .A0 = +io for Port 2 of internal Ram 

#B0. .B0 = +io for Port 3 of internal Ram 

%0000. .03ff = +r +w -e -io -b -n for the External Data 

Forgetting to set the attributes correctly (such as making the code memory — e) will cause 
the simulator to stop while in free run and display a violation in the upper right hand 
corner of the screen. 

Remember: 

After having configured your screens, set the memory starting addresses, and given 
attributes to all memory, save your new .BSS file by leaving the run mode (CTRL END) 
to get to the s5 1 Menu screen. Press the S key to save the new file and provide the new file 
name on the status line when asked. 



HOW TO USE THE SIMULATOR 



227 



FIGURE C1 Menu 



PseudoMax™ 51 "the smart simulator" 

Educational Version Bl.1.01 

Copyright © 1990 PseudoCorp 

All rights reserved! 

Licensed for non-commercial Educational use only! 



DIRECTORY 

RUN 

SAVE 

LOAD 

QUIT 

PROFILE 



Select : 



FIGURE C2 Main Screen 

Screen: 1 Trace: OFF 



Internal Ram Window 


1 


Addr 


Value Addr 


Value 


RO 


= 00 0008 


- 00 


Rl 


= 00 0009 


= 00 


R2 


= 00 OOOA 


- 00 


R3 


- 00 OOOB 


= 00 


R4 


= 00 000C 


= 00 


R5 


= 00 OOOD 


= 00 


R6 


= 00 OOOE 


- 00 


R7 


- 00 OOOF 


= 00 



Update 



PC 

0000 

0000 

0000 

0000 

0000 



A 

00 

00 

00 

00 

00 



Loc 

0000 

0000 

0000 

0000 

0000 



SP 


Stack 


05 


00 


06 


00 


07 


00 


08 


00 


09 


00 



Inst Addr 



IE 
00 
00 
00 
00 
00 



STOP 



Internal Ram Window 


2 


Addr 


Value Addr 


Value 


DPL 


= 00 TLO 


= 00 


DPH 


= 00 TL1 


= 00 


0084 


= 00 THO 


= 00 


0085 


= 00 TH1 


= 00 


0086 


= 00 008E 


= 00 


PCON 


= 00 008F 


= 00 


TCON 


= 00 PI 


= FF 


TMOD 


- 00 0091 


= 00 



CY 


AC 


FO 


RSI 


RSO 


OV 


— 


p 























































































































1 



PI 

FF 
FF 
FF 
FF 
FF 

P3 
FF 
FF 
FF 
FF 
FF 



M 
00 



g 
x 

n 



FIGURE C3 Main Screen 1 
Screen: 1 Trace: OFF 



Internal Ram Window 


1 


Addr 


Value Addr 


Value 


RO 


- 00 0008 


= 00 


Rl 


= 00 0009 


- 00 


R2 


= 00 000A 


- 00 


R3 


- 00 000B 


= 00 


R4 


= 00 oooc 


= 00 


R5 


= 00 000D 


= 00 


R6 


= 00-OOOE 


= 00 


R7 


= 00 000F 


= 00 



Update 



PC 

0000 

0000 

0000 

0000 

0000 



A 

00 

00 

00 

00 

00 



Loc 

0000 

0000 

0000 

0000 

0000 



SP 


Stack 


05 


00 


06 


00 


07 


00 


08 


00 


09 


00 



Inst Addr 



IE 
00 
00 
00 
00 
00 



STOP 



Internal Ram Window 


2 


Addr 


Value Addr 


Value 


DPL 


= 00 TLO 


= 00 


DPH 


= 00 TL1 


= 00 


0084 


= 00 THO 


= 00 


0085 


= 00 TH1 


= 00 


0086 


= 00 008E 


= 00 


PCON 


= 00 008F 


= 00 


TCON 


= 00 PI 


= FF 


TMOD 


= 00 0091 


= 00 



CY 


AC 


FO 


RSI 


RSO 


OV 


_~ 


P 























































































































1 



PI 

FF 
FF 
FF 
FF 
FF 

P3 
FF 
FF 
FF 
FF 
FF 



x 
Q 



c 

I— 

70 



FIGURE C4 Internal RAM Screen 2 



Screen 


2 Trace: OFF 




Inter 


nal Ram Window 


3 


Addr 


Value Addr 


Value 


0010 


= 00 0018 


= 00 


0011 


- 00 0019 


- 00 


0012 


= 00 001A 


- 00 


0013 


- 00 001B 


= 00 


0014 


= 00 001C 


= 00 


0015 


= 00 001D 


= 00 


0016 


= 00 001E 


- 00 


0017 


= 00 001F 


= 00 



Update 



0020 


= 00 0028 


- 00 


0021 


= 00 0029 


= 00 


0022 


= 00 002A 


= 00 


0023 


= 00 002B 


= 00 


0024 


= 00 002C 


- 00 


0025 


= 00 002D 


= 00 


0026 


= 00 002E 


- 00 


0027 


= 00 002F 


= 00 



Internal Ram Window 


5 


Addr 


Value Addr 


Value 


0030 


- 00 0038 


= 00 


0031 


- 00 0039 


= 00 


0032 


= 00 003A 


= 00 


0033 


= 00 003B 


= 00 


0034 


- 00 003C 


= 00 


0035 


= 00 003D 


- 00 


0036 


= 00 003E 


- 00 


0037 


= 00 003F 


= 00 



SCON 


- 00 F2 


= FF 


SBUF 


= 00 OOAl 


= 00 


009A 


= 00 00A2 


- 00 


009B 


- 00 00A3 


= 00 


009C 


= 00 00A4 


= 00 


009D 


- 00 O0A5 


= 00 


009E 


= 00 00A6 


= 00 


009F 


= 00 00A7 


= 00 



A 

00 

00 

00 

00 

00 



STOP 



SP 




DPTR 


00 




0000 


00 




0000 


00 




0000 


00 




0000 


07 




0000 



PC 

0000 

0000 

0000 

0000 

0000 



IjU 

© 



> 

-a 



g 
x 

n 



FIGURE C5 Code Screen 3 

Screen: 3 Trace: OFF 



Code 


Memory Window 


1 






1 


2 


3 


4 


5 


6 7 




8 9 


A 


B 


C 


D 


E F 


0000 


00 00 


00 


00 


00 


00 


00 00 




00 00 


00 


00 


00 


00 


00 00 


0010 


00 00 


00 


00 


00 


00 


00 00 




00 00 


00 


00 


00 


00 


00 00 


0020 


00 00 


00 


00 


00 


00 


00 00 




00 00 


00 


00 


00 


00 


00 00 


0030 


00 00 


00 


00 


00 


00 


00 00 




00 00 


00 


00 


00 


00 


00 00 
1 



PC 

0000 

0000 

0000 

0000 

0000 



A 

00 

00 

00 

00 

00 



Loc 

0000 

0000 

0000 

0000 

0000 



Inst Addr 



Update 



DPTR 
0000 
0000 
0000 
0000 
0000 

















STOP 


Code 


Memory Window 


2 









1 


2 


3 


4 


5 


6 7 




8 


9 


A 


B 


C 


D 


E F 


0040 


00 


00 


00 


00 


00 


00 


00 00 




00 


00 


00 


00 


00 


00 


00 00 


0050 


00 


00 


00 


00 


00 


00 


00 00 




00 


00 


00 


00 


00 


00 


00 00 


0060 


00 


00 


00 


00 


00 


00 


00 00 




00 


00 


00 


00 


00 


00 


00 00 


0070 


00 


00 


00 


00 


00 


00 


00 00 




00 


00 


00 


00 


00 


00 


00 00 



0080 


00 00 00 


00 00 


00 


00 00 




00 00 00 


00 00 


00 


00 00 


0090 


00 00 00 


00 00 


00 


00 00 




00 00 00 


00 00 


00 


00 00 


00A0 


00 00 00 


00 00 


00 


00 00 




00 00 00 


00 00 


00 


00 00 


OOBO 


00 00 00 


00 00 


00 


00 00 




00 00 00 


00 00 


00 


00 00 



X 

o 



c 

p— 

> 






St 



FIGURE C.6 External RAM Screen 4 



Screen 


: 4 Trace: OFF 






Extern Data Memory Window 


1 




1 


2 3 


4 5 


6 


7 




8 9 


A B 


C D 


E 


F 


0000 


00 00 


00 00 


00 00 


00 


00 




00 00 


00 00 


00 00 


00 


00 


0010 


00 00 


00 00 


00 00 


00 


00 




00 00 


00 00 


00 00 


00 


00 


0020 


00 00 


00 00 


00 00 


00 


00 




00 00 


00 00 


00 00 


00 


00 


0030 


00 00 


00 00 


00 00 


00 


00 




00 00 


00 00 


00 00 


00 


00 



PC 

0000 

0000 

0000 

0000 

0000 



A 

00 

00 

00 

00 

00 



Loc 

0000 

0000 

0000 

0000 

0000 



Inst Addr 



Update 



DPTR 
0000 
0000 
0000 
0000 
0000 



STOP 



Extern Data Memory Window 2 


12 3 4 5 


6 7 


8 9 A B C D 


E F 


0040 00 00 00 00 00 00 


00 00 


00 00 00 00 00 00 


00 00 


0050 00 00 00 00 00 00 


00 00 


00 00 00 00 00 00 


00 00 


0060 00 00 00 00 00 00 


00 00 


00 00 00 00 00 00 


00 00 


0070 00 00 00 00 00 00 


00 00 


00 00 00 00 00 00 


00 00 



ooso 


00 00 


00 00 00 


00 00 00 




00 00 


00 00 00 


00 00 00 


0090 


00 00 


00 00 00 


00 00 00 




00 00 


00 00 00 


00 00 00 


00A0 


00 00 


00 00 00 


00 00 00 




00 00 


00 00 00 


00 00 00 


00B0 


00 00 


00 00 00 


00 00 00 




00 00 


00 00 00 


00 00 00 



x 

n 




The 8255 Programmable I/O Port 



introduction 



Eight-bit microprocessor families included peripheral chips that are used with the CPU to 
provide many of the I/O functions that are now found integrated inside a microcontroller. 
As the 8-bit microprocessor fades into obsolescence, these peripheral chips are finding a 
new life in augmenting microcontroller I/O capability. 

These peripheral chips include serial and parallel I/O as well as interrupt controllers 
and dynamic RAM controllers. The 8051 loses two parallel I/O ports when used with 
external memory, and part of a third to serial data communication and interrupt functions. 
To make up for this loss, a programmable parallel port chip, the 8255, is often added to 
an 8051 system, as discussed in Chapter 7. This appendix describes how to use the 8255 
as a basic parallel I/O port. The 8255 is capable of many sophisticated I/O functions, 
including interrupts and handshaking. Refer to the manufacturers" literature for a com- 
plete description of 8255 capabilities and programming. 



Functional Description 



The 8255 features three 8-bit programmable parallel I/O ports named A, B, and C. Port C 
can be used as two separate ports of four bits each if properly programmed. The program- 
ming model of the 8255 and a pinout of the 40 pin DIP is shown in Figure D. 1 . 

Before any port can be used, the 8255 must be programmed by writing the proper 
control bits to the control register. The three ports may then be accessed by the 8051 pro- 
gram. The 8255 uses the address lines A0 and Al to access the Control register and the 
three Ports. The RD, WR and CS lines are enabled by the particular decoding scheme 
used by the 8051 system designer. The resulting control and address states yield the fol- 
lowing actions: 



233 



234 



APPENDIX D 










Al 


AO 


RD 


WR 


CS 








L 


H 


L 





1 


L 


H 


L 


1 





L 


H 


L 








H 


L 


L 





1 


H 


L 


L 


1 





H 


L 


L 


1 


1 


H 


L 


L 


X 


X 


X 


X 


H 



Action 

Read the Contents of port A 
Read the Contents of port B 
Read the Contents of port C 
Write to the port A Latch 
Write to the port B Latch 
Write to the port C Latch 
Write to the Control register 
Data bus to high impedance 

The 8255 appears much like an internal port of the 8051 once it has been programmed. 



Programming The 8255 



Control bytes written to the control register use each bit of the byte to program some 
feature of the 8255: 

Result 

Program ports for mode and input or output 
Set/reset individual bits of port C 

then the ports are programmed as: 

Result 

Set port A and C4-C7 in I/O mode 

Set port A and C4-C7 in I/O mode 1 

Set port A and C4-C7 in I/O mode 2 

Set port A as an output port 

Set port A as an input port 

Set C4-C7 as an output port 

Set C4-C7 as an input port 

Set port B and C0-C3 in I/O mode 

Set port B and C0-C3 in I/O mode I 

Set port B as an output port 

Set port B as an input port 

Set C0-C3 as an output port 

Set C0-C3 as an input port 

8255 I/O Modes 

Port A and the high part of port C may be programmed in one of three modes, port B and 
the lower part of port C may be programmed in one of two modes. The modes are 

Mode 0— Basic I/O: Data written to the port is latched; data read from the port is 
read from the input pins. (This mode is identical to 8051 port operation.) 

Mode I — Strobed I/O: This handshaking mode uses ports A and B as I/O and port C 
to generate handshaking signals to the devices connected to ports A and B and an 
interrupt signal to the host microcontroller. 



Bit 


State 


7 


1 


7 





When bit 7 is a 


Bit 


State 


6,5 


00 


6,5 


01 


6.5 


10 


4 





4 


1 


3 





3 


I 


2 





2 


1 


1 





I 


1 











1 



THE 8255 PROGRAMMABLE I/O PORT 235 

Mode 2 — Strobed bi-directional I/O: This mode is similar to Mode I with the abil- 
ity to use port A as a bi-directional data bus. 

Modes 1 and 2 require setting interrupt enable bits in the port C data register. These 
modes are intended to be used with intelligent peripherals such as printers. 

Reset Condition 

Upon reset all the port data latches and the control register contents are cleared to 00. The 
ports are all in the input mode. 




Control Registers 



Introduction 



For the convenience of the programmer the control special-function register figures from 
Chapter 2 are shown here for easy reference. An ASCII table is shown below. 



ASCII Codes for Text and Control Characters— No Parity 



HEX 


Character 


HEX 


Character 


HEX 


Character 


HEX 


Character 


00 


NUL 


28 


( 


50 


P 


78 


X 


01 


SOH 


29 


) 


51 





79 


y 


02 


STX 


2A 


* 


52 


R 


7A 


z 


03 


ETX 


2B 


+ 


53 


S 


7B 


{ 


04 


EOT 


2C 


, 


54 


T 


7C 


1 
1 


05 


ENQ 


2D 


- 


55 


U 


7D 


} 


06 


ACK 


2E 




56 


V 


7E 


~ 


07 


BEL 


2F 


/ 


57 


w 


7F 


(del) 


08 


BS 


30 





58 


X 






09 


HT 


31 


I 


59 


Y 






0A 


LF 


32 


2 


5A 


Z 






0B 


VT 


33 


3 


5B 


[ 






OC 


FF 


34 


4 


5C 


\ 






0D 


CR 


35 


5 


5D 


] 






OE 


SO 


36 


6 


5E 


A 






OF 


SI 


37 


7 


5F 









10 


DLE 


38 


8 


60 


' 






11 


DC1 


39 


9 


61 


a 






12 


DC2 


3A 




62 


b 






13 


DC3 


3B 


; 


63 


c 






14 


DC4 


3C 


< 


64 


d 






15 


NAK 


3D 


= 


65 


e 







Continued 



236 



HEX 


Character 


HEX 


Character 


HEX 


Character 


16 


SYN 


3E 


> 


66 


f 


17 


ETB 


3F 


7 


67 


g 


18 


CAN 


40 


<3> 


68 


h 


19 


EM 


41 


A 


69 


i 


1A 


SUB 


42 


B 


6A 


J 


IB 


ESC 


43 


C 


6B 


k 


1C 


FS 


44 


D 


6C 


1 


ID 


GS 


45 


E 


6D 


m 


IE 


RS 


46 


F 


6E 


n 


IF 


US 


47 


G 


6F 


o 


20 


(space) 


48 


H 


70 


P 


21 


i 


49 


I 


71 


q 


22 


" 


4A 


J 


72 


r 


23 


# 


4B 


K 


73 


s 


24 


$ 


4C 


L 


74 


t 


25 


% 


4D 


M 


75 


u 


26 


& 


4E 


N 


76 


V 


27 


■ 


4F 


O 


77 


w 



CONTROL REGISTERS 237 

HEX Character 




Index 



Add Instructions, 74-77 
Address Pins, 15, 23-25 
A/D Conversion Circuit, 165 
Addition, 74-77 
Accumulator ( A Register ). 14, 

17-18 
Addressing Modes 
direct, 47 
immediate, 45 
indirect, 49 
register. 45 
Address/Data Bus. 23-25, 26-28 
Address Latch Enable ( ALB ) 

Pulse, 26 
Asynchronous Serial Data Baud 

Rate, 35-37 
Asynchronous Serial Data Modes. 

35-37 
Asynchronous Serial Data Format, 

36 
Asynchronous Serial I/O, 32-37 

B Register, 14, 17-18 

Baud Rate. Timer 1, 36 

Binary Coded Decimal Arithmetic. 

81-82 
Binary Coded Decimal. 81 
Bit Addressable RAM, 19, 62 
Bit-Level Instructions, 62-65 
Byte-Level Instructions, 60-61 
Boolean Instructions, 59-66 
Bus Timing, 26-28 



Call Instructions. 92-93 
Carry Flag, 18 

Central Processing Unit. 11-14 
Ceramic Resonator. 17 
Clock Divider. 30 
Compare Instructions. 90 
Counter Mode, 32 
Crystal Oscillator. 16-17 

D/A Converter. 163 

Data Exchange Instructions. 53 

Debouncing Keys, 132 

DPTR Register. 17 

Data/ Address Bus. 23-25. 26-28 

Decrement Instructions, 73-74 

Direct Addressing Mode, 47 

Disable Interrupts, 40 

Displays 

LCD, 155 

LED, 151 
Division, 80-81 

Edge Triggered Interrupts, 39 
Enable Interrupts, 40 
EPROM Memory. 26 
Externa! Access Pin, 22,26 
External Memory 

circuits, 26-28 

instructions, 50-52 
Even Parity. 18, 73 

Flags 

auxiliary carry. 18, 72 



carry. !8. 72 

external interrupt 0. 28, 39 

external interrupt I, 28, 39 

overflow, 18 

parity, 18, 73 

timer 0. 28-29 

timer 1. 28-29 

serial data. 32-34. 39 

user, 18. 33 
Free Running Counter. 30 
Frequency Measurement, 159 

Gate Bit For Counter Control. 

29-30 
Gate Circuit for Counters, 30 
General Purpose Internal RAM. 19 
Generating a Waveform. 163 

Hexadecimal Numbers. 217 
Highest Priority Interrupt. 41 

Increment Instructions. 73 
Immediate Addressing Mode. 45 
Indirect Addressing Mode. 49 
Instruction Set. 203-2M 
Integer Division. 80-81 
Interrupts 

external, 39 

timers, 39 

serial data, 39 

software, 41 
Interrupt Circuits. 166-177 



240 



INDEX 



Interrupt Driven Program, 177 
Interrupt Enable Register IE. 38 
Interrupt Priority Register IP, 38 
Interrupt Destination Vectors. 4l 

Jump Instructions. 89-9! 
Jump Table, 169 

Keyboard 
debounce, 132 
coded, 134, 144 
matrix. 133,147 
uncoded, 133, 136 

Latched Port Outputs. 23 
LCD Display Circuit, 23 
LED Display Circuit, 151 
Level Sensitive Interrupts, 28, ,39 
Logical Operation Instructions. 

59-66 
Long Range Addresses, 88 
Look Up Tables, 117 

Machine Cycle, 16-17 
Maskable Interrupts. 40-41 
Measuring External Frequencies, 

158 
Measuring Pulse Widths, 161 
Memory Map 

programming, 13 
Memory 

external RAM. 26-28 

external ROM. 26-28 

internal RAM, 19 

internal ROM. 22 

mapped I/O, 104-106 
Modes 

address, 45-49 

timers. 30-32 

serial I/O, 34-37 
Moving Data Instructions 

external, 50-51 

internal, 45-49 
Multiplexed Address/Data Bus, 

26-28 
Multiplication, 80 
Multiprocessing, 197-201 
Multiprocessor Receive Enable Bit. 

37. 197 
Multiprocessor Transmit Bit. 36. 
197 

Oscillator, 16-17 
Overflow Flag. 18 



Parity Flag, 18 
PCON Register. 33 
Period of a Signal, 161 
Pin Assignments 

DIP, 15 
Port I/O Circuits 
PortO, 23-25 
Port I, 25 
Port 2, 25 
Port 3, 25 

Pointers to Memory, 49 
Polling Software Technique, 112. 

124, 126 
Program Counter, 17 
Programming Model, 13 
Program Store Enable ( PSEN ) 

Pulse, 26 
Programs 

Adconv, 166 

Ant. 177 

Bigkey, 147 

Codekey, 144 

Davcon, 164 

Dplook, 120 

Freq. 159 

Getkey, 136 

Hardint, 175 

Hardtime, 115 

Hipri. 164 

Inkey, 139 

Intdat. 127 

Lcdisp. 156 

Loprj, 168 

Modeone. 193 

Modethree, 198 

Modezero, 190 

Pclook. 119 

RAM Test, 108 

ROM Test, 107 

SBUFR, 125 

Sendchar, 123 

Softime, HI 

Svnseg, 152 

Timer, 113 

Width, 161 

Xmit. 125 
PS W Register, 18 
Pulse Width Measurement 
Push and Pop Instructions. 52-53 

RAM 

external, 26-28 
internal, 19 
Read Pulse, 25-28 



Read-Modify- Write Port Instruc- 
tions, 61 
Receive Interrupt Flag, 34,39 
Register Address Mode, 45 
Register Banks, 19 
Register Bank Selection, 18-19 
Register Pointers to Memory, 49 
Relative Addresses, 87 
Reset Circuit, 102-103, 106 
Reset State of Special Function 

Registers, 40 
Return Instructions, 93-94 
ROM 

external, 26-28 

infernal, 22 
Rotate Instructions, 66-67 

SBUF Serial Buffer Register, 32 

SCON Serial Control Register. 33 

Serial Data Baud Rates, 32-37 

Serial Data Modes 

shift register mode 0, 34 
standard UART mode 1, 35 
multiprocessor modes 2 and 3, 
36-37 

Serial Data Formats 
UART, mode 1.36 
multiprocessing, mode 2 and 3, 
37 

Serial I/O. 32-37 

Serial Data Networks, 186-188 

Serial Receive Interrupt Flag. 34,39 

Serial Transmit Interrupt Flag, 34, 
39 

Shift Register Serial Data Mode 0, 
34 ' 

Short Range Addresses, 88 

Software Interrupt, 41 

Special Function Registers, 21-22 

Stack, 19, 52-53 

Stack Pointer, 19,. 52-53 

Start Bit, 35-36, 

States of a Machine Cycle. 16-17 

Stop Bit. 35-36, 

Subtraction. 77-79 

Table Look Up, 117 
TCON Timer Control Register, 28 
Timer 0, 28-29 
Timer 1, 28-29 
Timer Gating Circuit, 30 
TMOD Timer Mode Control Regis- 
ter, 29 
Timer Modes 



INDEX 241 



single 8 bit counter mode 0, 30 UART Serial Data Transmission 
16 bit counter mode I, 30 Mode, 35-36 

auto reload mode 2, 31 UART Serial Data Byte, 36, 193 
double 8 bit counter mode 3, 32 

Transmit Interrupt Flag, 34, 39 Vector, Interrupt. 41 

Write Pulse, 25-26