0% found this document useful (0 votes)
91 views

Microprocessors and Microcontrollers

This document provides an overview of microcomputers and their components. It describes a typical microprocessor-based system including the microprocessor, ROM, RAM, data bus, address bus, control bus, and input/output components. It then discusses the address bus, data bus, control signals like read/write and reset, and interrupt requests in more detail. The document also briefly mentions different processor architectures from various manufacturers and standard interfaces like RS-232.

Uploaded by

brightmore
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
91 views

Microprocessors and Microcontrollers

This document provides an overview of microcomputers and their components. It describes a typical microprocessor-based system including the microprocessor, ROM, RAM, data bus, address bus, control bus, and input/output components. It then discusses the address bus, data bus, control signals like read/write and reset, and interrupt requests in more detail. The document also briefly mentions different processor architectures from various manufacturers and standard interfaces like RS-232.

Uploaded by

brightmore
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 86

Chapter One: Introduction to Microcomputers

1.0 Microcomputers Overview

A microcomputer is a microprocessor based system which is a small but fully fledged computer complete with
all types of memories and input and output functionality. Figure 1.1 shows a block diagram of an 8-bit
microprocessor based system with a 16 bit address bus. It includes the typical components found in such a
system. It can be used as an embedded controller in a processing plant or any other system. The main
components of the system include the microprocessor (the heart of the system), some non volatile storage
typically a read only memory or ROM (for the system control program), some read write memory (also
random access memory or RAM for use as a scratch pad) and various forms of input and output components
(for communicating with the outside world). It is based around three buses: the 8 bit bidirectional data bus,
the 16 bit address bus radiating away from the microprocessor to all other devices and the control bus. This
course will use the Motorola MC6809 microprocessor as an example. It is one of the most powerful 8 bit
microprocessors ever developed and was released in 1979. Several other commonly used components will be
used to illustrate the course. The second part of the course will look at the Motorola MC68HC11
microcontroller. It is one of the most powerful 8-bit microcontrollers ever developed and found widespread
use in the automotive, processing and other industries.

Address Bus
Most 8 bit microprocessors (8 bit on the data bus) come with 16 bit addresses (A15..A0). Addresses are
generated by the microprocessor and used by all the other devices in the system. 16 bit addresses can address
a total of 64 kilo bytes of memory. A kilobyte is 210 or 1024 bytes. This is known as the memory address
range. Such addresses fall in the range $0000 through $FFFF or 0 through 65535. Such addresses must
always be treated as positive unsigned numbers. These addresses are normally buffered to address the problem
of fan out. The address outputs of the microprocessor (usually implemented as nMOS fabrication processing
technology) can only deliver a limited amount of current. The address buffers can drive the several inputs
typically found on the address bus in the microprocessor based system, i.e. the address inputs of the various
devices. TTL 74LS373 and 74LS374 buffers are commonly used. Two 74LS373 octal latches can be used and
these are then normally permanently operated in the transparent mode. Two 74LS374 octal flip flops can
also be used. These are positive edge triggered flip flops and require careful design. The lower order address
lines starting from A0 are used by the various components. The higher order addresses starting from A15 going
down are used by the memory address decoder (MAD) of the system. FPGAs are the best when it comes to
memory address decoding. Other decoding schemes are possible and these will be discussed in detail.
45
Data Bus

The 8 bit data bus is bidirectional. D7..D0. Data can be read into the microprocessor from memory and input
output devices or written away from the microprocessor to memory and input and output devices. A data
transceiver is used between the microprocessor and the various other components to address fan out
limitations. The 74LS245 data transceiver chip is commonly used. The buffered data lines are available on the
common data bus to which all other components connect. When data is written by the microprocessor onto the
bus during a write cycle, the selected device (and only the selected device) is able to accept the written byte.
All other devices must ignore the byte and in-fact will be in the standby mode – thus inactive. In the same
manner, during a read cycle, only the addressed device should place the byte to be read onto the bus to prevent
the potentially destructive bus conflict. All other devices must float their data pins to prevent bus conflict. As
a result, a maximum of one and only one device should be selected for every address placed on the buffered
address bus. Some addresses may be unallocated in a system and will result in no device being selected.

Control Bus

The control bus consists of a number of individual signals. Some are generated by the microprocessor,
whereas others are generated by input and output devices. Yet some are derived from higher order address
lines through memory address decoding. The following are typical control signals.

The RESET signal (RESET): A control signal which is low active. After power is applied to the system, a
special circuit keeps this signal low for a minimum period after the voltages stabilize. This drives the entire
system into an initial known starting state. This ensures a consistent and predictable start up (or boot)
sequence. After some time, the RESET signal is deactivated and the system is ready to run. Simple NE555
timer based RESET circuits are commonly used. There are also specialized but optimized chips which can
derive the RESET signal. They invariably use the charging of a capacitor through a resistor to produce the
RESET signal.

The enable clock (E): A piezo electric crystal is used as a timing reference by the entire system. It is
connected to the microprocessor and an internal oscillator circuit produces a free running clock, typically at a
frequency which is a quarter of the crystal frequency. This is referred to as the enable clock. It marks bus
cycles and a bus transfer takes place during the bus cycle. During the first half of the bus cycle, the clock is
low and addressing and other control information stabilizes during this period. During the second half of the
bus cycle, the enable signal is high and the actual data transfer takes place. See figure 1.3.

The Read and not Write (R/W): Also sometimes called WE, this control signal determines the direction of
data transfer during a bus cycle. During a read cycle, the control signal is high. Data is read into the
microprocessor via the common data bus from the addressed (selected) input and output device or from
46
memory. During a write cycle, the control signal is low. Data is written by and from the microprocessor to the
addressed device. This is the norm. However, the Intel range of microprocessors use two low active signals:
RD and WR for both reading and writing.

Interrupt Requests: These are control signals from the input and output devices. They enable the I/O devices
to invoke special processing by the processor apart from its normal sequence of instructions or operations. A
processor will have one or more of these interrupt request inputs. Some are low level sensitive, e.g. IRQ and
FIRQ on the MC6809 microprocessor. Others can be negative edge sensitive, e.g. NMI. There is a built in
prioritization of interrupts in case several interrupt requests occur at the same time. There may be more I/O
devices than there are interrupt request inputs to a processor. Several I/O devices may end up sharing a
common interrupt request input. Prioritisation on a shared IRQ line is normally through software. This can
only be done on level sensitive interrupt inputs. Later on we shall show that an edge sensitive interrupt input
can only support one source of the interrupt. Otherwise a deadlock situation could arise.

Memory address decoding normally produces several signals for selecting memory and I/O devices in a
mutually exclusive way. Though derived from the address bus, these signals become part of the control bus.

Bus Request / Bus Grant / Bus Acknowledge: These control signals are not present on all processors. They
allow external bus controllers to take over the three buses from the processor to allow direct high speed data
transfers between memory and mass storage devices like disk drives, magnetic tape, network interface etc.

Different Processor Architectures

Different processors by different manufacturers have been produced throughout the years. The first processors
were predominantly 8 bits on the data bus. Later on, 16 bit, then 32 bit and even 64 bit processors were then
developed. Data word lengths longer than that are possible. Although the basic concepts are the same, there
are differences in detail. A manufacturer would produce a processor which interfaces easily with its range of
input and output devices in the family together with support components and memories. It is possible to mix
components from different families, however, but in some cases this may result in complex glue logic
required to enable them to be interfaced together. Different processors use different machine code and
different assembly languages. Even the way data is stored in memory for larger numbers can be different. We
will see the difference between little endian and big endian data storage in memory. Generally the American
Standard Code for Information Interchange, ASCII is widely used. EBCDIC, Extended Binary Coded
Decimal Interchange Code, is an 8-bit character encoding which was used mainly on IBM mainframe and
IBM midrange computer operating systems.

However, microcomputer systems from different families can talk to each other through standardized
interfaces like the EIA RS232 serial interface. The interface was available on DB25 and later DB9 ports. The
Centronics interface was another early parallel interface commonly used with printers in the old days and was
available through the 25 pin (DB25) parallel port. This is almost obsolete. The USB interface is now common
and is replacing all the other traditional interface types. The USB interface, through physically simple with
only 4 pins, is inherently very complex in its operation. New smarter interfaces are surfacing like Bluetooth
which allow wireless communication between devices but is essentially RS232 in nature.

Microcontrollers and microcomputers are now available with built in Ethernet interfaces which means they be
connected to the internet and communicate through TCP/IP and the associated application protocols. Built in
USB ports are now also part of modern microcontrollers. Later on we shall come across the I2C interface
which simplifies communication between microcontrollers in a factory set up. Again, these are integrated onto
the one chip.

Microchip PIC microcontrollers are also widely used. These are readily available, lower in cost and have free
hardware and software development systems which can be downloaded from the internet. PIC
microcontrollers’ main limitation is the reduced instruction set and a cumbersome system of banks and pages.

47
Chapter Two: Memories and Memory Maps
2.1 Read Write Memories

A read write memory (RWM) also commonly referred to as a random access memory (RAM) is a
memory where data can be written to and read from while power is applied to the system. Read
Write Memories are volatile in the sense that all stored data is lost if power is interrupted. RAM can
be divided into Static RAMs and Dynamic RAMs. Static RAMs, when constructed with CMOS
technology consume zero power in the standby mode while retaining stored information as long as
the supply voltage remains present. Dynamic RAMs require complex periodic refreshing which
increases its power consumption even in the standby mode. A RAM chip has three ports.

 the address input port which selects a memory location for a read or write operation
 the bidirectional data port through which data is written or read in parallel
 the control input port which determines whether a read or write takes place, selection of the
chip and enablement of the data port for read operations.

Figure 2.1(a) shows a block diagram of a memory chip and figure 2.2 shows the pin configuration of
the TC551001 132 kilobyte RAM chip. Figure 2.1(b) shows read and write cycle operations. The
most important timing parameter of a RAM chip is its access time. It is the minimum time from
when the chip has been selected and all its address inputs (and data inputs for write operations) have
stabilised to the time data can be read from or written into the memory chip.

After power is applied to a RAM chip it stores random data. For every memory location, data must
be written to it before it can be read from the same location after each power up.

A write operation begins with the address lines changing to the new value followed by the chip
select signal(s) becoming active. The data lines also change to the value of the byte to be written.
The R/W (or WE) becomes low. After the access time of the chip, the value on the data port will
have been written to the addressed location. WE must be deactivated before the data value is
removed and before the address changes to another value.

A read operation begins with the address lines changing to the new value followed by the chip
select signal(s) becoming active. The R/W (or WE) becomes high. After the access time of the chip
the value on the data port can be read, provided the output enable (OE) control input is active low.
Otherwise the outputs will float in the high impedance state.

48
2.2 Read Only Memories

Read Only Memories are non-volatile. They retain their data even after power has been removed.
There are several different types of read only memory:

 Custom ROM. Here the stored data is fixed during the fabrication of the memory chip and is
used for thoroughly debugged code or specialists applications like the storage of fonts for dot
matrix displays. These are called character generator ROMs or CGROMs. Stored data cannot
be changed. Newer versions of software require completely new replacement chips.
 Bipolar PROMs (Programmable Read Only Memories). These have fusible links just like
FPGAs and FPLAs. A blank (new) bipolar PROM stores all ‘1’s or $FFs. Programming
blows fuses to create ‘0’s. A ‘0’, one programmed by blowing a fuse, cannot be reversed
back to a ‘1’. Special software running on a computer and hardware programmers linked by
an appropriate cable is required to program blank bipolar PROMs. They are OTP.
 UV Erasable Programmable Read Only Memory or EPROMs are the most widely used
ROMs and have a window to allow UV light to shine through to the chip. A new or erased
EPROM stores all ‘1’s. UV erasable EPROMs make use of floating gates (in addition to the
normal gates) on nMOS transistors in the data or the OR plane. This is referred to as
FAMOS. Programming involves trapping or storing charge on the floating gate which makes
the transistor never conduct giving a ‘0’. This normally requires the application of a high
programming voltage ranging from over 12 volts to around 21 volts depending on the design
and type of EPROM. Again software running on the computer and a cable to a special
programmer is required. Once programmed, a black sticker label is placed over the window
to enable stored data to be retained. Erasure involves exposing the entire chip to ultra violet
light of the correct frequency. The created electron hole pairs due to optical means allows all
the trapped charges for all the floating gates in the OR plane to be released. All transistors
now behave normally and revert back to storing all ‘1’s. Erasure is for all stored data bits.
There is no selective erasure of bits. Radiation from the sun for about 12 hours is adequate to
erase an EPROM. but the EPROM tends to get hot in the process, There are specially erasure
boxes on the market using UV lamps which are typically used for EPROM erasure.
49
 EAROMs (Electrically Alterable Read Only Memories) and EEPROMs (Electrically
Erasable Programmable Read Only Memories) commonly referred to as flash do not have a
window but allows the data to be programmed and erased through the use of a special
programmer. They are much more flexible and achieve faster turnaround times during
software development of a new system. The only difference between the variations is the
modes of erasure. Individual locations or blocks of memory can be erased at a time.

All the ROM types discussed above are random access in the sense that memory locations can be
accessed in any order – not restricted to serial access of consecutive memory locations. A large
number of pins are required for the several address inputs and several (typically 8) data outputs and
each chip has a large footprint.

Serial EEPROMs are becoming common using a serial interface with a minimum number of lines. 8
pin serial EEPROMs are now available where the address is sent to the device in series over a data
line. The same data line, synchronised to a clock, is used to write to the chip and a separate line for
reading data from the chip. Access is in serial format, i.e. access of consecutive memory locations for
each block of data read or written. Another random address can be specified for access to the next
serial block. Typically the SPI or I2C interfaces are used for such access.

Like with a RWM chip, there are three ports around a parallel ROM chip. These are the input address
port, the output data port and the input control port. The control port usually has a low active Chip
Enable (CE), a low active output enable (OE) and a programming voltage pin, VPP, to which the
large programming voltage is applied during programming. Some EPROMs have a Write Enable
(WE) control for programming. If the chip is selected (CE = ‘0’) and outputs are enabled (OE =
‘0’), after application of a stable address input, stored data will be available on the data port after the
access time of the memory chip. See figure 2.3. The data outputs will float when either CE = ‘1’ or
OE = ‘1’. During normal operation most EPROMs will have VPP and WE permanently set to 5V by
the PCB wiring, possibly through a pullup resistor.

2.3 Memory Maps

During the design of a microcomputer (a microprocessor based system), once the microprocessor
type has been chosen, the type and size of each memory type must be decided upon including the
type number of input and output devices required. This is determined by the specifications of the
required system. Assuming an 8-bit microprocessor with 16 bit addresses has been selected, a
memory map can be constructed. The positioning of the I/O devices, volatile and non-volatile
memories will be determined by a knowledge of the intricate details of the operation of the chosen
50
microprocessor. With the MC6809 microprocessor, non volatile memory is required towards the end
of the memory address space to accommodate the RESET vector and interrupt vectors. Read
Write Memory is required at the beginning of the memory address space to accommodate ZERO
page addressing. Input and output devices will be allocated space somewhere in the middle. A
typical memory map is shown in figure 2.4 while Table 2.1 is the corresponding memory address
decoding table. The memory map shows the address ranges for the different memory types and input
and output devices.

2.4 Memory Address Decoding

Each address generated by the microprocessor lies in one of the ranges and must result in the
selection of the particular device, and that only, to prevent destructive conflicts on the data bus
during read operations and allow only a targeted device to accept written data during write
operations. Memory address decoding is the process of selecting one device for any 16 bit address
generated by the microprocessor. It processes the higher order address bits to produce the various
chip selects for the different memory and I/O devices. The first step is to construct a memory address
decoding table from the memory map. Address decoding logic is then designed from this table.
Discrete logic consisting of NOT, AND, OR, NAND and NOR gates can be used for address
decoding. Standard off the shelf decoders can also be included in the mix, especially for the I/O
section of the memory address decoding table. The best memory address decoders use FPGAs which
provide for a compact design.

Table 2.1 Memory Address Decoding Table

A15 A14 A13 A12 A11 A10 A9 SELECTED DEVICE


0 X X X X X X RAM CHIP
1 0 0 0 0 X X ACIA_0 CHIP
1 0 0 0 1 X X ACIA_1 CHIP
1 0 0 1 0 X X PIA_0 CHIP
1 0 0 1 1 X X PIA_1 CHIP
1 0 1 X X X X EEPROM CHIP
1 1 X X X X X EPROM CHIP
51
Assume that each of the ACIAs is a Rockwell R6551 with two chip selects: low active CS1 and high
active CS0. Assume that each of the PIAs is a Motorola MC6821 with three chip selects: low active
CS2, and high active CS1 and CS0. I/O devices are allocated memory addresses in the same range as
memories in the memory map. This is called memory mapped I/O and tends to waste memory
addresses and is used in all Motorola systems. Dedicated I/O, which is used in Intel systems
however, has two address spaces. The primary 64 kilobyte address space is for memories and the
other 256 address space is for input and output. I/O devices are referred to as ports. Port addresses in
dedicated I/O are 8 bits with the address range 0 to 255. This system efficiently utilises the available
address space. Control signals are now required to distinguish memory accesses from port accesses.
M/IO.is used and is set to ‘1’ for memory accesses and to ‘0’ for port accesses.

For a chip to be selected, all its chip select inputs must be active. If any one of them is inactive, the
chip will be in standby mode and all its data output drivers will float. Figure 2.5 shows the FPGA
implementation of the memory address decoding which assumes that one low active chip select is
driven from the FPGA output and all other chip selects are activated (or enabled). Only the one
FPGA chip is required and thus provides compact memory address decoding.

Discrete logic in the form of NOT, NAND, NOR, AND and OR gates can also be used but results in
a very large number of small scale integrated circuits to achieve the same effect. See figure 2.6.
52
Address decoding for the RAM chip is trivial. Address line A15 is connected directly to the low
active chip select while the high active chip select is pulled up to 5V through a pullup resistor. The
selection of the other chips is given below. I/O devices have several chips selects, to simplify address
decoding through the use of discrete logic. The fact that some are high active and others low active
enhances the prospects of simple discrete logic for the memory address decoding.

There

When designing discrete logic memory address decoding, it is important to try and use the minimum
number of SSI packages. One 74LS04 HEX inverter chip, one 74LS00 QUAD NAND and one
74LS32 QUAD NOR will suffice for the above example. The OR gate for the EEPROM selection
can be implemented as a NOR gate followed by a NOT gate. There will be several different valid
discreet memory address decoding alternatives for a given memory map.

2.5 Data Organisation and Data Representation

2.5.1 Representation of Alphanumerical Characters.

ASCII, American Standard Code for Information Interchange, is a widely used code throughout the
industry to represent ASCII text. Each alphanumeric character is assigned a unique 7 bit code. The
first 32 codes are referred to as non-graphic characters – they cannot be represented graphically.
Most of these so called control characters are used in data communication while others have specific
effects like backspace, $08 generated by pressing the CONTROL key and the H character at the
same time. Horizontal tab is $09 <CNTRL> Y or the TAB key, BELL is $07 or <CNTRL> G. The
remainder are graphic characters starting with the space character with ASCII code $20. The
numerical digits are assigned codes from $30 through $39. An extended version of ASCII uses the
8th bit to allow graphical symbols and other characters to be represented.

2.5.2 Little Endian and Big Endian representation of integers.

An 8 bit byte (occupying one memory location) can be used to represent either a signed two’s
complement number in the range -128 to + 127 or an unsigned 8 bit number in the range 0 to 256.
Two consecutive bytes are used to represent 16 bit numbers signed or unsigned. Four consecutive
bytes will represent 32 bit numbers while 64 bit numbers require eight consecutive bytes. Big
Endian representation, the most common, is the natural form of representation. The most significant
byte is stored first followed by the other bytes in order of significance till the least significant byte,
the bytes being stored starting at the lowest address and ending at the highest address. This is the
53
format used in Motorola microprocessors and microcontrollers. Little Endian reverses the byte
order and is used in Intel microprocessors and microcontrollers. See figure 2.7 for the representation
of the 64 bit number $A7B35806149C2FED stored in each case (starting) at address $1280.

2.5.3 Intel Hex format

To program an EPROM with desired data, a text file on a computer will hold the EPROM contents
which is downloaded to the EPROM programmer with the EPROM mounted typically on a ZIF
(Zero Insertion force) socket. Typically this text file will hold either Intel Hex format records or
Motorola S format records. Each record occupies one line. There is an end of file (EOF) record at the
end of the file. Each record can represent up to either 16 or 32 bytes of data to be stored. 32 bytes in
a record is the absolute maximum. Such a file can also be used to hold data to be downloaded into
the RAM of a system, e.g. using the serial link or a USB link. It has a number of fields.

Each Intel hex format record begins with the full colon (:) at the beginning of a line. It is followed by
a byte count – made up of two ASCII text characters – each a hexadecimal digit to represent an 8-bit
unsigned binary number. The byte count counts to number of data bytes carried by the record. It is
followed by four ASCII characters, each a hexadecimal digit representing the 16-bit start address in
memory of the data to follow. This is followed by a type byte – ‘00’ represents a normal data
record while ‘01’ represents the end of file (EOF) record. This is followed by the actual data of the
record – as many bytes as specified in the byte count. Each is two ASCII characters – hex digits for
the 8-bit byte. At the end of the record is a checksum byte. It is used for checking the integrity of the
entire record to ensure that there were no transmission errors.

: BCHBCLA3A2A1A0THTLD0HD0LD1HD1LD2HD2L … DNHDNLCSHCSL

The checksum byte is obtained by adding all the data bytes in the record starting with the byte count
followed by the two bytes for the 16 bit address, then the type byte and all the data bytes. The sum is
subtracted from 0. The least significant byte of the difference is the checksum. The receiving device,
if it adds all the bytes in the record should get $00 if there were no transmission errors

The end of file record for Intel hex format is therefore always :00000001FF.

What does the Intel hex format record represent?

:1012800000112233445566778899AABBCCDDEEFF66

In the Intel hex format record example above, the sum of all the binary bytes is $89A. Therefore
the checksum is $00 – $9A which is $66.

54
2.5.4 Motorola S format

Each Motorola S format record begins with the letter S at the beginning of a line. It is followed by a
type character. This is either 1 for a normal data record or 9 for the end of file record. This is
followed by the byte count. This time the byte count counts to number of data bytes carried by the
record starting with the two address bytes and ending with the checksum byte. It is therefore always
three plus the number of data bytes carried by the record. It is followed by four ASCII characters for
the 16-bit start address in memory of the data to follow. This is then followed by the actual data of
the record – as many bytes as specified in the byte count ending with the checksum byte.

STBCHBCLA3A2A1A0D0HD0LD1HD1LD2HD2L … DNHDNLCSHCSL

The checksum byte is obtained by adding all the data bytes in the record starting with the byte count
and ending with the last data byte. The sum is subtracted from -1 or $FFFFFF. The least significant
byte of the difference is the checksum.

The end of file record for Motorola S format is therefore always S9030000FC.

What does the Motorola S format record represent?

S113D28000112233445566778899AABBCCDDEEFFA2

In the Motorola S format record example above, the sum of all the binary bytes is $95D.
Therefore the checksum is $FF – $5D which is $A2.

2.6 EPROM Programming

EPROM programming is usually done by the use of an EPROM programmer receiving downloaded
data from a PC running some program development software. This section looks at what is involved
in programming and verification of programmed data on an EPROM. This allows one to design their
own EPROM programming hardware for a specific EPROM if the programming specification is
available. Consider the programming of the M27128 EPROM. Figure 2.8 shows a block diagram of
the programming set up. An address latch provides the address to the EEPROM while a data latch
drives the data pins which are now inputs. The control port consists of VPP, CE, OE and PGM.
During normal operation, CE and OE are low, PGM high and VPP at VCC. During programming, CE
is low, OE high, VPP at 12.5V and PGM is pulsed for 1 ms. VCC is raised to 6V. That causes the
addressed memory location to be programmed with the data applied to the data pins. See figure 2.8.

55
Chapter Three: Input and Output Devices
3.1 Overview of the Serial Interface

The RS232 serial standard was developed in the 1960s to allow two devices to communicate over
long distances with a minimum number of wires. Originally, it was supported on a DB25 connector
and later on a DB9 connector. It was widely used to connect computers to peripheral devices like
plotters, printers, scanners etc. It is being widely replaced with the much more versatile USB port.
While TTL levels, i.e. 0V and 5V are used on a logic board of a computer or peripheral devices,
RS232 uses +12V and -12V as the two voltage levels to increase noise immunity when transferring
data over long distances. 1488 and 1489 line drivers and line receivers were used in the early days of
its implementation. In the mid to late 1980s, the MAX232 chip was introduced to simplify its
implementation requiring just one 5 volt supply as compared to +/- 12V required by the earlier chips.
The line drivers and receivers are inherently inverting. 0V is converted to +12V while 5V is
converted to -12V and vice versa through the line drivers and receivers. See figure 3.1. The
MAX232 chip, however, uses +10V and -10V which is generated internally through switching.
Signal attenuation reduces signal strength but can be correctly recovered if more than 3V magnitude.
Below 3 volt magnitude, the output of the line receiver becomes unpredictable.

An RS232 link has two types of signals – data signals and handshake signals. The two data signals
are transmit data (TxD) and receive data (RxD). All the other signals are handshake. See figure 3.2.

56
3.2 Character Frames

Data signals idle at a TTL logic ‘1’ (i.e. -12V on the RS232 side). The RS232 interface is an
asynchronous interface in the sense that each character frame transmitted is self synchronising
through the use of a start bit. Data is transferred at a predetermined data bit rate (commonly referred
to as the baud rate). The data bit rate determines the duration of a bit on the data line - T. A
character frame begins with a start bit – a ‘0’ of duration T followed by the data bits of the character
to be transmitted, each of duration T. The least significant bit (LSB) is transmitted first and the most
significant bit (MSB) last. This is followed by the optional parity bit followed by the stop bits. There
can be 1, 1.5 or 2 stop bits depending on the configuration. Odd or Even parity may be used as
determined by the configuration. The number of data bits varies between 5, 6, 7 and 8 bits per
character and is also a configuration parameter. A number of industry standard baud rates are used:
110 bps, 300 bps, 600 bps, 1200 bps, 2400 bps, 4800 bps, 9600 bps and 19200 bps. The two ends
of a serial link must operate with the same configuration parameters. Some systems use a bank of
DIP switches to allow the installer the ability to configure the parameters of a serial link so it
matches the configuration on the other end of the link. Figure 3.3 shows to scale, two different
character frames for transmitting the two ASCII characters: ‘6’ ($36) and ‘I’ ($49) using 7 bits per
character, even parity and 2 stop bits. The top timing diagram is for the TTL side while the bottom
one is for the RS232 side. A character frame begins with the start bit and ends with the last stop bit.

Transmission errors can result in a Parity Error. Simple parity can only detect an odd number of
erroneous bits. Too many parity errors detected on a line is an indication of excessive noise from an
interference source. Reducing the data bit rate can reduce the error rate significantly. A Framing
Error occurs when one or more expected stop bits are missing. This can be a result of mismatched
data bit rates or transmission errors. It could also arise if the local oscillators on opposite ends of the
link have a large mismatch. The two local oscillator frequencies must be equal within certain limits.
The break character is a special character where all the data bits of the character frame are all 0s.

57
3.3 Handshaking Signals

A handshake signal is active or ON when it is at +12V and is inactive or OFF when it is at -12V.
Handshake signals are mainly used to control the flow of data between a sender and a receiver. It is
possible to connect two devices through a serial link directly with the use of a short cable. The
minimum number of wires required in the cable is 3. A signal or logic ground reference, the TxD and
RxD lines. TxD and RxD lines are crossed over to make what is called a NULL modem cable. See
figure 3.4(a). Most configurations make use of one or more handshake signals in addition to the 2
data lines. Again these would be crossed over. Figure 3.4(b) shows a link which uses two handshake
signals. To ensure there is communication, unused handshake inputs should be set to ON.

3.4 Flow Control

When a fast data sender, typically a computer, interfaces with a slow data receiver, e.g. a printer, it is
possible for the receiver to be overwhelmed with data. This could happen, for example, if its internal
buffer fills up. A method is required to control the flow of data so that none of it is lost. This is called
flow control. Software handshaking uses the three wire link in figure 3.4(a). When the receiver is
no longer able to receive more data, it sends back a transmit OFF character (XOFF) which is DC1 or
$11. When it is able to receive more data it sends back the transmit ON or XON character which is
DC3 or $13. This is referred to as in band flow control or software flow control.

Hardware handshaking on the other hand requires at least one handshake signal as depicted in
figure 3.4(b). Here, the state of a handshake signal informs the sender whether it is clear to send data.
A computer or printer is referred to as data terminal equipment or DTE. DTR or Data Terminal
Ready is used by the printer to inform the computer through its CTS or clear to send input whether it
can or cannot send data. DTR is ON when the printer can accept data and is OFF when it becomes
busy. This is out of band flow control.

3.5 Rockwell R6551 ACIA (Asynchronous Communications Interface Adapter)

A microcomputer will have a chip which handles the transmission and reception of serial data
through a serial link. Such a chip is referred to as an asynchronous communications interface adapter
or ACIA. The Rockwell R6551 ACIA is an advanced ACIA with several advantages over similar
chips like the Motorola 6850 ACIA. Figure 3.5 is a block diagram of the R6551 ACIA while figure
3.6 is a chart which summarises its configuration and programming. Between the chip and the
physical hardware interface is the MAX232 chip for level conversion because the chip only uses
TTL voltage levels. See the right side of the diagram. The chip interfaces to the controlling processor
through the address bus, data bus and control bus as depicted on the left side of the diagram.

One significant advantage of the Rockwell ACIA is that an external crystal is used to determine the
data bit rates on both the transmitted data line and the received data line. The table in figure 3.6
applies to an external crystal of frequency 1.8432MHz. It is possible to drive the ACIA with a 3.6864
MHz or a 7.3728 MHz crystal. From the table, the resulting baud rates would have to be multiplied
by factors of 2 or 4 respectively. Other ACIAs (like the Motorola MC6850 ACIA) requires an
external TTL clock to be fed into the ACIA and there is limited flexibility in baud rate selection. A
complex external clock circuit with the respective multiplexers and DIP switches are required to
allow the ACIA handle the different industry standard data bit rates to enable it to be able to
communicate with other serial devices. However, it can easily interface with Motorola and other
manufacturers’ microprocessors through the standard data and control buses.
58
The Rockwell ACIA features double buffering on both the receive side and the transmit side. All the
handshake signals on the right of the block diagram are TTL level, which means that they are all low
active. When a handshaking signal is low, the corresponding signal on the RS232 side will be ON or
at +12V. This is why all the handshake signals have a bar over them.

59
Figure 3.6 Rockwell R6551 ACIA Configuration and Programming

The chip has two select control inputs, the low active CS1 and high active CS0. Both select controls
must be active for the chip to be selected. This is done by the memory address decoding circuit. If
deselected, the chip will be in the standby mode with a floating data bus. In addition to that, two
register select input lines RS1 and RS0 determine which of the five internal registers is selected
during a read or write operation as determined by the state of the R/W control signal. Normal designs
have address line A1 connected to RS1 and address line A0 connected to RS0. This allows the
primary addresses of all the internal registers to be determined for each ACIA in a microcomputer.
Determine the primary 16-bit addresses of all the internal registers of the two ACIAs in the memory
map of chapter 2. One thing to note is that each internal register can be addressed by several
addresses within the I/O address range of the ACIA. These are referred to as secondary addresses or
aliases. This is why memory mapped I/O wastes addresses when compared to dedicated I/O. The
status register is read only and so is the receive data register RDR. RDR, the received data register
shares the same address as the transmit data register, TDR. It is the state of the R/W control bit
which determines which register is accessed.

The ACIA has one open drain interrupt request output, IRQ, which is a summary of all the
conditions within the ACIA which requires special attention of the controlling microprocessor. Open
drain interrupt outputs allow several such requests to be connected together to one interrupt request
input of the processor which must interrogate these ACIAs in some predetermined order or priority.
60
3.6 ACIA Receiver Operation

After a hardware RESET or programmed RESET, the ACIA is ready to receive data from the serial
link. From the RxD line, serial data is converted into parallel form in the receive shift register. The
incoming start bit is used by the receive control to synchronise to the incoming character frame. This
is then transferred into the Receive Data Register (RDR). This causes bit RDRF (receive data register
full) bit in the Status Register to be automatically set by the hardware. The processor must read the
received data from the RDR after discovering that bit RDRF has been set by reading the status
register. This two step process, reading the status register with RDRF set, followed by a read of the
RDR will clear the bit in the status register. There are two ways the processor will know that bit
RDRF in the status has been set. The first is polling, where the processor polls, or periodically
checks the status register by reading it. The second is to use interrupts. The moment the bit RDRF is
set in the status register, and if the corresponding receiver interrupt is enabled by configuration, an
interrupt is generated. First bit IRQ in the status register is set to indicate the interrupting condition.
This causes the pull down transistor of the O/D IRQ output to turn ON thus interrupt the
microprocessor. Interrupt processing then takes place. When RDRF is cleared, IRQ is cleared at the
same time assuming there are no other conditions which have enabled interrupts within the ACIA.

If a second character is received through the receive shift register before the first character, now in
the RDR, has been read by the processor, the second character is lost – cannot be transferred to the
full RDR. This condition is a character overrun and results in the bit OVRN being set in the status
register. PE and FE are also set in the status register with each received character if a parity error or a
framing error is detected by the receiver hardware respectively. If interrupts are used to receive data
from a serial link, it is unlikely there will be character overruns. When polling is used, there is no
guarantee that character overruns will not occur. In the design of a system, careful decisions have to
be made as to which I/O operations are polled and which make use of interrupts.

If interrupts are used to receive characters coming in through the serial link, a circular buffer, or
FIFO (First In First Out) queue, is normally used by the interrupt service routine to save received
data. This is a reserved area of memory in RAM which operates with two pointers, head and tail.

3.7 ACIA Transmitter Operation

After a hardware RESET or programmed RESET, the two transmitter registers will be empty and the
bit TDRE (transmitter register empty) will be set. This bit being set, if its interrupt is enabled, will
generate an interrupt. Normally this transmitter interrupt is disabled because data cannot be lost as
the local processor is in charge of transmitting data. To transmit data, the local processor first checks
this bit, TDRE, and only writes a byte to the transmit data register, TDR, when the bit is set.
Immediately the byte is transferred to the transmit shift register. TDRE is set again. The processor
can write a second byte to TDR which cause the bit TDRE to be cleared. The processor cannot write
a third byte then since TDRE will be clear. When the first byte’s transmission is completed, the
second byte is transferred to the transmit shift register and TDRE is set. Only then can a third byte be
written to TDR which causes TDRE to be cleared again. So data cannot be lost because the system or
user program will ensure no writes to TDR while TDRE is set.

CTS, the incoming handshake signal, when inactive at ‘1’, will cause the transmit control to prevent
the transmit shift register from sending the stored character out the TxD line. Normal transmitter
operation can also be affected by the special receiver echo mode – the transmitter will then transmit
on the TxD line whatever is received on the RxD line in this mode.
61
3.8 Command and Control Registers

The two registers are the only ones which can be written to and also read from. Typically they are
written to only once during start up and have values which remain unchanged while the system is
running. However, if flow control is implemented by using the data terminal ready output handshake
line, DTR, then this register can be changed regularly to inform the remote sender as to when to send
data. The control register is used to program the configuration of the serial link. This is the number
of bits per character or word length, the data bit rate, the number of stop bits and the source of the
receiver clock which can be derived from the internal baud rate generator or an externally applied
TTL clock. The command register determines the parity mode of operation selecting between odd,
even, mark, space or no parity. It is also used to determine if and when interrupts are used on the
receiver or transmitter sections. The receiver echo mode is also selected through this register. The
state of the two outgoing handshake signals: DTR and CTS are also programmed through this
register.

The state of the two incoming handshake signals DCD (Data Carrier Detect) and DSR (Data Set
Ready) is reflected in bits 5 and 6 of the status register respectively. While the other interrupt sources
from the receiver and transmitter can be disabled, changes in the levels of either DCD or DSR
always results in the bit IRQ being set and a hardware interrupt being generated by the pulling down
of the pull down transistor of the IRQ output. This allows the local processor to manage flow control
when it is acting as a transmitter of data to another remote system.

3.9 Managing Several ACIAs on one hardware interrupt line

Figure 3.7 depicts a situation where three ACIAs interrupt a controlling processor through the same
interrupt input line. When an interrupt occurs, the processor has to establish which ACIA caused the
interrupt and why. It does this by reading the status register of each ACIA, in a predetermined order,
which establishes the assigned priority. By testing the IRQ bit of the status register of an ACIA the
processor is able to determine whether to further interrogate that ACIA by checking the other status
bits. RDRF would be checked first, to try and minimise the remote possibility of a character overrun.
It then services the interrupt by taking appropriate action, e.g, reading the receive data register and
saving the read byte etc. After checking all three ACIAs, the processor returns to resume what it was
doing before being interrupted.

62
3.10 Circular Buffers
A circular buffer (also called a FIFO or First In First Out queue) is an area of memory reserved in
read write memory for storing values from one process which will be removed by a different process.
A good example is a slow printer receiving characters from a fast computer. Characters are received
in sequence through the serial link and then saved in the queue. The printing process must retrieve
the characters in the order in which they were received. The buffer has start and end addresses which
we will call buffer_start and buffer_end and will have a fixed buffer_size, i.e.
buffer_end – buffer_start + 1. Two pointers are used to maintain a circular buffer and
these are head and tail. These point to the item at the front of the queue, if it is not empty, and the
first free empty slot immediately after the last item of the queue respectively. Figure 3.8 shows three
different scenarios of the same buffer with stored data.

To initialise the buffer, the two pointers head and tail are normally made equal to
buffer_start, typically during system start up. Setting them equal to any address within the
address range of the buffer will also work. The condition head equals tail therefore represents an
empty buffer. The process responsible for putting characters into the queue (enqueue operations) will
use the tail pointer as an address to use for the storage – assuming the buffer is not completely full.
Typically this will happen each time a receiver interrupt occurs as a result of the receive data register
becoming full. Immediately after this storage, the tail pointer is updated for the next enqueue
operation. This is by incrementing the tail pointer to the next address. However, if the updated
pointer becomes greater than buffer_end, it is immediately set to buffer_start. This is referred to as
wrap around. The process responsible for removing characters from the queue (dequeue operations)
will use the head pointer as an address to read from the buffer. This only occurs as long as the queue
is not empty. Typically this will be the printing routine. Immediately thereafter, the head pointer is
updated for the next dequeue operation. Again, the head pointer is incremented. Again the head
pointer is initialised to buffer_start if it becomes greater than buffer_end. The two pointers therefore
chase each other around as data items are enqueued into and dequeued from the buffer.

A completely filled buffer corresponds to head being equal to tail with all the memory locations
filled up with enqueued data items. This must be avoided at all costs as there is no way of
distinguishing a completely filled buffer from an empty buffer. Typically the process responsible for
enqueue operations will handle the flow of data items from the sending entity. It can send XOFF
when the buffer exceeds a predetermined value or deactivate data terminal ready (DTR).
63
3.11 Current Loop

Due to attenuation, the length of an RS232 cable is limited. At 19 200 bps, the maximum cable
length is about 15 m, or when the capacitance of the cable is 2 500 pF. Reducing the data
transmission rate allows an increase in the cable length. Normal RS232 generates a standard voltage
of +/-12V or +/-10V at the transmitting end. Attenuation due to cable resistance reduces signal
strength. Attenuation is more pronounced and get worse with an increase in the cable length. If the
received signal has an amplitude less than 3 volts, there is no guarantee the received signal will be
recovered correctly. The use of a current loop interface can be used to increase the cable length
considerably and at the same time increase the noise immunity of the serial link. Figure 3.9 shows
the circuit diagram of a current loop which includes the sending end and the receiving end of the
serial link.

When the TxD line is at a logic ‘1’, the input diode of the transmitter optocoupler is OFF and the
corresponding phototransistor is OFF. No current flows through the twisted pair line. The diode of
the optocoupler on the receiving end is also OFF and its corresponding phototransistor is OFF and
hence the RxD line is also a logic ‘1’ at the receiver. Since the TxD / RxD line idles at ‘1’ in an
RS232 interface, this is good, because when idling no current flows through the twisted pair line and
this conserves power.

When the TxD line is ‘0’, current (about 4 mA) flows through the input diode of the transmitter
optocoupler. This turns on the corresponding phototransistor. The voltage of node A rises towards 12
volts and drives a current of between 45 mA and 50 mA. This current flow round the twisted pair
line. The voltage of node B is that of node A less the potential drop across the resistance of the I+
line. Enough current flows through the input diode of the receiver optocoupler to switch on the
corresponding phototransistor, which saturates. The RxD lines falls to the collector emitter saturation
voltage of about 0.2 volts and becomes a logic ‘0’. So RxD is always the same as TxD.

The transistor parallel to the input diode has the role of shunting excess current away from the diode.
This base emitter junction of this transistor is driven by the potential drop across the 27resistor. To
get the 0.7 volts required to turn on the base emitter junction, a current of 25 mA is required. This
becomes the maximum current through the diode of the optocoupler of the receiver.

64
3.12 The Motorola MC6821 PIA (Peripheral Interface Adapter)

Another commonly used I/O component in a microcontroller is the Motorola MC6821 PIA or
Peripheral Interface Adapter. It is used to interface to parallel buses and provides a lot of input and
output pins for the monitoring and control of an embedded control environment. It can be used to
read a bank of DIP switches during system start up to determine various operational configurations,
e.g. of the serial link. It can be used to interface to LCD Matrix Displays, Analogue to Digital
Converters, Digital to Analogue Converters or individual control points in a process.

65
It can also provide the required buffering of addresses and data for the control of the programming of
EPROMs. Figure 3.10 is an internal block diagram of the PIA while figure 3.11 is a summary of how
it can be configured and programmed.

Like with the R6551 ACIA it interfaces with the controlling processor through the data bus and a
control bus as shown on the left of the diagram in figure 3.9. It interfaces with the monitored and
controlled environment through two ports: PortA and PortB (each 8-bits) on the right of the diagram.
It has three chip select signals, one low active CS2 and two high active CS1 and CS0. Two register
select inputs RS1 and RS0 are used to select the internal configuration and data registers for reading
and writing as is determined by the state of R/W during a bus cycle. RS1 and RS0 are driven by the
buffered address lines A1 and A0. This means that the addresses of the different addresses for all the
internal registers for the earlier memory map for the two PIAs can be worked out. Again, there are
primary and secondary addresses for each register and a lot of wastage of address space.

The PIA is divided into 2 sections: the A side and the B side, which are almost identical in terms of
operation with minor differences. Two bits CRA2 or CRB2 in the respective control registers are
used for addressing – selecting either the Data Direction Register (DDR) or the data or peripheral
register. Each side has its own separate low active open drain interrupt request output and control
register. Each control register has two interrupt flags.

Figure 3.11 Configuration and Programming Summary for the MC6821 PIA

Each port pin can be configured independently of the others on a port as an input or output by its
own bit in the respective data direction register. The two data direction registers are cleared by a
hardware reset so that all ports pins default to inputs to prevent potentially destructive conflicts.
66
Figure 3.12 CA1 (CB1) and CA2 (CB2) handshaking summary for the MC6821 PIA

Control bits CRA2 and CRB2 are also cleared by hardware reset to allow for the configuration of
data direction registers once followed by repeated access to the peripheral registers thereafter. All the
pins of a port can be configured as inputs or outputs together to allow for interfacing to a parallel
bus. CA1 (CB1) and CA2 (CB2) are additional pins for general purpose I/O or can be used for
handshaking to control the flow of data through parallel ports to or from external devices.

67
3.13 PIA Configuration and Operation

Hardware RESET clears all the internal registers. This means that all port pins on the two ports are
configured as inputs since both data direction registers a cleared. A ‘0’ in a data direction register
configures the corresponding port pin as an input while a ‘1’ configures it as an output. A read from
a peripheral port will read the input ports for pins programmed as inputs. For pins programmed as
outputs, the output register bit is returned (i.e. the current output state of that output pin) if it not
overloaded (excessive fan out) such that the voltage levels lie outside the prescribed range. On
overloaded PORTA outputs, the actual value on the pin is returned and will differ from the value
programmed in the output register. PortA inputs have an internal weak pullup meaning if not driven
will default to ‘1’.PortB on the other hand have tristate outputs which are enabled for pins configured
as inputs. PortB outputs can be used to source and drive more than 1 mA to drive the base of a
bipolar transistor. Reads from PortB outputs return what was written to the output register.

CA1 and CB1 are peripheral inputs which can generate an interrupt if the programmed edge occurs.
CA2 and CB2 may be configured independently as inputs or outputs through data direction register
bits (CRA5 and CRB5) in respective control registers. When programmed as inputs, they behave
exactly as CA1 and CB1, i.e. a programmed edge will generate an interrupt. When programmed as
outputs, they are used in handshake modes of operation to allow for the orderly flow of data through
the parallel port (inputs for PortA and outputs for PortB) to and from an external device. Figure 3.11
summarises the handshake operation. Each of CA1, CB1, CA2, CB2 has its own interrupt flag in the
control register. The flag is set on the active edge (when configured as input) or when specific events
occur when programmed as an output handshake. When the corresponding interrupt enable bit is set,
an interrupt will occur on the corresponding IRQ open drain output line. Each section has its own
separate open drain interrupt request output line.

Operation of input only CA1 and CB1 control lines is simple. If CRA0 or CRB0 is clear (as soon
after a hardware reset), interrupts from the respective control input are disabled. If the bit is set, then
interrupts are enabled. In either case the flag will be set by the programmed edge. CRA1 and CRB1
determine the edge which sets the flag (and may cause an interrupt if enabled). A ‘0’ selects the
falling edge as the active edge while a ‘1’ selects the rising edge as the active edge.

Operation of CA2 and CB2, when configured as inputs by clearing CRA5 and CRB5 respectively,
results in behaviour is similar to that described above. This is the default mode after a hardware
reset. Then, when CRA3 or CRB3 are cleared, corresponding interrupts are disabled. If they are set,
corresponding interrupts are enabled. In either case the flag is set whenever the programmed edge
occurs. If CRA4 or CRB4 are ‘0’ the falling edge is the active edge while if CRA4 or CRB4 is ‘1’,
then the rising edge is the active edge which causes the flag to be set (and may generate an interrupt
if enabled).

Operation of CA2 or CB2 as outputs is complex. This is when CRA5 or CRB5 is set to ‘1’. This
selects the complex handshake modes. Their operations on A and B sides are very different then.

CA1 and CA2 operate as handshake signals in opposite directions to manage the flow of parallel data
from an external device to the PIA through PortA. The two basic modes are a pulsed mode and an
interlocked mode. CB1 and CB2 also operate as handshake signals in opposite directions to manage
the flow of parallel data from the PIA through PortB to an external device. Again, there are two basic
modes: a pulsed mode and an interlocked mode. See the timing diagrams of figure 3.11 for the
different modes. The concept of handshaking is described next. See diagrams overleaf.
68
3.14 Handshaking

Figure 4.13 shows a data source connected to a data receiver where bytes are transferred through the
use of two handshake signals, a transfer_request and a transfer_acknowledge.
Assume that when no transfer is taking place both handshake signals are idling at ‘0’. A data transfer
normally begins with fresh data appearing on the bus. The source activates transfer_request. If the
receiver is able to accept the data it will respond by activating transfer_acknowledge. If it is unable
to accept fresh data because it is busy internally, e.g. local receive buffer is full, then it keeps the
acknowledge signal unchanged until the busy condition clears. The source will then deactivate its
request line and the receiver, upon capturing the transferred byte will also respond by deactivating its
acknowledge line and the transfer is complete. The interface is ready for the next transfer. If the
source has another byte to transfer, it will activate its request line and the cycle repeats. Note that
sometimes, the polarity of the request handshake signal or the acknowledge handshake signal can be
complemented.

Figure 4.14 shows the operational configurations of the handshake controlled byte transfers through
the PIA ports, PortA and PortB whose timing diagrams are given in figure 4.11.

Finally, the internal circuit configuration of Port A and Port B peripheral circuitry in figure 4.15.

69
Chapter Four: The Motorola MC6809 Microprocessor
4.1 Processor Structure

A processor is at the heart of a microprocessor based system. This course considers 8-bit
microprocessors with 16 bit address buses. This means the microprocessor can address a maximum
of 64 kilobytes of memory and input and output devices. The MC6809 microprocessor will be used
as an example because it is one of the most powerful 8-bit microprocessors ever developed. A
processor fetches instructions stored in memory and executes them, accessing information from input
and output devices and memory. The course will look at the von Neumann architecture of a stored
program computer. A stored program, either in volatile or non-volatile memory consists of a
sequence of instructions. Each instruction is a series of bytes stored in consecutive memory
locations. Figure 4.1 is a block diagram which shows the generic structure of such a processor.

The power of a processor is determined by the number and function of its internal registers. It is also
dependent on the addressing modes available and the entire instruction set. The MC6809
microprocessor has a very powerful instruction set with a wide variety of addressing modes,
especially through its indexed addressing mode. Instructions fetched by the processor must specify
the source and destination operands. It must specify which arithmetic or logical operation is to be
performed. It must specify the destination of the result and the address of the next instruction to be
performed. The latter is normally stored in a special register for addressing instructions called the
program counter register (PC). One or more of the source operands will be on-chip registers.

70
Accumulator registers are present on-chip for this purpose and the number of such registers
determines the processor’s power. The processor goes through an infinite sequence of fetching and
executing instructions which comprise the following five steps:

 fetch the opcode, the first byte of the next instruction using the address stored in the program
counter, and immediately update the program counter so that it points to the next instruction
or the next byte of the same instruction. Program Counter update is normally an increment
operation. That first byte of an instruction is called the operation code or OPCODE and is
unique among the processors’ instructions.
 decode the instruction (a function of the control unit).
 fetch one or more operands as required by the instruction (updating the program counter
where necessary).
 perform the specified arithmetic, logical or other operation.
 store the result as required by the instruction and update the status register which stores the
five arithmetic status flags. This register is also commonly referred to as the condition code
register (CCR). Note that selected instructions do not save the result but use the result to
update the status flags. After the fifth and last step, go back to the first step and fetch the next
instruction using the program counter contents.

Note that after the fifth step and before going back to the first step, the processor checks for pending
and enabled interrupts. If there are, then interrupt processing takes precedence over the fetching of
the next instruction.
4.2 The Control Unit (Control Path)
The control unit is central to the operation of the processor. It is driven by an external piezo electric
crystal whose frequency determines the speed of operation of the processor. The crystal frequency
drives an internal oscillator and divide by 4 counter to produce two free running clocks E and Q. All
bus operations and internal operations are related to these clocks. The control unit has internal and
external control inputs and outputs. The status flags in the condition code register are part of the set
of internal inputs to the control unit. The control unit is one giant finite state machine or FSM
controller. After directing the fetch of the next instruction opcode from memory using the program
counter contents, the fetched opcode is stored in an instruction register, IR. This directs the controller
to generate a series of micro-operations to produce the effect required by the fetched instruction. It
selects or directs the fetching of the required source operands. It produces the correct function code
for the ALU which performs the specified arithmetic or logical operation. It directs the storage of the
results and the update of the status flags. Its operation is also linked to the interrupt request inputs.

4.3 Internal Registers


One or more data accumulator registers are found on every processor. Most instructions use an
accumulator register as one of the source operands or the destination of the result or both. The
condition code register (also the status register) stores the arithmetic status flags to reflect the result
of an operation. These are ZERO (Z), SIGN or NEGATIVE (N), OVERFLOW (V), CARRY (C) and
HALF CARRY (H). They also store interrupt masks used to enable and disable interrupts. The
Program Counter contains the address of the next instruction, meaning instructions are normally
executed in sequence as they are stored in consecutive memory locations. The hardware stack pointer
register is used to maintain the hardware stack for storing return addresses and the processor state
(i.e.) the values of all or selected registers during interrupt processing and for handling subroutines.
71
Additional stack pointers may be available for maintaining additional stacks. Each register will have
a specialised function as its primary role but may also have secondary functions of a general nature.
The collection of the set of values of all the internal registers is called the processor state.

One or more index registers are available with the indexed addressing mode(s) to allow support of
complex data structures and repetitive processing. There are also temporary registers available for
use by the control unit which the user or programmer is not aware of and does not have access to. A
good example is the memory address register (MAR) which is commonly used when an instruction
requires access to an external memory location during the operation of an instruction. There may also
be temporary data registers.
4.4 A Stack
A stack is a LIFO (Last In First Out) data structure which occupies space in read write memory. A
stack pointer register is central in the operation of the stack. A stack should be an open ended area of
memory without limit. In practice a finite amount of memory is available or reserved for the stack.
The stack pointer register must be initialised to point to the bottom of the stack. That initialisation of
the stack pointer register creates an empty stack. A specific memory location and address is selected
for this. Data items (8-bit or 16 bit) are saved on top the stack by push operations. Data items are
retrieved from the top of the stack by pop or pull operations. The first data item to be pushed onto
the stack is the last data item to be pulled from it. Push and pull operations make use of the contents
of the stack pointer register to provide addresses for memory accesses. The stack will only overflow
if it encroaches and overlaps with other data stored in the memory with catastrophic results. A stack
underflow occurs when one tries to retrieve more data items from the stack than was saved on it.
This should never happen with carefully designed structured programs. There are four different
methods of organising a stack. The stack can grow from lower memory addresses towards higher
memory addresses. The stack pointer can point to the top data item on the stack, or to the next free
memory location on top of the stack. Figure 4.2 shows MC6809 microprocessor stack operations for
a stack that grows towards lower memory addresses and where the stack pointer points to the data
item on top of the stack. Initialisation of the stack pointer therefore points to a memory location just
outside (higher than) the stack space. The stack pointer register is conveniently initialised to $8000
so that it grows towards $0000. Data and programs in such a system must be allocated space
starting at $0000 growing towards higher addresses. Note that push operations of 16-bit data results
in it being stored in big endian format – the most significant byte is always stored in the lowest
memory address. The lower byte is pushed first then the upper byte is pushed last.

Every microprocessor has a hardware stack. It is used for interrupt processing. It is also used for
supporting subroutines. The stack pointer must be initialised before interrupts occur or are enabled
72
after power on RESET or subroutines are called by a user program or a software error occurs. Note
that after pull operations, the data items above the stack pointer remain in their places in memory but
cannot be accessed with normal stack operations. They may be accessed through indexed addressing.

4.5 Programmers Model

A programmers model for a microprocessor is a chart of the registers of the microprocessor which
the programmer has access to. It can also show the bits and their positions within selected registers.
Figure 4.3 is the programmers model for the MC6809 microprocessor.

There are five 16 bit registers: The Program Counter, The Hardware System Stack Pointer and User
Stack Pointer registers and the two index Registers IX and IY. There are two 8-bit accumulator
registers: ACCA and ACCB. The two registers combined form the 16-bit double accumulator
register ACCD with ACCA being the most significant and ACCB the least significant. The Direct
Page register is unique to the MC6809 microprocessor allowing the short and fast direct addressing
mode to be used throughout the 64K address space. The Condition Code register has the five
arithmetic flags and two interrupt masks and an ENTIRE flag E.

4.6 Processor Instructions


A processor will have instructions for moving data from a source to a destination. Load involves
moving a data item from memory or an I/O device into a register through a read into the processor.
Store, on the other hand, writes a data item from the processor to an I/O device or memory.
LOADS: ACCA := immediate value (constant); ACCB := memory(IX)

STORES: memory(address) := ACCD; memory(IY) := IX


73
MOV or move is the terminology used with Intel microprocessors for data movement. IN and OUT
is used to denoted data movement to a from input and output ports.

There will be instructions for performing arithmetic and logical operations. Multi-precision
arithmetic is supported by supporting additions and subtractions which involve the carry flag (C).
Complex operations like multiplication and division can be invoked by individual instructions.
There will be instructions for altering the flow of instruction execution. Normally instructions are
executed in the sequence they are stored in memory. Program Control Instructions alter this flow by
jumping or branching to a different instruction stream. Subroutines jumps and branches are allowed.
A subroutine is a predefined sequence of operations that can be invoked (called) by a single
instruction. It may or may not have input and output parameters. Subroutines are like functions in the
programming language C. Jump instructions transfer control to a specific 16-bit address. Branch
instructions on the other hand are relative to the current position or address in the program counter.

There are a set of instructions which perform an arithmetic or logical operation where the result is
not stored but is used to update the status flags. This is typically followed by a conditional branch
instruction. This allows the program to make decisions on the flow of the program depending on
conditions which arise during program operation. A TEST instruction subtracts ‘0’ from a register or
a memory location but does not store the result. A COMPARISON instruction performs a subtract
operation without storing the result. A BIT instruction performs an AND operation without storing
the result. There are signed and unsigned comparison instructions in an instruction set. Signed
comparisons treat the two data items being compared as signed two’s complement numbers.
Unsigned comparisons treat the two numbers as unsigned positive numbers. The terms Greater than,
Greater than or Equal, Less than, Less than or Equal refer to signed comparisons. Higher, Higher or
Same, Lower, Lower or Same refer to unsigned comparisons. For example: $BD is higher than $32
but $BD is less than $32.
There are instructions for clearing registers or memory locations (loading ‘0’), for incrementing or
decrementing registers or memory locations (adding or subtracting ‘1’). Instructions exist for logical
and arithmetic shifts to the left and to the right and for rotate operations through CARRY or
bypassing CARRY. Instructions set and clear individual status flags.

4.7 MC6809 Addressing Modes


There are 6 main addressing modes in the MC6809 Instruction set:

 Implied or Inherent addressing (use of on chip registers)


 Immediate addressing (both for 8-bit and 16-bit immediate data or constants)
 Direct addressing (which uses the Direct Page Register DP for short and fast external access)
 Extended Addressing which specifies a full 16-bit address of an external operand
 Relative addressing for short and long branches with signed two’s complement 8-bit and 16-
bit offsets.
 Indexed Addressing which uses the Stack Pointer and Index Registers. Indexed addressing
allows access to more sophisticated addressing modes like indirect addressing. It also allows
pre-decrement and post-increment instructions allow two additional stacks (with IX and IY
as stack pointer registers) for a maximum of four possible stacks to be supported. The User
and hardware stack pointers can also be used as index registers resulting in very powerful
processing capability.

74
The effective address (EA) of an instruction is the address of the source or destination operand in
memory.

These very powerful addressing modes allow the MC6809 microprocessor to support complex data
types for the implementation of high level programming languages.
4.7.1 Inherent addressing
Inherent addressing does not require memory accesses. The source and destination operands are on
board the microprocessor. They tend to be short and fast. They should be used in preference to the
other addressing modes wherever possible.
4.7.2 Immediate addressing
In immediate addressing, the source operand immediately follows the opcode in memory. Immediate
operands can be 8-bits or 16-bits. They can be considered to be constants. The effective address with
immediate addressing is the address of the first byte of the immediate constant after the opcode in
memory. Immediate addressing operands are preceded by the hash ‘#’ character in assembly
language instructions. The upper byte comes first after the opcode followed by the lower byte with
16 bit immediate instructions.
4.7.3 Direct addressing
With direct addressing, the lower 8 bits of the address of the operand immediately follow the opcode.
The upper 8-bits are in the Direct Page register. The 64k address space can be divided into 256
pages. The page number is the upper 8-bits of the 16-bit address. The address within a page is the
lower 8-bits and these are specified with the instruction. They tend to be short requiring fewer bytes
when compared to the equivalent extended addressing mode. The effective address therefore is the
concatenation of the direct page register contents and the 8-bits specified in the instruction. With
processors without the direct page register, this form of addressing is only available in page ZERO –
zero page addressing. Page ZERO holds the first 256 bytes in the 64 kilobyte address space.
4.7.4 Extended addressing
With extended addressing, the full 16-bits of the address in memory immediately follow the opcode.
This becomes the effective address. This mode is slower and requires more memory when compared
to the direct addressing mode.
4.7.5 Relative addressing
After a relative branch instruction has been fetched, the updated program counter contents, pointing
to the next instruction, are used in relative addressing. The signed two’s complement offset is added
to the update program counter to obtain the branch address. 8-bit and 16-bit offsets are used for short
branch and long branch respectively. 8-bit offsets are sign extended before the addition. Short
branches have a limited branch range of +127 to -128 of the updated PC. Long branches can reach
the entire 64 K address space. The effective address here is the target branch address.
4.7.6 Indexed addressing
Indexed addressing on the MC6809 microprocessor is complex but powerful. Immediately following
the indexed addressing opcode is a postbyte which can be followed by additional bytes. Indexed
addressing allows the effective address to be obtained by adding contents of the selected index
register with a signed two’s complement short 5-bit offset, 8-bit offset which can be a constant or
provided by either accumulator registers. A 16 bit offset in the double accumulator is also possible.

75
Post increment and pre-decrement are also possible. Indirect addressing with most of the variations
described above is possible giving the MC6809 instruction set its phenomenal power.
4.8 MC6809 Instruction Set
The MC6809 Instruction set is given as Appendix A. An instruction set of a microprocessor is a list
of all the instructions available together with addressing modes. It provides all the information
required to program the microprocessor or to develop assemblers for the microprocessor. The
manufacturer provides a set of mnemonics which must be used, which the assemblers will be able to
process to produce machine code. Ultimately, it is the machine code which runs on a processor and is
the only language it understands and can work with. An assembly language program is called the
source form of the code or source code. Source code is assembled into machine code, also called
object code. The source code and the object code will only be useful for a given microprocessor and
will not assemble or run on a different microprocessor or different hardware structure.
4.9 Subroutines
Subroutines make it possible to write structured low level language programs. Subroutines are the
equivalent of C functions. A subroutine specifies a sequence of actions which must take place each
time it is called. When a subroutine is called, the address of the instruction following the call (which
is in the program counter) is automatically saved on the hardware stack. The program counter, PC, is
loaded with the start address of the subroutine and instructions are now fetched from the instructions
of the subroutine. A special instruction, RTS, or return from subroutine returns control to the calling
instruction sequence. The causes the saved return address to be pulled from the stack into the
program counter register. Instructions are now fetched from the calling sequence in memory.
When input and output parameters are passed to and from a subroutine, the predefined sequence of
operations is applied to the parameters. Formal parameters refer to the data variables of a subroutine
while actual parameters refer to the actual data which will be manipulated by the subroutine. It is
common to use internal registers of the microprocessor to bring in values and take out results out of a
subroutine. Even the individual bits of a register, e.g. the status flags can be used to bring in and take
out results from a subroutine. Parameters are commonly passed via a stack and this is especially
useful if another stack, different to the hardware stack is available. That is why the MC6809
microprocessor has the user stack pointer register, U. The two index registers can be used to support
additional stacks. It is easy to see that pre-decrement of indexed addressing is equivalent to a push
operation while post-increment is equivalent to a pull operation. This applies to both 8-bit and 16-bit
values. Although individual selected memory locations can be used for parameter passing, it is bad
programming practice and is only used as a last resort when the other alternatives cannot be used.
A called subroutine can call other subroutines which can in turn call other subroutines. This is called
subroutine nesting. Nesting depth is only limited by the size of the stack.
4.10 Special Instructions
MUL is a special instruction which treats the contents of the two accumulator registers: ACCA and
ACCB as unsigned positive 8-bit numbers. It multiplies the two numbers leaving the 16 bit result in
the 16-bit double accumulator ACCD. It can be considered as a predefined multiplication subroutine.
Subroutines can be written to handle multiplications involving larger numbers based on the use of
the MUL instruction. In the same way, a signed multiplication subroutine can also be written based
on the MUL instruction. It is important to bear in mind that the multiplication routine overwrites the

76
multiplier and the multiplicand which were in the two accumulators before the MUL instruction was
called to save the 16 bit result in the double accumulator.
DAA stands for decimal adjust arithmetic and affects only ACCA. The instruction typically
immediately follows an addition operation where the sum is left in ACCA. It then adjusts the result
to allow Binary Coded Decimal or BCD arithmetic. Only the addition instructions affect the Half
Carry flag, H, which is central to the operation of this instruction.
CWAI (wait for interrupt) is an instruction which is used to synchronise a program to an external
event which causes an interrupt. All the processor registers are stacked before instruction fetching is
suspended. When an enabled interrupt occurs, control is transferred to the interrupt service routine of
the interrupting line. If a disabled interrupt is detected, processing proceeds with the instruction
following the CWAI instruction after the restoration of the stacked registers.
TFR (transfer) and EXG (exchange): The transfer instruction allows a source register to be
transferred to a destination register of the same size. Exchange allows the contents of two registers of
the same size to be exchanged. Each register has been assigned a four bit code for these two
operations. See figure 4.4.
D 0000 X 0001 Y 0010 U 0011 S 0100

PC 0101 A 1000 B 1001 CCR 1010 DPR 1011

4.11 RESET and Interrupt Processing


After power is applied to a microcomputer, the RESET signal is forced low for a period after the
supply voltage has stabilised. The MC6809 microprocessor will push out the address $FFFE onto the
address bus for a read operation. When the hardware RESET input goes high, the read byte is stored
internally onto the upper byte of the program counter. Next the address $FFFF is pushed out of the
address bus for another read operation. The read byte is stored into the program counter’s lower byte.
Thereafter the processor starts its continuous instruction fetch and execute cycle using the addresses
in the program counter. This means that the address of the very first instruction of the system
program (or the boot code) must be stored at these last two addresses of the 64K memory space. This
is called the RESET vector. In our example memory map $CO would be stored at $FFFE and $00 at
$FFFF in EPROM. This is one of the reasons why non-volatile memory must occupy the higher end
of the memory address space. The set of instructions starting at $C000 are executed only once at start
up. This is called the initialisation sequence. It is used to initialise key registers within the
microprocessor and configure input and output devices to the required operational modes. The
microprocessor hardware stack pointer, ACIA control and command registers are good examples of
registers which are loaded with specific values during this sequence. Typically, the last operation in
the initialisation sequence is the enabling of interrupts by clearing the two interrupt masks I and F in
the condition code register CCR. Thereafter the system program forms an infinite loop.
When an input and output device requires the attention of the processor, it will pull down an interrupt
request line. An interrupt is then said to be pending. If the pending interrupt is enabled, interrupt
77
processing takes place. There are three hardware interrupts on the MC6809 microprocessor. These
are NMI, or non maskable interrupt, FIRQ which is fast interrupt request and IRQ which is the
regular interrupt request. There are also three software interrupts: SWI, SWI2 and SWI3.

The I bit in the condition code register is an interrupt mask for IRQ. The F bit is the mask for FIRQ.
Hardware RESET sets the masks thus disabling the interrupts. For each interrupt to be enabled, its
mask bit must be cleared. The ANDCC instruction can be used to do this. Each interrupt can be
disabled after it has been enabled by setting the respective mask bit using the ORCC instruction.

All interrupts push the entire processor state (i.e. all the internal registers in a predetermined order)
onto the hardware stack except FIRQ which pushes only the PC register first then the CCR. The E or
ENTIRE bit in the CCR is an indication of whether the entire processor state was stacked if the bit is
a ‘1’ or whether only PC and CCR were stacked if the bit is a ‘0’. The order of stacking is indicated
in the push/pull byte shown in figure 4.4. The registers are pushed onto the stack to save them, since
they are most likely going to be used before control is transferred back to the interrupted program.
The last register to be stacked is the condition code register. The bit E, is set to appropriate value
depending on interrupt priorities before the register is stacked. Soon thereafter, I and or F may be set
depending on interrupt priorities.

The processor then uses the respective interrupt vector to fetch the start address of the interrupt
service routine (or interrupt handler) for the specific interrupt. The interrupt vectors are shown in
figure 4.3. Once the program counter has been loaded with the vectored address, the processor
resumes its endless cycle of instruction fetch and execute. This continues until the return from
interrupt, RTI, instruction is fetched. This causes the CCR register to be unstacked and the E bit
examined to determine whether only PC or all the other registers should be unstacked. The endless
cycle of instruction fetch and execute resumes at the interrupted instruction sequence.

IRQ and FIRQ are low level sensitive interrupt inputs while NMI is an edge sensitive interrupt input.
IRQ and FIRQ interrupts can be shared by several I/O devices but the edge sensitive NMI can only
be driven by one interrupting source.

Interrupts have predefined priorities shown in the table of figure 4.3. NMI has the highest priority
after hardware RESET. After a hardware RESET NMI interrupts will only be recognised after the
first load of the system stack pointer register. NMI cannot be interrupted by the other two hardware
interrupts. However, NMI can always and will interrupt all other interrupts since it cannot be
disabled or masked. Next in priority is the soft interrupt SWI followed by FIRQ then IRQ. The
lowest priority interrupts are SWI2 and SWI3 in that order. Software interrupts can be considered to
be subroutines where the stacking and unstacking of the registers is automatically done and much
faster than with the use of the PUSH and PULL instructions.

4.12 Interrupt Service Routines (Interrupt Handlers)


An interrupt service routine must be provided for each interrupt source. It will start at a specific
address to be stored in the interrupt vector table. Typically the interrupt service routine will poll the
devices connected to that interrupt input in a predetermined order which becomes the priority levels
among that group. The interrupt service routine will establish conditions which caused the interrupt
and attend to them. It is absolutely critical for the interrupt service routine to clear interrupt flags of
the interrupting devices before returning control to the interrupted instruction sequence. Failure to do
so will result in the routine being continuously called and the processor will not be able to execute
the instructions in the main sequence. The FIRQ interrupt service routine is meant to be fast. Ideally
78
it must not push and pull internal registers required by the routine. Typically it is used to increment
or decrement certain memory locations without overwriting internal registers. However, depending
on the situation a designer may choose to override this and use it as a normal interrupt with a higher
priority than IRQ

4.13 Edge Sensitive Interrupts

NMI is the only edge sensitive interrupt on the MC6809 microprocessor. It is the falling edge of this
negative edge sensitive interrupt which causes the interrupt to become pending. Several devices
cannot be connected together to share this type of interrupt because this can result in system
malfunction. Consider the situation shown in figure 4.5 where three I/O devices are connected to
NMI.

The timer requires the attention of the processor and pulls down the common NMI line. The falling
edge generates the interrupt. The interrupt service routine polls the ACIA first. At this point the
ACIA does not require the processor’s attention. Then it polls the PIA which also does not require
processor’s attention. At this point a serial character is received in the ACIA which causes it to pull
down the NMI line. The interrupt service routine meanwhile polls and services the timer. It then
returns control to the interrupted program. The NMI line will remain low. The falling edge can never
occur again. The pending ACIA interrupt and any other interrupts from the other two I/O devices
thereafter will not be attended to. This situation results in system failure.

EXERCISE
Describe in detail, step by step, what would happen, if the same scenario as described above were to
occur, if the three I/O devices were connected to the standard interrupt request input, IRQ. Draw a
timing diagram showing the state of the common shared interrupt request line, IRQ, and label it with
events as is shown in Figure 4.5.

79
Chapter Five: Assembly Language Programming
5.1 Assemblers and Assembly Language Programming
Microcomputers can only run on machine code stored in memory as bytes. Microcomputer
application programs have been written in higher level languages because they are more structured
and are easier to comprehend and to modify. Compilers can be written and used to compile high
level languages directly into machine code for specific target microcomputers. Compilers for
languages like C and Pascal are commonly supported for different target microcomputers. The
resulting machine code is not always optimised in terms of the size of the machine code nor its
performance in terms of execution time.

Assembly language is a lower level programming language which is very close to machine code. It is
easily converted to machine code with the use of much simpler assemblers. While it may be more
difficult for humans to write assembly language programs, it is the preferred approach to developing
machine code programs. Comprehension of assembly language programming can be assisted by
adopting certain habits when writing such programs. Structured programming techniques like the
correct use of subroutines and the extensive use of comments will go a long way in making assembly
language programming more readable and practical.

An assembly language program consists of a sequence of assembly language statements. In most


cases, each assembly language statement is converted into one machine code instruction. There are
exceptions to this rule when assembler directives are used. An assembler directive does not directly
produce a machine code instruction, but it provides the assembler with useful information to be used
later during the assembly process. Assemblers produce machine code (or object code) from an
assembly language source program stored in a source text file. The assembler makes use of a
Location Counter and a Symbol Table during the translation process. A location counter is a
variable which keeps track of the addresses within the 64 kilobyte address space. It can be initialised
by any one of the assembler directives and is updated during the analysis and translation of assembly
language statements. By default, the Location Counter is initialised to 0 at the beginning of the
process. The symbol table on the other hand is used to store the attributes of identifiers. Typically the
symbol table is provided with information by assembler directives, but in some cases may extract
stored information from the program itself. In most cases, the machine code is created in a text file
which then stores either Intel Hex format records or Motorola S format records.

An assembly language statement is made up of four fields and will occupy one line of the source
program stored in a text file. A well written program will have each field start in a specific column
for aesthetics and for ease of comprehension.

Label field: The first field of an assembly language statement is the label field. Most assemblers
require that this field begins in the first column of its line if it is present. A label is an identifier
whose composition follows the normal lexical rules for forming identifiers. This means a label must
begin with a letter or an underscore (underline) and may be followed by letters and numerical digits.
Most assemblers place an upper limit to the length of a label and is usually 15. A horizontal tab
(obtaining by pressing the tab key) with ASCII code $09 causes a forward skip of 8 character
positions. Two tabs therefore allow 16 character positions to be skipped. Having labels with a
maximum length of 15 means if no label is required or provided, or if a short label is used, two tabs
allows the programmer to jump straight to the next field. Labels must be given meaningful names.
Underscore can be used in much the same way as a space is used.
80
Operation field: This field is mandatory. An assembler directive, if used, will be in this field. Most
statements will use one of the mnemonics in the instruction set as defined by the manufacturer of the
microprocessor. If the label is missing, this field will normally start in column 16. Each operation, be
it an assembler directive or one of the standard mnemonics in the instruction set, will be associated
with a number of further parameters which occupy the next field. A mnemonic is a memory jogger.

Operands field: This field is determined by the directive or mnemonic in the operation field. It will
specify the operands required by the operation or directive. Different items in this field are normally
separated by commas. The data may be specified as variables or internal register names. Literal or
constant data may also be used. Numerical addresses can also be specified. Special characters are
used to direct the assembler on the nature of the operand. Numerical values may be specified in the
following number bases:

 decimal (this is the default) when there is no character preceding the number.
 binary in which case the binary number is preceded by the percent sign (%)
 octal in which case the number must be preceded by @ or O
 hexadecimal in which case the number is either preceded by the dollar sign ($) or be
terminated by the letter ‘H’. The lower case letter x may also be used at the beginning after
an initial ‘0’. If an ‘H’ is used at the end of a hexadecimal number, a ‘0’ digit must begin any
hexadecimal number which would otherwise have begun with the letters ‘A’ through ‘F’. The
assembler may otherwise treat it as a label when in fact it is a number.
 character value in which case it is enclosed in single quotes, e.g. ‘A’.

Simple arithmetic expressions involving constant numerical values (also called literals) and or
previously defined values are allowed in the operands field and may assist in making program more
readable. Only constant values are permitted in the expressions of the operands section.

Comments field: The comments field follows the Operands field. Some assemblers require that a
special character, typically the semicolon (;) or the asterix or star (*) be used to indicate that a
comment follows. Such characters may be used at the beginning of the line to direct the assembler to
consider the whole line as a comment. Others assume anything following the operations field is a
comment. Assemblers ignore all comments. Comments are there to assist with program readability.

In addition to producing Intel Hex format records or Motorola S format records after assembling a
correct program, the assembler can be requested to generate a listing file. A listing file flags all errors
in addition to showing the machine code produced on the left of the source assembly language
statements. The listing can be produced as a file or as textual output on the teletype screen. The
assembler normally uses error codes which are defined in a user manual document in case of errors.

5.2 Assembler Directives

5.2.1 ORG (Origin Directive)


[label] ORG <expression> [;comment].

The origin directive is used to inform the assembler of the 16-bit address to use for variables and
instructions from that line going forward. The default origin at the beginning of the file is 0. It is
common to find the ORG directive being associated with a label, which assumes the address as
specified in the directive. The Directive requires one parameter, which is the address to be used. The
address can be a numerical value or a predefined label or name.
81
ORG $C000
COLD_START LDS #$8000
The instruction LDS #$8000 will be stored at address $C000. The label COLD_START will be
stored in the symbol table to have the value $C000 which will replace the label from that point on.

5.2.2 EQU (Equate Directive)


[label] EQU <expression> [;comment].

The equate directive is used to direct that the assembler replace each occurrence of the identifier in
the label field of that directive with the specified value. 8-bit and 16-bit values can be specified in the
operands field. The values in the operands field can be other labels or variables already defined. This
directive is commonly used to assign 16-bit addresses to I/O registers to make programs more
readable.

ACIA1 EQU $8000


ACIA2 EQU $8800
NULL EQU $00
The previous two directives, on their own, do not affect the location counter which remains
unchanged.

5.2.3 FCB (Form Constant Byte Directive)


[label] FCB <expression> (<expression>, … , <expression>) [;comment].

The form constant byte directive is used to direct the assembler to reserve one byte in memory and to
initialise it to the specified value. This is one way of creating tables in memory. The location counter
is incremented by the number of bytes specified after processing each one of this type of directive.

CR_LF FCB $0D ; carriage return


FCB $0A ; line feed

5.2.4 FDB (Form Double Byte Directive)


[label] FDB <expression> (<expression>, … , <expression>) [;comment].

The form double byte directive is used to reserve two bytes of memory to be initialised to the
specified value (in big endian format for Motorola devices and little endian format for Intel based
processors). The location counter is increased by twice the number of 16-bit words specified after
processing each one of this type of directive.

CR_LF FDB $0D0A ; carriage return and line feed


FDB ACIA1 ; predefined labels allowed

5.2.5 RMB (Reserve Memory Bytes Directive)


[label] RMB <expression> [;comment].

The reserve memory bytes directive skips the specified number of bytes but does not initialise the
skipped memory locations to any values. This directive is used to reserve memory for variables in a
program, typically in RAM. The location counter is incremented by the number of bytes reserved for
each such directive. The number of bytes reserved depends on the variable and its numerical range or
size in bytes. Variables declared thus have their associated addresses entered into the symbol table.
82
temperature RMB 2 ; 2 bytes reserved for temperature
pressure RMB 2 ; 2 bytes reserved for pressure
flow_rate RMB 2 ; 2 bytes reserved for flow rate
identity_no RMB 1 ; 1 byte reserved for identification no.

5.2.6 FCC (Form Constant Character String Directive)


[label] FCC <delimiter> <expression> <delimiter> [;comment].

This directive is used to form character strings in memory. The NULL character may be appended to
the end of the string using the Form Constant Byte directive after the string depending upon usage.
The delimiter may be any non space character after the FCC directive. Commonly used delimiters
are the single and double quotes. Commas, round and square brackets can also be used. The same
delimiter must be used for opening and closing the string. C strings are terminated by NULL ($00).

SIGN_ON FCC ‘Sweet Packing Machine’


FCB NULL

5.2.7 BSZ (Block Storage of ZEROs Directive)


[label] BSZ <expression> [;comment].

This directive is used to reserve memory space and initialise it to all ZEROs. The number of bytes to
be cleared is specified by its only operand. The reserved area of memory will start at the current
address in the location counter.

5.2.8 ZMB (Zero Memory Bytes Directive)


[label] ZMB <expression> [;comment].

The zero memory bytes directive has the same effect as the block storage of zeros directive.

5.2.9 FILL (FILL memory Directive)


[label] FILL <expression>, <expression> [;comment].

The fill memory directive directs the assembler to fill a given area of memory with the specified
byte. The first parameter specifies the fill byte while the second parameter specifies the number of
such bytes to be placed starting at the current address in the location counter.

5.3 Example Assembly Language programs

5.3.1 ACIA receive and transmit subroutines

Two example polled ACIA subroutines will be used to illustrate the development of assembly
language programs and subroutines. The first one: get_char1 will, once called, wait for a serial
character to be received through the serial port of ACIA_1. Once received, the character will be
returned through the accumulator A, ACCA, register. The second one: put_char1 will, once
called with a value in ACCA, send the passed byte out through the serial link of ACIA_1 and return.
All programs will be shown in the standard listing file format produced by assemblers complete with
addresses and machine code on the left. Further Intel hex format records and Motorola S format
records are shown at the bottom of the assembled subroutine. This is not part of a listing file.
83
8000 ACIA1 EQU $8800
8801 ACIA1_STATUS EQU ACIA + 1
8800 ACIA1_RDR EQU ACIA
8800 ACIA1_TDR EQU ACIA
10 ACIA_TDRE EQU $10
08 ACIA_RDRF EQU $08

; ACCA returns received character


F000 ORG $F000
F000 B6 8801 get_char1 LDA ACIA1_STATUS ; sense
F003 85 08 BITA #ACIA_RDRF ; status
F005 27 F9 BEQ get_char1 ; loop
F007 B6 8800 LDA ACIA1_RDR ; load char
F00A 39 RTS ; and return

; ACCA brings in character to be transmitted


F00B 34 02 put_char1 PSHS A ; save on hardware stack
F00D B6 8801 put_loop1 LDA ACIA1_STATUS ; wait for
F010 85 10 BITA #ACIA_TDRE ; TDRE to
F012 27 F9 BEQ put_loop1 ; become a 1
F014 35 02 PULS A ; retrieve from stack
F016 B7 8800 STA ACIA1_TDR ; send char
F019 39 RTS ; and return
Corresponding Intel hex format record
:1A F000 00 B68801850827F9B68800393402B68801851027F93502B7880039 BA
:00 0000 01 FF

and Motorola S format record


S1 1D F000 B68801850827F9B68800393402B68801851027F93502B7880039 B6
S9 03 0000 FC
Note that in both cases, the spaces are included to separate out the fields of the records. In a real data
file, these spaces will not be there.

5.3.2 Multi-precision Addition and Multiplication

The next two examples look at multi-precision addition and multiplication. The MC6809 supports 16
bit arithmetic operations, both addition and subtraction. Multi-precision arithmetic is possible
through the development of appropriate subroutines. A subroutine that adds two 32 bit numbers
producing a 32 bit sum and a carry will be developed. Also a subroutine to multiply two 16 bit
unsigned numbers will also be developed. The code is given below.

In the case of 32 bit addition, the two index registers IX and IY point to the two numbers to be added
while the User Stack pointer, U, used as an index register, will point to the 32 bit sum. There will be
a carry which must be considered as part of the result. In the case of 16-bit by 16-bit multiplication,
IX points to the multiplicand while IY points to the multiplier and U points to the 32 bit product.
There cannot be an overflow in this operation. As an exercise, develop subroutines for 32 bit
subtraction and 16 bit by 24 bit multiplication.

84
; IX points to 32 bit number
; IY points to 32 bit number
; U points to 32 bit sum
F020 ORG $F020
F020 34 02 ADD_32 PSHS A
F022 A6 03 LDA 3,X
F024 AB 23 ADDA 3,Y ; Carry significant
F026 A7 43 STA 3,U ; Carry not affected
F028 A6 02 LDA 2,X ; Carry not affected
F02A A9 22 ADCA 2,Y ; Add with Carry
F02C A7 42 STA 2,U ;
F02E A6 01 LDA 1,X
F030 A9 21 ADCA 1,Y
F032 A7 41 STA 1,U
F034 A6 00 LDA 0,X
F036 A9 20 ADCA 0,Y
F038 A7 40 STA 0,U
F03A 35 02 PULS A
F03C 39 RTS ; Return

85
; IX points to 16 bit number
; IY points to 16 bit number
; U points to 32 bit product
F040 ORG $F040
F040 34 06 MUL_16 PSHS A,B
F042 6F 40 CLR 0,U
F044 6F 41 CLR 1,U
F046 A6 01 LDA 1,X ; set up for
F048 E6 21 LDB 1,Y ; multiplication
F04A 3D MUL
F04B ED 42 STD 2,U ;
F04D A6 00 LDA 0,X ; Carry not affected
F04F E6 21 LDB 1,Y ; Add with Carry
F051 3D MUL
F052 E3 41 ADDD 1,U ; Carry is significant
F054 ED 41 STD 1,U ; Carry is significant
F056 24 02 BCC SKIP_0
F058 6C 40 INC 0,U
F05A A6 01 SKIP_0 LDA 1,X ; Carry not affected
F05C E6 20 LDB 0,Y ; Add with Carry
F05D 3D MUL
F05E E3 41 ADDD 1,U ; Add with Carry
F060 ED 41 STD 1,U ; Carry is significant
F062 24 02 BCC SKIP_1
F064 6C 40 INC 0,U
F066 A6 00 SKIP_1 LDA 0,X ;
F068 E6 20 LDB 0,Y ;
F06A 3D MUL
F06B E3 40 ADDD 0,U ;
F06D ED 40 STD 0,U ;there can be no Carry
F06F 35 06 PULS A,B
F071 39 RTS ; and return

5.3.3 Signed Two’s Complement Multiplication

It is required to be able to multiply two signed two’s complement 8 bit numbers in the two
accumulators leaving the 16-bit product in the double accumulator. The signed two’s complement
multiplication subroutine must consider four cases as follows.

 Case 1 - both numbers are positive


 Case 2 - ACCA is positive but ACCB is negative
 Case 3 - ACCA is negative while ACCB is positive
 Case 4 - both numbers are negative.

; ACCA is the multiplicand


; ACCB is the multiplier
; ACCD returns 16 bit product

86
F080 ORG $F080
F080 4D SIGNED_MUL TSTA
F081 2B 0D BMI CASES_34 ; where ACCA -ve
F083 5D TSTB ; ACCA +ve
F084 2A 08 BPL CASE_1
F086 50 CASE_2 NEGB ; negate ACCB
F087 3D POS_AND_NEG MUL
F088 53 NEGD COMB ; same as negate ACCD
F089 43 COMA
F08A C3 0001 ADDD #$0001
F08D 39 RTS
F08E 3D CASE_1 MUL ; ACCA +ve and ACCB +ve
F08F 39 RTS
F090 5D CASES_34 TSTB ; ACCA -ve
F091 2B 03 BMI CASE_4
F093 40 CASE_3 NEGA ; ACCA –ve and ACCB +ve
F094 20 F1 BRA POS_AND_NEG
F096 40 CASE_4 NEGA ; ACCA –ve and ACCB -ve
F097 50 NEGB
F098 3D MUL
F099 39 RTS

5.3.4 String Copy


Character strings in most programming languages are terminated by the NULL character or $00. The
following is a string copy subroutine which copies a string from a source area to a destination area.
The start address of the source string is in index register X, IX, while the start address of the
destination area is in index register Y, IY. See figure 5.3.

; IX points to the source string


; IY points to the destination area
; copies string from source to destination
F0A0 ORG $F0A0
F0A0 34 02 STRING_COPY PSHS A ; save ACCA
F0A2 A6 80 STRING_LOOP LDA 0,X+
F0A4 27 04 BEQ COPY_DONE
F0A6 A7 A0 STA 0,Y+
F0A8 20 F8 BRA STRING_LOOP
F0AA 35 02 COPY_DONE PULS A
F0AC 39 RTS
87
5.3.5 Memory reservation for variables

The following indicates how memory is reserved for variables in memory.

0000 ORG $0000


0000 temperature RMB 1
0001 pressure RMB 2
0003 variable_32 RMB 4
0007 flow_rate RMB 2
0009 id_string RMB 16
0019 first_name RMB 16
0029 surname RMB 16
0039 age RMB 1
003A position RMB

The location counter is updated as each variable declaration is seen. The 16-bit addresses on the left
are used in place of the variables in the assembly language program.

5.4 Machine Code Overlaps

The origin directive should be used with caution. It is possible to use the directive several times in a
program and then create what are called code overlaps. This means from different origin blocks,
certain memory locations will be allocated different bytes. This error can be very difficult to detect.
If it occurs in an EPROM code area, the error could be picked up by a programming verification
error while trying to actually program the EPROM. If such code were to be downloaded into RAM,
the presence of code overlaps would not be noticed expect that the program will not run correctly. It
can be very difficult to notice or detect such errors and take the necessary corrective action. Careful
examination of the end result, i.e. the object code files with Motorola S format or Intel hex format
records might be necessary to confirm there are no code overlaps.

5.5 Machine Code offsets

Once an assembly language program has been written and is being compiled, there are certain details
which need to be taken into consideration while using the tools for producing machine code. The
code will eventually be loaded into RAM or EEPROM or EPROM each with its own starting
address. Consider for example the system program beginning at address $C000 in the entire memory
map. The Motorola S format or Intel Hex format records will ultimately be downloaded to a
programmer to burn the code into EPROM. Memory map address $C000 will correspond to address
$0000 within the EPROM memory chip. A code offset must be specified with the relocation offset
while creating the actual code. The assembler will request for this offset as it prepares to assemble
the program. Programs, which are however meant to be loaded into RAM, will not require such an
offset. This means the offset would be 0. This because the host system will correctly interpret the
addresses and load the data in the correct destination.

Exercise:

Write an assembly language program which adds all the numbers between 1 and 10 and stores the
result in memory location $00A0.

88
Chapter Six: LCD Matrix Displays
6.1 Background
An LCD matrix display is commonly found on the control panel of a control system. These displays
come in different sizes, i.e. the number or rows and the number of characters per row. All of them
have a common interface. This comprises the power supply inputs and a display contrast control.
They also feature three control signals for selection of internal registers, direction of transfer and
synchronisation of transfer of data to and from the display. There is also an 8-bit bidirectional data
port. LCD matrix displays afford the designer of a control system a very flexible and informative
way of displaying system operation, parameters and alarm conditions. Figure 6.1 shows the interface
signals of a typical LCD matrix display. The input VLCD is normally adjusted by a precision
potentiometer between 0V (VSS) and 5V (VDD) to be about 0.5V. This gives the best display. With
some displays, pin 15 is connected to 5V and pin 16 to ground through a current limiting resistor.

89
Figure 6.2 is the instruction set and format summary. The designer has the choice of using a 4-bit
data bus or the full 8-bit data bus. The former requires allocation of few pins but requires twice as
many bus transfers to achieve the same effect. Figure 6.3 compares the two different data bus width
configurations. The transfer of data across the data bus has a timing similar to that between a
microprocessor and a typical input / output device. There is one register select line and the read and
not write control signal. The enable signal synchronises the actual transfer which takes place when
the enable signal is high. A write to the LCD while the register signal is ‘0’ is a transfer of a
command to the LCD. Typically this is required to initialise the LCD display at the beginning and
correctly configure it for the required operational mode. A read from the LCD display with the
register select signal set to ‘0’ is a BUSY flag read which also returns the current cursor position
address. A write to the LCD display with the register select high writes a character to the display at
the current cursor position or address. A read with the register select bit set reads the data or
character stored at the current cursor position or address. See the timing diagrams of figure 6.4. If a 4
bit data bus is being used, the 8-bit command or data is transferred with two enable pulses, the upper
nibble being transferred first followed by the lower nibble.

90
Since it is necessary to both read from and write to the LCD through its bidirectional data port, it is
necessary for PORTA to be turned around frequently from being an input port into being an output
port and vice versa. Remember that if Port A is configured as an output port permanently, then to use
it as an input port without the need to change DDRA, just simply write $FF into the output peripheral
register for port A. Data can be read through Port A to determine the state of the BUSY flag. It is
good practice, during the design of the hardware, to put 220  resistors between Port A pins and the
LCD data port pins to eliminate altogether potential hardware bus conflicts.

6.2 LCD Matrix Display Instructions


The position of the leading ‘1’ in an instruction determines the type of instruction or command being
sent to the LCD and its format (.i.e. the meaning and position of each bit)
6.2.1 Function Set (Execution time 37 microseconds)
This is the first command to be sent to the LCD display after power up. This command must be sent
three times with one second delays in between to initialise the display. Before this command is sent,

91
one or more lines will display boxes which allows the contrast potentiometer setting to be adjusted.
After the display is initialised as described above, the display is cleared and the cursor set to the
home position, i.e. the top left corner with address $00. Bit 4, DL, defines the data bus width or data
length. If DL is ‘0’ it assumes a 4 bit bus whereas if DL is ‘1’, an 8-bit bus is assumed. The next bit
N determines the number of lines. N=0 for one line and is ‘1’ for two lines. Lastly, F defines the font
matrix size. F = 0 defines a 5 x 8 dot matrix pattern which is the normal whereas F = 1 defines a 5 x
10 dot matrix pattern. Note that one of the either 7 rows or 10 rows is used as a spacer and is
normally off, meaning the effective font sizes are 5x7 and 5x9.

6.2.2 Clear Display $01 (Execution time 1.52 ms)


This command clears the entire display and returns the cursor to the home position.

6.2.3 Return Home $02 or $03 (Execution time 1.52 ms)


Returns the cursor to the home position, but does not change what is being displayed on the LCD
matrix display.

6.2.4 Entry Mode Set (Increment/Decrement Cursor Position, Shift Characters) (37 s)
This command sets the cursor movement to increment mode when I/D is set to ‘1’ and is in
decrement mode when I/D is cleared to ‘0’. If SH is set to ‘0’ then the cursor shifts and the
displayed characters do not shift as data characters are sent to the LCD for display. If SH is ‘1’, it is
the display characters which shift and not the cursor position. The most commonly used combination
is Increment and Shift the cursor (i.e. do not shift the data), i.e. the command $06.

6.2.5 Cursor Display (S/C and R/L) (Execution time 37 microseconds)


If S/C = ‘0’, this moves the cursor, if S/C = ‘1’, it is the data that shifts. R/L shifts the cursor to the
left when set to ‘0’ and to the right when set to ‘1’.

6.2.6 Display (ON/OFF and Cursor Operation) (Execution time 37 microseconds)


This command controls the operation of the cursor. D, when cleared will cause the entire display to
be off, and when set to ‘1’ enables the display. The next bit, C, when cleared means the cursor is not
visible, but when set to ‘1’, means the cursor is visible. The next bit B (for Blink) sets the cursor to
blink when set and does not blink when cleared.
6.2.7 Set Character Generator RAM Address Counter (Execution time 37 microseconds)
Sets the character generator ram address to set up custom user defined fonts
6.2.8 Set Display Data RAM Address Counter (Execution time 37 microseconds)
Used to move the cursor to a desired address to start displaying characters from that position.
6.2.9 Read the Busy Flag and RAM Address Counter (0 ms)
This command is normally issued before write command or write data transfers. It returns the state of
the busy flag and the current cursor address. Most often, the current cursor address is not required
but the state of the BUSY flag is. The command is normally sent in a subroutine which waits for the
busy flag to clear before returning. The subsequent command write or data write can then take place.
The use of this command presupposes the existence of a bidirectional data bus providing the
commands and data which can easily be turned around between read and write operations. The LCD
display can be interfaced to the microprocessor data bus directly provided the enable signal is only
propagated in bus cycles addressing the LCD display. Most applications will have the LCD display
92
be interfaced through the parallel port of an I/O device like a PIA. Such an application will require
the selected port to be turned around between read and write operations. This implies frequent access
to the data direction register. Access to the data direction register in the case of the MC6821 is
through the control register bit CRA2 or CRB2. This is very cumbersome. If the PIA’s port A is
configured as an output port permanently, its behaviour, when it is loaded with the data byte $FF is
identical to the port having been programmed as an input. This is a much easier approach. With other
microcontroller ports or with the ports of peripheral devices similar to PIAs, this might not be
possible. It is possible to configure the LCD matrix display, by permanently tying its R/W control
input to ground so that only write operations take place and the LCD port is input only. The need for
reading of the busy flag is done away with by generating a large enough delay after a write command
or write data operation, after which the BUSY flag is assumed or known to have cleared. The time
required to complete commands are documented for most displays. For example, for the HITACHI
HD44780 display, the two commands: Clear Display and Cursor Home require an execution time of
1.52 ms. All the other commands and operations require 37 microseconds, expect the ready status (or
BUSY) command which does not have any execution time at all as expected.

6.2.10 Write Data (Execution time 37 microseconds)


This by far the most common operation. It is used to write the ASCII code of the character to be
displayed on the LCD matrix display at the current cursor position. The cursor address is then
updated, incremented or decremented, depending on the programmed values of I/D and SH with the
entry mode set command.
6.2.11 Read Data (Execution time 37 microseconds)
This operation is very rare and not really necessary. It reads back the stored data at the current cursor
address. It returns the most recent data written to the display unless if the cursor address was
subsequently altered by the set cursor address command.

6.3 Initialising the LCD Matrix Display


After power is supplied to the LCD and the supply voltage has stabilised, the first row (or the two
odd rows for 4 row matrix display will display square blocks which only clear after the LCD matrix
display has been correctly initialised. Initialisation of the display involves transferring the Function
Set command (appropriately programmed) three times with a one second interval between the
transfer of the commands. It is common to send the command $38 to select an 8-bit bus, two line
LCD display and the standard 5x7 dot matrix pattern display for all the characters. Initialising the
LCD display in this manner clears it and returns the cursor to the home position. The other
commands can then be sent to complete its configuration. During the normal operation of a system
with such a display, commands are sent to change the cursor position and to transfer ASCII
characters (codes) to the internal data register so as to display the transferred characters. In the
process, before sending any command or data, the internal status register is read to confirm that the
BUSY bit (or flag) has cleared before the transfer. The following assembly language subroutine
(which assumes the existence of a one second delay subroutine) would be used to initialise the
display.

6.4 LCD Matrix Display Subroutines

93
It is common to provide four subroutines for writing commands and data and reading from the status
and data registers. The command or data to be written or read would be passed to and from via the
accumulator register ACCA. Assume that an LCD matrix display is interfaced through PIA_0 in the
example memory map. Further assume an 8-bit bus connected to PORTA of the PIA and the three
control signals: RS, R/W and E are connected to PORTB lines PB0, PB1 and PB2 respectively as
shown in figure 6.3. The four subroutines are given in the following code together with the required
initialisations at start up which configure PORTA as a data output port and the first three PORTB
lines as the control outputs. Note that handshaking would be inappropriate for this transfer since
there is no handshake control signal coming back from the LCD matrix display.

PIA0_PORTA EQU $9000 PIA_INIT LDA #$FF


PIA0_DDRA EQU $9000 STA PIA0_DDRA
PIA0_CRA EQU $9001 LDA #$07
; DDRA access through bit CRA2 STA PIA0_DDRB
PIA0_PORTB EQU $9002 LDA #$04
PIA0_DDRB EQU $9002 STA PIA0_CRA
; DDRB access through bit CRB2 STA PIA0_CRB
PIA0_CRB EQU $9003 CLR PIA0_CRA
END_INIT CLR PIA0_CRB

LCD_INIT LDB #$03 LDA #$04 ; (E)


LDA #$38 STA PIA0_PORTB
STA PIA0_PORTA NOP
; 8 bit bus – 2 lines for LCD NOP
; command sent 3 times CLR PIA0_PORTB
; for initialisation JSR ONE_SECOND
INIT_LOOP CLR PIA0_PORTB DECB
NOP BNE INIT_LOOP
NOP RTS

; ACCA <= command to LCD NOP


LCD_COMMAND PUSH A ; stack NOP
JSR WAIT_BUSY LDA #$00
PULL A STA PIA0_PORTB
STA PIA0_PORTA NOP
LDA #$00 RTS
STA PIA0_PORTB
NOP ; ACCA <= data to LCD
NOP LCD_DATA PUSH A ; stack
LDA #$04 ; (E) JSR WAIT_BUSY
STA PIA0_PORTB PULL A

94
STA PIA0_PORTA
LDA #$01
STA PIA0_PORTB
NOP
NOP
LDA #$05 ; (E)
STA PIA0_PORTB
NOP
NOP
LDA #$01
STA PIA0_PORTB
CLR PIA0_PORTB
RTS

95
The common subroutine, WAIT_BUSY, for waiting on the busy flag can be implemented as a finite
delay loop or a sense status loop checking on the busy flag and only returning when the busy flag has
cleared. Note that there is no need to save ACCA temporarily on the stack since the only two
subroutines which call the WAIT_BUSY subroutine stack ACCA before and unstack ACCA after
the call to this subroutine.
; subroutine waits for the BUSY flag to clear before returning
WAIT_BUSY LDA #$02 ; (set the R/W control bit to Read)
STA PIA0_PORTB
NOP
NOP
LDA #$06 ; (now set the Enable pulse to high)
STA PIA0_PORTB
NOP
LDA PIA0_PORTA
BITA $80 ; (Is the LCD Busy?)
BNE WAIT_BUSY ; if it is, then go back try again
LDA #$00 ; clear PortB
STA PIA0_PORTB
RTS ; and return from the subroutine

With the use of these library subroutines, it is now possible to develop the main code which would
call these subroutines to display strings on the LCD display. The first example will be the display for
a temperature data logger instrument. The string to be displayed is: “Temp Data Logger”
centred on the top row of the LCD display. Then the string: “Self Testing” is to be displayed
on the second row of the LCD display. First, it is important to calculate the start addresses for each
of the two strings on the two lines as shown in figure 6.6. Assuming the LCD matrix display is 2
rows by 16 characters per row. The first string occupies all the 16 character positions and will start at
address $00. The bottom string is 12 characters which means there are two spaces either side of the
centred string. So the string will start in the third character position of the bottom row at address $42.

T e m p D a t a L o g g e r
S e l f T e s t i n g
Figure 6.6 Example display for programming example
Develop a subroutine which displays a NULL terminated string where the source string in ROM is
pointed to by the index register X and the start address of the string on the display is brought in
through ACCA. This subroutine can then be called twice to display the two strings, defined in the
source program using the form constant character string (FCC) assembler directive. Also provide the
calling code. A slightly different approach is used in the calling code shown below.
In this case,
BANNER FCC ‘Temp Data Logger’
FBC $00
52
SELF_TEST FCC ‘Self Testing’
FCB $00

MAIN_PROGRAM LDX #BANNER


LDAA #$80 ; start address
JSR LCD_COMMAND
BANNER_LOOP LDA 0,X
BEQ END_BANNER
JSR LCD_DATA
LEAX 1,X ; same as INCX
BRA BANNER_LOOP

END_BANNER LDX #SELF_TEST


LDA #$C2 ; set address $42
JSR LCD_COMMAND
TEST_LOOP LDA 0,X
BEQ END_TEST
JSR LCD_DATA
LEAX 1,X
BRA TEST_LOOP
END_TEST RTS

53
Chapter Seven: The Motorola MC68HC11 Microcontroller
7.1 Background
A microcontroller (also MCU) is a computer on a chip requiring a power supply and crystal to be
complete. It can be as small as the size of a postage stamp and is designed for embedded controllers.
A microcontroller integrates all the components found in a microprocessor based microcomputer
onto the same chip. Several advantages accrue from this. Small size, light weight, less power
consumption, higher operation speed and much lower cost. Improvements in IC fabrication
technology made it possible to make very powerful microcontrollers. The first microcontroller was
the Texas Instruments TMS 1000 which became commercial in 1974. Intel developed the 8048
which went commercial in 1977. Microcontrollers had different variations in non-volatile memory
ranging from OTP (one time programmable) through those with EPROMS and custom ROMs. By
1993, EEPROM was integrated onto microcontrollers. Early applications were in keyboards,
calculators, washing machines, microwave ovens and other domestic appliances. The automobile
industry is a major consumer of microcontrollers which some vehicles having more than 30
microcontrollers. Microcontroller cost has significantly come down with some 8-bit versions selling
for less than 25 US cents. The Microchip PIC range of microcontrollers are very popular and widely
used in Zimbabwe since they are easily available, cheap and it is very easy to get free internet
downloadable software development systems and hardware schematics for programmers and other
tools. This course looks at the Motorola MC68HC11 microcontroller – one of the most powerful 8-
bit microcontrollers ever developed. It comes in several variations and this course will focus on the
MC68HC11F1N3 version which has several advantages over the other variations, especially when
operated in the normal expanded mode. This particular version of the microcontroller has the
following features:
 MC68HC11 CPU core
 four basic modes of operation flexibly selectable during power up (through MODA and
MODB inputs)
 more input and output ports and high speed non-multiplexed expanded system operation
 internal chip select functions with variable programmable clock stretching
 lots of internal configuration registers with status information and control
 time protected registers and bits can which can only be written to once in the first 64 Enable
cycles
 a powerful bootstrap mode
 512 bytes of relocatable internal EEPROM with bock protection
 1024 bytes of internal CMOS static RAM (all saved during standby)
 an advanced 16 bit timer subsystem with input capture, output comparison channels
 a real time interrupt (RTI) for supporting a real time clock
 an 8 bit Pulse Accumulator
 Synchronous Serial Peripheral Interface or SPI
 Asynchronous Non Return to Zero Serial Communications Interface SCI (similar to ACIA)
 Power saving STOP and WAIT modes
 Eight channel 8-bit analogue channels and an 8-bit internal analogue to digital converter
(ADC) with an internal sample and hold
 Computer Operating Properly (COP) watchdog timer
 Clock Monitor system
 Several interrupt input sources with global and local interrupt enables and separate vectors
54
 68 pin PLCC or (Plastic Leaded Chip Carrier) package
BLOCK DIAGRAM AND PIN CONFIGURATION OF THE MC68HC11F1N3

55
7.2 Control and Configuration Registers
The MC68HC11 has a 96 byte configuration register block for the control of all its various sub
systems. Some of the bits in these registers return status information from subsystems. Appendix C is
a summary of all the control and configuration registers for the microcontroller. The addresses given
are for the default locations of these registers starting at address $1000. Internal RAM which by
default starts at $0000 can also be relocated to start at another address. The two start addresses can
be relocated by writing, during initialisation, alternate values into the configuration register INIT
within the first 64 Enable cycles after a hardware RESET. One special register, CONFIG, is
implemented in EEPROM and retains its value after power is removed from the MCU.

INIT - $103D
RAM3 RAM2 RAM1 RAM0 REG3 REG2 REG1 REG0

7.3 Modes of Operation


MODA and MODB are two inputs to the microcontroller which are used to select from one of four
different modes of operation. The state of these two inputs as the MCU comes out of hardware
RESET determines which mode it will operate in

 Normal Single Chip Mode (MODA = ‘0’, MODB = ‘1’). In this mode, the chip operates
like a standalone microcontroller
 Bootstrap Mode (MODA = ‘0’, MODB = ‘0’). This is a special mode used for internal IC
testing after manufacture and can also be used to program the internal EPROM in some
versions. This mode can also be used for the rapid prototyping of new systems in
development.
 Normal Expanded Mode (MODA = ‘1’, MODB = ‘1’). In this mode, the chip operates like
a microprocessor requiring external memory and additional external I/O.
 Special Test Mode (MODA = ‘1’, MODB = ‘0’). This mode is used to test normal expanded
mode hardware and generally increments its address pins in a counting fashion.

The mode of operation is determined by the values in the internal configuration register HPRIO. It is
possible to start up in one of the special modes and then change the values of the bits to move into
another special mode or the normal modes, but the reverse is not possible. See the table 7.1 below.

Table 7.1 Selection of Modes of operation


Input Pins Mode Description Control Bits in HPRIO
MODB MODA RBOOT SMOD MDA
1 0 Single Chip 0 0 0
1 1 Normal Expanded 0 0 1
0 0 Special Bootstrap 1 1 0
0 1 Special Test 0 1 1

7.4 Memory Maps


Figure 7.2 shows the memory maps for the four different operating modes. The 1024 bytes of
internal RAM and the internal configuration registers can be relocated to any 4 kilobyte boundary. A
special BOOTROM ($BF00 through $BFFF) which holds the bootloader for the special bootstrap

56
mode is only enabled when the chip is in that mode. The vectors are towards the end of that memory
space. The 512 bytes of internal EEPROM can also be relocated at any 4 kilobyte boundary.

$0000
1024 Bytes 1024 Bytes 1024 Bytes 1024 Bytes
Internal Internal Internal Internal
RAM RAM RAM RAM
$03FF

$1000
Configuration Configuration Configuration Configuration
Registers Registers Registers Registers
$105F

$BF00
Bootstrap
ROM
$BFFF

$FFC0
Normal Normal
Vectors Vectors
$FFFF
Single Normal Special Special
Chip Mode Expanded Mode Bootstrap Mode Test Mode
Figure 7.2 Memory Maps for different modes of operation
7.5 Resets and Interrupts
The RESET pin on the MCU is bidirectional. The external hardware RESET circuit must therefore
be open drain or open collector. There are two internal sources of reset. These are the COP watchdog
timer and the clock monitor system. There are therefore three RESET Vectors for the MCU. The
COP subsystem can be enabled or disabled (bit NOCOP in CONFIG). If enabled, $55 and $AA are
written to the COPRST (COP reset register) within the timeout interval determined by the time
protected bits CR1:CR0 in the register: OPTION. A thoroughly debugged program will always
perform the write operations to COPRST before the programmed timeout interval expires. Software
failures are easily determined when the COPRST register is not written to within the specified
timeout period.
There are a total of 22 interrupt sources and 18 interrupt vectors. The SCI interrupt vector services
the five different SCI interrupt sources. Three interrupts cannot be masked. These are Illegal Opcode
Trap, Software Interrupt and the XIRQ input. All other interrupts can be disabled by the global
interrupt enable mask bit (I) which is bit 4 in the condition code register (CCR). The maskable
interrupts have a predefined priority order, although any one of them can be elevated to be the
highest priority among that group through the bits 0 through 3 of the HPRIO (highest priority)
register.

57
IRQ is an interrupt input which can be masked by the mask bit I. By default, after a hardware reset, it
is a negative edge sensitive interrupt input (IRQE = ‘1’). By clearing this bit, (only possible in the
first 64 E cycles), the IRQ input becomes a low level sensitive interrupt which can now be shared by
several devices. XIRQ on the other hand is a low level interrupt input which is disabled after
hardware reset (X bit in CCR is set). After clearing X, XIRQ interrupts are enabled. Once cleared, X
cannot be set by user software. It can only be set back to ‘1’ again by a hardware reset.
Vector Address Interrupt Source CCR Local Flag Bit
Mask Mask
FFD6, FFD7 SCI Serial System
SCI Transmit Complete TCIE TC
SCI Transmit Data Register Empty TIE TDRE
SCI Idle Line Detect I bit ILIE IDLE
SCI Receiver Overrun RIE OR
SCI Receive Data Register Full RIE RDRF
FFD8, FFD9 SPI Serial Transfer Complete I bit SPIE SPIF
FFDA, FFDB Pulse Accumulator Edge I bit PAII PAIF
FFDC, FFDD Pulse Accumulator Overflow I bit PAOVI PAOVF
FFDE, FFDF Timer Overflow I bit TOI TOF
FFE0, FFE1 Timer Input Capture 4/ I bit I4/O5I I4/O5F
Output Compare 5
FFE2, FFE3 Timer Output Compare 4 I bit OC4I OC4F
FFE4, FFE5 Timer Output Compare 3 I bit OC3I OC3F
FFE6, FFE7 Timer Output Compare 2 I bit OC2I OC2F
FFE8, FFE9 Timer Output Compare 1 I bit OC1I OC1F
FFEA, FFEB Timer Input Capture 3 I bit IC3I IC3F
FFEC, FFED Timer Input Capture 2 I bit IC3I IC3F
FFEE, FFEF Timer Input Capture 1 I bit IC1I IC1F
FFF0, FFF1 Real Time Interrupt I bit RTII RTIF
FFF2, FFF3 IRQ Pin I bit I bit None
FFF4, FFF5 XIRQ Pin X Bit None None
FFF6, FFF7 Software Interrupt None None None
FFF8, FFF9 Illegal OPCODE Trap None None None
FFFA, FFFB COP Failure None NOCOP None
FFFC, FFFD Clock Monitor Fail None CME None
FFFE, FFFF RESET None None None

Having separate interrupt vectors means interrupt service routines can be fast. The needless
sequential polling of devices sharing the same vector which might not have generated interrupts is
done away with. It is important to clear the interrupt flags within the interrupt service routines. All
timer subsystem flags are cleared by writing a ‘1’ into the flag bit. Other flags have their own
clearing sequence, e.g. SCI read of the status register SCSR followed by a read of its receive data
register, SCDR. The same clearing mechanism applies to the SPI subsystem to clear SPIF, where it is
necessary to read the SPI status register SPSR with the bit SPIF set followed by a read of the SPI
data register SPDR. This sequence will clear SPIF in the SPI status register SPSR.

HPRIO Interrupt Highest Priority Selection


0000 Timer Overflow 0001 Pulse Accumulator Overflow
0010 Pulse Accumulator Input edge 0011 SPI transfer complete
0100 SCI Serial 0101 Default – (reverts to IRQ)
58
0110 IRQ External Pin 0111 Real Time Interrupt (RTI)
1000 Input Capture 1 1001 Input Capture 2
1010 Input Capture 3 1011 Output Comparison 1
1100 Output Comparison 2 1101 Output Comparison 3
1110 Output Comparison 4 1111 OC5 / IC4
7.6 MC68HC11 Ports
7.6.1 Port A
Port A operation is tied to the 16 bit timer subsystem. The 8 bit port can be operated as a general
purpose bidirectional port with its own data direction register, DDRA, which can configure
individual port pins as inputs or outputs independently. PA0 through PA2 can be configured to be
input capture channels 1 through 3. PA7 down to PA4 can be configure as output comparison
channels 1 through 4. PA3 can be configured as an additional input capture channel or output
comparison channel.
7.6.2 Port B
Port B is an 8-bit output only port. It can be used as a general output port in single chip modes. In
normal expanded modes it becomes the upper byte of the 16-bit address bus.
7.6.3 Port C
Port C is an 8-bit bidirectional port. It can be operated as a general purpose input/output port with its
own data direction register, DDRC. Pins can be configured independently as inputs or outputs. In
normal expanded modes, it becomes the bidirectional data port. CWOM in OPT2 when set will drive
all of port C outputs into open drain outputs.
7.6.4 Port D
Port D is the only 6-bit port. It can be configured as a general purpose 6-bit input / output port with
its data direction register DDRD. PD0 and PD1 can be configured to provide the RxD and TxD pins
of the SCI subsystem. PD2 through PD5 can be configured to provide an SPI port. Port D has a
wired OR mode determined by the bit DWOM in SPCR. When DWOM is set, all port D pins have
open drain outputs meaning external pull up resistors are required
7.6.5 Port E
Port E is an 8 bit input only port. It can be operated as an 8 bit general purpose input only port or can
be configured to provide 8 analogue input channels of an internal 8 bit analogue to digital converter.
7.6.6 Port F
Port F is an 8-bit output only port. In normal expanded mode, it becomes the lower byte of the 16-bit
address.
7.6.7 Port G
Port G is a bidirectional 8-bit port. DDRG, its data direction register, allows each port pin to be
configured as an input or an output independently. The upper four bits: PG4 through PG7 can be
used as chip selects for program EPROM, system RAM and two I/O devices, thus simplifying chip
select logic for the four devices. The chip selects are very flexible and can be configured to select the
active level (active low or active high), start addresses and sizes of address ranges in addition to
clock stretching to accommodate a wide range of device access times. Bit GWOM in OPT2, when
set, will drive all the port G outputs to be open drain outputs.
7.7 MC68HC11 CPU Core Programmers Model
59
Figure 7.3 is the programmer’s model of the MC68HC11 CPU. There are lots of similarities with the
MC6809 programmer’s model. There are two accumulator registers ACCA and ACCB which can be
combined to form the 16-bit double accumulator: ACCD. There are two index registers IX and IY
with simple indexed addressing calculations. Only the Hardware Stack Pointer register is present.
Like with the MC6809 microprocessor, the stack grows towards lower addresses, but this time, the
stack pointer points to the next free slot on top of the stack. 8 bit and 16 bit register pairs can be
exchanged.

HC11 CPU CORE PROGRAMMER’S MODEL


(No User Stack Pointer Register U, nor Direct Page Register DP)
Internal Data Bus
Stack Pointer SP

d Register
Instruction ACCD
d
ACCA d ACCB Index Register IX

Instruction Index Register IY


d Arithmetic
Decoder
LogicdUnit
Program Counter
ALU
Control Bus
Signals / Enables
Address Latch
S X H IdN Z V C
CCR
Internal Address Bus
Figure 7.3 MC68HC11 CPU Programmer’s Model
FIRQ is now replaced by XIRQ and the interrupt mask F has been replaced by X. The Entire Flag, E
is now replaced by the bit S, signifying STOP mode. In STOP mode all the processor clocks are
stopped and since the microcontroller is a CMOS chip, power consumption is reduced to zero.

7.8 MC68HC11 Addressing Modes


The MCU has six addressing modes, most of which are similar in operation to the MC6809
microprocessor.

 Inherent or implied addressing: – same as the MC6809 microprocessor


 Immediate addressing: – 8 bit and 16 bit immediate operands -identical in operation to the
MC6809 microprocessor

60
 Direct addressing: – There is no Direct Page Register (DPR). Direct addressing can only be
applied to page 0, i.e. direct addressing can only be applied to addresses in the range $0000
through $00FF.
 Extended Addressing: Identical in operation to the MC6809 microprocessor
 Indexed addressing: Much simpler than on the MC6809. Can only be applied to the two
Index Registers, IX and IY. An unsigned 8-bit offset is specified with this addressing mode.
The contents of the selected index register are added to the zero extended 8-bit offset to
obtain the 16-bit effective address.
 Relative Addressing: Only the short 8-bit signed two’s complement offsets can be specified.
The updated program counter is added to the sign extended offset to obtain the branch
address which becomes the effective address. The branch range is there limited to -128
through +127 of the updated Program Counter value. Long branches can be obtained through
the use of short branches together with 16-bit target address jump instructions.

Some instructions combine several addressing modes in the same instruction. These include bit
manipulation and bit testing instructions. An immediate mask is usually combined with indexed or
direct addressing. These are BRSET, BRCLR, BSET, BCLR. CCR individual bits can be set or
cleared.

7.9 MC68HC11 CPU Instruction Set


The microcontroller’s instruction set is not as extensive as for the MC6809. Because it is meant for
embedded control applications, it introduces powerful bit manipulation and bit comparison
instructions. In addition to 8 bit by 8 bit unsigned multiplication, it introduces two divide
instructions. These are Integer Divide (IDIV) and Fractional divide (FDIV). Typically an Integer
divide is followed by several fractional divisions to generate fractions of the required accuracy for
the quotient.

7.10 Serial Communications Interface (SCI) Subsystem


The SCI subsystem performs the role of an ACIA in a microprocessor based system. It provides a
simple serial link comprising only of the RxD line (PD0) and the TxD line (PD1). A complete serial
interface with handshaking can make use of the full port D with the other four pins of the port being
used as handshake signals if the SPI subsystem is not being used. Its configuration is fixed at one
start bit, eight or nine bits per character and one stop bit. The baud rate, derived from the enable
clock E, is selected by configuring two fields in the control register BAUD. The Enable frequency E,
is first divided by 16, then further divided by two scale factors in the PreScale (SCP2:SCP0) and
then the Rate Select (SCR2:SCR0) to arrive at the desired baud rate. See the tables below.

BAUD - $102B
TCLR SCP2 SCP1 SCP0 RCKB SCR2 SCR1 SCR0

PRESCALE FACTOR SCI RATE SELECT


E/16 divided by factor PRESCALER output divided by factor
SCP2 SCP1 SCP0 Factor SCR2 SCR1 SCR0 Factor
X 0 0 1 0 0 0 1
0 0 1 3 0 0 1 2
X 1 0 4 0 1 0 4
61
X 1 1 13 0 1 1 8
1 0 1 9 1 0 0 16
1 0 1 32
1 1 0 64
1 1 1 128
To use the SCI subsystem, the receiver section and transmitter section must be enabled
(independently of each other) by setting the bits RE and TE in SCCR2. Note that DDRD0 must be
set to ‘0’ and DDRD1 must be set to ‘1’ for correct operation before the subsystem is used. For any
of the desired industry standard baud rates and given a crystal frequency, it is always possible to find
a suitable combination of the two scale factors. Find the two factors (prescale factor and rate select
factor) which give a baud rate of 1200 bits per second if a 2 MHz crystal is being used.

SCCR1 - $102C
R8 T8 0 M WAKE 0 0 0

SCCR2 - $102D
TIE TCIE RIE ILIE TE RE RWU SBK

SCSR - $102E
TDRE TC RDRF IDLE OR NF FE 0
The register, SCDR at address $102F, doubles up as the receive data register and the transmit data
register and provides the 8 bits to be sent or received. If nine bits per character are required, then the
MORE bits bit M in SCCR1 must be set. The 9th bit is found in SCCR1 for both transmit, T8 and
receive R8. To transmit 9 bits, the 9th bit must be pasted into SCCR1 first, before the other 8 bits are
written to SCDR which initiates the transfer. After receiving nine bits, the 8 bits in SCDR are
received first followed by reading and isolating the ninth bit from SCCR1.
The basic operation (transmit and receive of characters) of the SCI subsystem is similar to that of the
ACIA. Character overruns are indicated by the status bit OR while framing errors are indicated by
the status bit FE in the SCI subsystem status register: SCSR. Note that there is no parity error. The
SCI character frame does not make provisions for a parity bit. This is replaced by the more reliable
noise flag bit NF. With each bit received, starting with the start bit and ending with the last stop bit,
each bit is sampled three times and majority logic is used to determine the state of the bit. If, for any
one bit, the three samples are not all the same, the noise flag bit, NF, is set to indicate the
interference and it is up to the software to decide how to handle this situation.
On the transmitter side, in addition to TDRE, TC is an additional flag which indicates that
transmission is complete and the TxD line will become idle. In the same way, on the receiver side, if
the RxD line is idle for at least the time taken to transmit one complete character, the IDLE status
flag is set. All these conditions have their own separate interrupt enable bits giving a total of four
conditions which can give rise to an interrupt from the SCI subsystem.
The SCI subsystem can be operated in a special receiver wake up mode. In this mode, selected by
setting the bit RWU (Receiver Wake Up mode) in SCCR2, the SCI subsystem is normally set to
sleep. All SCI clocks are switched off to save power, especially useful in remote battery operated
systems. The receiver only wakes up upon receiving a message addressed to it. There are two types
62
of messages, a message being a sequence of characters addressed to a particular slave address. The
bit WAKE (for wake up mode), selects idle line recognition if WAKE is set to ‘0’, or address
mark, if bit WAKE is set to ‘1’. With idle line recognition, message characters are sent without long
idle periods. A long idle period separates messages. Each message is starts with an address, which
each slave compares with its own, to decide to wake up or not. In address mark, the MSB is set with
ASCII text to indicate the beginning of a message which starts with the address in the other 7 bits.
7.11 Synchronous Serial Peripheral Interface (SPI) Subsystem
The SPI interface is becoming very popular for interfacing to a wide range of devices on a system
and is based on a MASTER / SLAVE relationship. It is a four wire interface. Figure 7.4 shows two
MC68HC11 MCUs being linked together through their respective SPI interfaces. Each interface has
the following signals. MISO (Master In Slave Out) on PD2, MOSI (Master Out Slave In) on PD3,
SCK (Synchronous Clock) on PD4 and finally SS (Slave Select) on PD5. A device on an SPI link is
either a master or a slave. Some devices, like the serial SPI EEPROM, to be looked at later, is always
a slave. DDRD must be configured correctly depending on whether the device is a master or a slave.
The master generates the synchronous clock which is input to and used by the slave. The Master also
generates the slave select which is an input to the slave.

MISO MISO

MOSI MOSI

SPDR SPDR
SS SS
MASTER SPI SLAVE SPI
SPI Clock
Generator SCK SCK

Figure 7.4 SPI to SPI connection of Master and Slave


The SPI interface allows one master to control several slaves through slave select inputs. Only the
selected slave participates in the byte exchange, other slaves ignoring the transaction. The low active
slave select input is used to indicate which slave has been selected. The master generates a
synchronous clock which is used by the slave. Both the Master and the slave each has an 8 bit shift
register. Figure 7.4 shows that the two shift registers are connected in series and since they share the
same clock, act as one long 16 bit shift register. Before an exchange takes place, the master activates
the SS line, and both systems write 8 bit values to their SPI data registers – SPDRs. These values are
automatically transferred to the respective shift registers. The slave must write to its SPDR first in
anticipation of a byte exchange. The master write to its SPDR initiates the byte exchange. The master
generates 8 clock pulses to move data 8 places in the 16 bit shift register. This causes a byte
exchange after which the local shift register contents are transferred to the local SPDR. At the end of
each exchange, the status flag bit, SPIF, in the status register SPSR is set. This causes the local CPU
to read its SPDR either through polling or as a result of an interrupt. After the end of the exchange
63
typically the master will deactivate the slave select control line. The frequency of the synchronous
clock is derived from the Enable clock frequency. Bits SPR1:SPR0 in the SPI control register SPCR.
The SPE bit in that register enables the SPI subsystem when set while the bit MSTR sets the SPI as a
master when set and as a slave when cleared. Bit DWOM sets the entire port D to be an open drain
port, when set. Bit SPIE enables SPI interrupts when set.

In most practical situations, data transfer is required in only one direction, i.e. from the master to the
slave or the other way round. Any dummy byte can be transferred in the direction in which it is not
required. A write collision, which can only occur at the slave, is the result a write to the SPDR
during an SPI transfer and this corrupts both bytes at both ends. WCOL in SPSR indicates this
condition. A mode fault (MODF) occurs when a master is selected by another device to be its slave.
This causes the SPI subsystem to shut down and can only be rectified by disabling and re-enabling
the SPI.

SPCR - $1028
SPIE SPE DWOM MSTR CPOL CPHA SPR1 SPR0

SPSR - $1029
SPIF WCOL 0 MODF 0 0 0 0

There are two different clock polarities and two different clock phases giving a total of four different
timings for transfers. This makes the SPI flexible enough to interface with any other system,
irrespective of the requirements of its timing specifications. If CPOL is ‘0’, the synchronous clock
idles at ‘0’ while if it is set to ‘1’, the clock idles at ‘1’. See figure 7.5. If the clock phase CPHA is
set to ‘0’, then the first bit is ready as soon as the slave select line is activated before the first clock
edge. The very first clock edge is used to sample and clock the 16-bit shift register. If CPHA is ‘1’,
however, the second clock edge is the one that samples and clocks the 16-bit register. In most
practical situations, there is only one master and one slave. It is possible to permanently ground the
slave select input of the slave, provided the clock phase is set to ‘1’. If CPHA is set to ‘0’, the slave
select line must be deactivated at the end of each byte exchange. However, this is not always
possible. Each slave SPI device will have a detailed description of its operation as shall be seen for
the serial EEPROM.

SPI CYCLE 1 2 3 4 5 6 7 8
CPOL = ‘0’

SCK
CPOL = ‘1’
CPHA = ‘0’
MSB BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 LSB

MSB BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 LSB


CPHA = ‘1’

SS
Figure 7.5 SPI exchange timing

64
Turning to the block diagram of figure 7.4, assuming that the SCI subsystem is being used at both the
master and the slave, we can work out the initial values at both ends to be set during initialisation in
the control registers. Assume a baud rate of 9600 bps in both cases. Basic assumptions can be made
about the other parameters like the SPI rate etc.

MASTER SLAVE
BAUD $QQ BAUD $QQ
DDRD $QQ DDRD $QQ
SCCR1 $QQ SCCR1 $QQ
SCCR2 $QQ SCCR2 $QQ
SPCR $QQ SPCR $QQ
The following subroutine can be used at both the master and the slave for an SPI exchange. ACCA
brings in the value to be exchanged and returns the value received.

SPSR EQU $1029


SPI_COMPLETE EQU $80 ; SPIF is bit number 7
; ACCA <= byte to be exchanged; byte received => ACCA
; initiates byte exchange at the master; – anticipates at the slave
SPI_EXCHANGE STAA SPDR
SPI_LOOP LDAA SPSR ; sense status loop
BITA #SPI_COMPLETE
BEQ SPI_LOOP
SPI_DONE LDAA SPDR ; load he return value
RTS

The master is responsible for activating the slave select input before the exchange and deactivating
the control after the exchange. The code below assumes that Index Register X has been loaded with
the start address of the internal configuration registers, either $1000 (default) or $9000 (relocated).

SPI_TRANSFER BCLR $00,X $80 ; activates SS before exchange


BSR SPI_EXCHANGE
BSET $00,X $80 ; deactivates SS after exchange
RTS

7.12 8 bit Analogue to Digital Converter (ADC)


The microcontroller has an 8-bit successive approximation analogue to digital converter (ADC)
which is shared by 8 analogue input channels on port E. It has an internal sample and hold. It is
powered up by setting the bit ADPU in OPTION. If the enable frequency is less than 750kHz, the bit
CSEL, in the register OPTION, must be set to select an internal RC oscillator (running at about 2.5
kHz) to drive the internal charge pump circuit which generates the large voltage required for the
analogue multiplexer. This same voltage is used for programming the internal EEPROM. The
reference voltages are applied to the pins VRH and VRL and therefore determine the allowable
analogue input range. It is common practice to ground VRL and tie VRH to the 5 volt supply. The
maximum supply voltage on VRH is 6 volts. The ADC is linear between VRH and VRL. The 8-bit
unsigned positive results are left in the result registers: ADR1 through ADR4 at addresses $1031
through $1034.
65
It is recommended to include a 1 k resistor in series with the input to minimise the damage to each
input should the input voltage become large negative. Also a capacitor can be connected between
each analogue input pin and ground of approximately 0.01 F. The RC circuit at the input, will act as
a low pass filter. The RC time constant may need to be adjusted to handle the frequency range of
input.

ADCTL - $1030
CCF 0 SCAN MULT CD CC CB CA

Chn Channel Result Chn Channel Result Chn Channel Result


Code Code Code
0000 AN0 ADR1 0100 AN4 ADR1 1100 VRH ADR1
0001 AN1 ADR2 0101 AN5 ADR2 1101 VRL ADR2
0010 AN2 ADR3 0110 AN6 ADR3 1110 VRH/2 ADR3
0011 AN3 ADR4 0111 AN7 ADR4 1111 Reserved ADR4
CCF is the conversion complete flag which signifies that the result registers can be read. Bit CCF
does not have an interrupt enable bit and it cannot cause interrupts. Polling has to be used to manage
ADC conversions. The channel select bits select a channel or group of channels for conversion. The
bit SCAN, when set programs continuous scanning which updates the result registers with the most
up to date results. Otherwise when the bit is reset, only one conversion takes place. The bit MULT,
when set to ‘1’ selects a group of four channels for conversion with results left in separate result
registers. If the bit is cleared, only one channel is converted four times with the four results left in the
four result registers. A conversion is initiated by a write to ADCTL with the desired operation and
channel selection. For each analogue to digital conversion, the first 12 E cycles are for sampling and
holding. An additional 20 E cycles are required for the successive approximation conversion.
Therefore, the analogue to digital conversion takes a fixed amount of time for each result.

Write a temperature control program for an oven (or water bath) operating between 69 oC and 71oC
with a set point of 70oC. Assume an LM35 temperature sensor with an output which is linear
between 0V at 0oC and 1V at 100oC. Assume a positive gain of +5 in a non-inverting amplifier before
the analogue input channel. See figure 7.6.

vo
5V OVEN
MICROCONTROLLER
A PE0
3.5V
DC LM35

PA0
o o HEATER
70 C 100 C
T
Figure 7.6 Temperature Control of an oven or water bath
66
Solution
Figure 7.6 shows a linear temperature characteristic, after amplification, which passes through the
two points: [0oC, 0V] and [100oC, 5V]. At 70oC the output is 3.5 V. Similarly at 69oC and 71oC the
output voltages are 3.45 V and 3.55 V respectively. Since the 8-bit ADC is linear, the output results
for the three values are as follows: 3.5V => $B3, 3.45V => $B0, 3.55V => $B5, These results are
obtained from using the formulae: vin / 5V = digital result / 255. From this, the temperature control
program follows:

TEMP_MAX EQU $B5


TEMP_MIN EQU $B0
ORG $F280
TEMP_CONTROL CLR ADCTL ; channel 0, single scan on one channel
WAIT_CCF LDAA ADCTL ; sense status loop
BITA #$80 ; CCF is bit 7
BNE WAIT_CCF ; wait for conversion complete flag
LDAA ADR1 ; read the converted result
CMPA #TEMP_MAX
BHI SWITCH_OFF
CMPA #TEMP_MIN
BLO SWITCH_ON
BRA TEMP_CONTROL ;take another reading
SWITCH_OFF LDAA PORTA
ANDA #$FE ; clear bit PA0
STAA PORTA
BRA TEMP_CONTROL
SWITCH_ON LDAA PORTA
ORAA #$01 ; set bit PA0
STAA PORTA
BRA TEMP_CONTROL

7.13 Internal EEPROM


There are 512 bytes of internal EEPROM with the internal configuration register CONFIG, being
also implemented in EEPROM. In single chip modes, the EEPROM is fixed to occupy the address
range $FFE0 through $FFFF. In the expanded and test modes, the EEPROM is relocatable to occupy
the range $xE00 through $xFFF. x is determined by the values EE3:EE0 programmed into the
register CONFIG. The bit EEON in that register, if set, enables the EEPROM into the memory map
of the microcontroller.

CONFIG - $103F
EE3 EE2 EE1 EE0 1 NOCOP 1 EEON

BPROT - $1035
0 0 0 PTCON BPRT3 BPRT2 BPRT1 BPRT0

PPROG - $103B
ODD EVEN 0 BYTE ROW ERASE EELAT EEPGM
67
The on chip charge pump produces the high voltage required for programming and erasing the
EEPROM. If the E frequency is less than 1 MHz, bit CSEL must be set to select the internal RC
oscillator to drive this charge pump. The bit PTCON protects the configuration register against
changes if the bit is set. When cleared, the register can be changed. The other four bits in BPROT are
used for determining which blocks can be programmed and erased and which are protected. These
bits are time protected and can only be written to ‘0’ within the first 64 Enable cycles after a
hardware reset in normal modes. This disables protection. They can, however be written to ‘1’ at any
time to re-enable the protection. See the table below for the block protection.

CONTROL BIT Protected Block Block Size


BPRT3 $xEE0 to $xFFF 288 bytes
BPRT2 $xE60 to $xEDF 128 bytes
BPRT1 $xE20 to $xE5F 64 bytes
BPRT0 $xE00 to $xE1F 16 Bytes
Programming and erasing operations require the use the internally generated high voltage and of two
latches around the EEPROM. These are an 8-bit data latch and a 16 bit address latch. To prevent
inadvertent erase or program operations, a strict sequence must be followed for each operation. The
bits in the register PPROG are used for erase and program operations. Note that during the erase and
program cycles, the EEPROM is not available in the memory map for reading in the normal way
because of the two latches. The following are the two sequences to be followed.

For program operations

 write to PPROG with bit EELAT set – introduce the two latches
 write the data to the desired address – these are stored in the respective latches
 set bit EEPGM – this activates the high voltage and begins the programming cycle
 wait for 10 ms for the operation to complete (20 ms for low voltage operations)
 clear the bit EEPGM to remove the programming voltage
 clear the bit EELAT to remove the two latches from around the EEPROM.

For erase operations

 write to PPROG with bits ERASE and EELAT set – also set the bit BYTE and ROW as
appropriate
 write any data to the desired address(es) – these are stored in the respective latches
 set bit EEPGM – this activates the high voltage and begins the programming cycle
 wait for 10 ms for the operation to complete (20 ms for low voltage programming)
 clear the bit EEPGM to remove the programming voltage
 clear the register PPROG

It is common practice to develop subroutines for erasing a byte, a row or the entire EEPROM.
Another subroutine can be developed for programming a byte. ACCA and IX can be used to pass the
data byte to be written and the address respectively. To erase just one byte, set the bit BYTE in
PPROG. To erase just one row, clear BYTE but set the bit ROW. The erase the entire EEPROM (a
bulk erase), clear both bits: BYTE and ROW. The subroutines for programming and erasing bytes,
rows and the bulk erase are given below.
68
PPROG EQU $103B
; ACCA <= byte to be programmed
; IX <= address to which the byte is to be programmed
PROGRAM_BYTE PSHA ; save temporarily byte to be programmed
LDAA #$02 ; set bit EELAT to bring in latches
STAA PPROG
PULA ; restore byte
STAA $00,X ; write byte to address
LDAA #$03 ; set bit EEPGM – apply programming
voltage
STAA PPROG
JSR DELAY_10 ; wait 10 ms
LDAA #$02 ; remove programming voltage
STAA PPROG
NOP
CLR PPROG
RTS
; IX <= address of the byte to be erased
BYTE_ERASE LDAA #$16 ; ERASE mode and bring in latches
STAA PPROG
STAA $00,X ; write any byte to address
LDAA #$17 ; set bit EEPGM – apply programming
voltage
STAA PPROG
JSR DELAY_10 ; wait 10 ms
LDAA #$16 ; remove programming voltage
STAA PPROG
NOP
CLR PPROG
RTS
; IX <= any address in the row range of the row to be erased
ROW_ERASE LDAA #$0E ; ERASE mode and bring in latches
STAA PPROG
STAA $00,X ; write any byte to address
LDAA #$0F ; set bit EEPGM – apply programming
voltage
STAA PPROG
JSR DELAY_10 ; wait 10 ms
LDAA #$0E ; remove programming voltage
STAA PPROG
NOP
CLR PPROG
RTS
; IX <= any address in the EEPROM address range
BULK_ERASE LDAA #$06 ; ERASE mode and bring in latches
STAA PPROG
STAA $00,X ; write any byte to address

69
LDAA #$07 ; set bit EEPGM – apply programming
voltage
STAA PPROG
JSR DELAY_10 ; wait 10 ms
LDAA #$06 ; remove programming voltage
STAA PPROG
NOP
CLR PPROG
RTS

7.14 16 bit Main Timer Counter, Pulse Accumulator and Real Time Interrupt (RTI)
The timer subsystem is centred around the free running 16 bit main timer counter register TCNT. It
is cleared by a hardware reset. In a sense it can be considered to provide a sense of real time which
can be measured by reading its value. The two bits PR1:PR0 in the register TMSK2 (timer mask
register number 2) determine the clock which drives the 16 bit counter. See table on the next page.
With each clock tick, the register is incremented until its gets to $FFFF and then rolls over to
$0000 – i.e. it overflows. With each roll over or overflow, the flag bit TOF, in TFLG2 (timer flags
register number 2), is set. If TOI in TMSK2 is set, an interrupt occurs each time TOF is set. The
interrupt can be used to increment another memory location (or several memory locations), cleared
after a hardware reset by user software, to increase the size of the effective main timer counter
register to record time over longer intervals. The time interval between the main timer counter
overflows is constant and depends only on the two bits PR1:PR0. In a sense, it is a real time
interrupt, which could be used to measure real time. The 16-bit value in TCNT is central to the
operation of input capture and output comparison operations to be described in the next section.
TCNT cannot be written to! It can only be read from.

TCNT Prescaler (E) RTI Scaler COP Scaler


PR1:PR0 Factor RTR1:RTR0 Rate CR1:CR0 Rate
00 1 00 E/213 00 E/215
01 4 01 E/214 01 E/217
10 8 10 E/215 10 E/219
11 16 11 E/216 11 E/221

The Real Time Interrupt, RTI, is another periodic interrupt, with its own separate scaler, whose
scale factor is determined by the bits RTR1:RTR0 in in the control register PACTL. The real time
rate is given in the table above. This determines the rate at which the real time interrupt occurs. Each
time the interrupt occurs, the flag bit RTIF (in TFLG2) is set, and if RTII (in TMSK2) is set, an
interrupt will occur. Typically the real time interrupt is used to maintain the system clock. With fine
adjustments, it can provide a clock which loses or gains less than one second in 24 hours!! This real
time clock would be managed by the interrupt service routine of the real time interrupt. Below is
shown an example of such a real time interrupt. It uses binary coded decimal for the representation of
hours, minutes and seconds to simplify the update of the time, which is much easier to display. The
library routine display_8 can be used to display the binary coded decimal values of the hours,
minutes and seconds since it treats each nibble independently, displaying the corresponding
(hexa)decimal digit.
70
ADJUST RMB 1
TIME_OUT RMB 1
SECONDS RMB 1
MINUTES RMB 1
HOURS RMB 1
RTI_ISR LDAA #$40
STAA TFG2
DEC TIME_OUT
BEQ SECS_UPDATE
RTI
SECS_UPDATE LDAA #$07
STAA TIME_OUT
DEC ADJUST
BNE SECS
LDAA #$0B
STAA ADJUST
RTI
SECS LDAA SECONDS
CMPA #$59
BEQ MINS
ADDA #$01
DAA
STAA SECONDS
RTI
MINS CLR SECONDS
LDAA MINUTES
CMPA #$59
BEQ HRS
ADDA #$01
DAA
STAA MINUTES
RTI
HRS CLR MINUTES
LDAA HOURS
CMPA #$23
BEQ DATE
ADDA #$01
DAA
STAA HOURS
RTI
DATE CLR HOURS
INC DAYS
RTI

71
The Pulse Accumulator is an 8-bit counter register which can be written to and read from. It is
enabled by setting the bit PAEN in PACTL. It can be incremented by a clock input through PA7
programmed as an input. The active edge which causes the register to be incremented is determined
by bit PEDGE. If PEDGE is ‘0’, the falling edge is active while if PEDGE is ‘1’, the rising edge is
active. This is referred to as the event counting mode which is the case when PAMOD is set to ‘0’.
The other mode, when PAMOD is set to ‘1’, is gated time accumulation mode. In this mode, the
pulse accumulator is incremented by an internal clock at 1/64 of the enable frequency. This mode
can be used to measure pulse widths of waveforms applied on PA7 configured as an input. PEDGE
determines whether counting occurs on not. If PEDGE is set to ‘0’, then counting is inhibited when
PA7 is ‘0’ and enabled when PA7 is ‘1’. If PEDGE is ‘1’, a ‘1’ on PA7 inhibits counting while a ‘0’
enables counting. Each time the pulse accumulator rolls over from $FF to $00, the flag PAOVF
(pulse accumulator overflow flag) is set in TFLG2. If bit PAOVI is set in TMSK2, an interrupt
occurs each time PAOVF is set. The associated interrupt service routine could be used to increment
another memory location, or several other memory locations, to effectively increase the size of the
pulse accumulator beyond 8 bits.
The second flag of the pulse accumulator is PAIF in TFLG2. Its interrupt mask is PAII in TMSK2.
This flag is set when PA7 changes from the enable mode to the inhibit mode. This would allow the
interrupt service routine to calculate the width of a pulse in gated time accumulation mode. In event
counting mode, the flag is set by the selected edge and the interrupt handler would be used to register
the event.

7.15 Input Capture and Output Comparison


Port A inputs can be operated as general purpose inputs and outputs as determined by the bits in
DDRA. However, Port A pins can be programmed to act as input capture channels or output
comparison channels with events being related to the value of the 16-bit main timer counter register
TCNT. There are four input capture channels as follows: IC1 (PA2), IC2 (PA1), IC3 (PA0) IC4
(PA3). There are five output comparison channels as follows: OC1 (PA7), OC2 (PA6), OC3 (PA5),
OC4 (PA4) and OC5 (PA3). Note that PA3 is either input capture or output comparison and its
direction is determined by the data direction bit I4/O5 in PACTL.
Each input capture channel has its own 16-bit capture register. Two bits (EDGnB:EDGnA) are
reserved for each channel in the register TCTL2 to select none, one or both edges as active edges.
See the table below. Each time an active edge occurs, the value of TCNT is transferred to the
respective input capture register for the channel. This records the exact instant (time) an input event
occurred. This can later be referred to an output comparison outgoing event with a defined delay in
between. When an active edge occurs, the corresponding flag bit in TFLG1 is set, and if enabled by
the corresponding interrupt enabled bit in TMSK1, an interrupt will occur. Flag bits must be cleared
either in a polling routine or in the interrupt service routine by writing a ‘1’ into the position of the
flag bit. Writing a ‘1’ against the bit clears the flag.

Input Capture Codes and Behaviour Output Comparison Codes and Behaviour
EDGnB:EDGnA Behaviour OMn:OLn Behaviour
00 Capture Disabled 00 Comparison Disabled
01 Rising Edges 01 Toggle
10 Falling Edges 10 Clear Line to ‘0’

74
11 Both edges 11 Set Line to ‘1’

Each output comparison channel has its own 16-bit comparison register. Two bits (OMn:OLn) are
reserved for each channel in TCTL1 to determine whether the output comparison channel output
does not change, changes to ‘1’, changes to ‘0’, or always changes each time there is a match when
comparing the TCNT value and that of its comparison register. Hardware automatically performs this
comparison for all output comparison channels each time TCNT is incremented. Each time there is a
comparison match, the corresponding flag in TFLG1 is set and if the interrupt enable bit for the flag
is set in TMSK1, an interrupt will occur. Again, the interrupt service routine (or the polling routine)
clears the flag bit by writing a ‘1’ against it in the timer flags number 1 register (TFLG1).
Input capture can be combined with output comparison to ensure that there is a fixed delay time
between an incoming event (as captured by an input capture channel) and a corresponding outgoing
event (as programmed on an output comparison channel).
The output comparison channels can be used to generate square waveforms or rectangular
waveforms (with different mark space ratios) and with different frequencies. An output comparison
channel can be used to vary the speed of a DC motor which depends on the DC voltage applied
across it. This can be achieved by producing a rectangular waveform whose mark space ratio is
related to the desired speed. Set an output comparison channel to always toggle each time there is a
match between TCNT and the output comparison timer register and enable its interrupt. Make the
interrupt service routine sense the value of the output after the output comparison action. Schedule
the next toggle by adding the current value in the output comparison register to the desired mark or
space. These can be read from two variables which are fixed in memory. The controlling program
can program any speed by writing two appropriate values to the two variables and the interrupt
service routine does the rest. See the example interrupt handler in the assembly language program
below.

MARK_VARIABLE RMB 2
SPACE_VARIABLE RMB 2
OC2_SPEED_CONTROL LDAA #$40 ; write a ‘1’ against OC2F
STAA TFLG1 ; to clear flag OC2F in
TFLG1
LDAA PORTA
BITA $40 ; check what PA6 changed to
BEQ SCHEDULE_SPACE
SCHEDULE_MARK LDD MARK_VARIABLE ; PA6 changed to ‘1’
ADDD TOC2 ; ignore any carry
STD TOC2
RTI
SCHEDULE_SPACE LDD SPACE_VARIABLE ; PA6 changed to ‘0’
ADDD TOC2 ; ignore any carry
STD TOC2
RTI

7.16 Expanded Mode Operation


The MC68HC11 microcontroller, when operated in expanded mode, acts like a glorified
microprocessor with built in I/O. Memory, external to the microcontroller is required. This is mainly
75
volatile and non-volatile memory, i.e. RAM and some form of read only memory. Additional I/O
devices may also be added over and above those already on board. A 16-bit address bus, an 8-bit data
bus and control signals for bus access like R/W and E are required. There will be need for an external
data bus transceiver, external address buffers or latches and memory address decoding. If one or two
extremely slow external devices (with large access times) must be mixed with faster devices, then the
slower devices typically slow down the bus cycle by de-activating a signal like MRDY on the
MC6809 microprocessor. The bus cycle is stretched indefinitely until the memory or I/O device is
ready and external logic is normally used for this. This is called clock stretching. Conventional
memory address decoding also requires a lot of external discrete gates which increase the size of the
system and slows it down in addition to making it more expensive. The MC68HC11F1N3 version
includes on board all the logic for memory address decoding, clock stretching, polarity selection,
base address of each memory and I/O device and the size of each range. This logic is very flexible
and is programmable to suit different designs. Integrating this flexible logic on board allows high
speed operation, lower cost and smaller size. There are four such internally generated control signals
on Port G. Each can be independently enabled for that function or can revert to being a general
purpose input/output pin. These are:

 CSPROG – (chip select for program memory) on PG7, this low active only chip select is
meant for the external EPROM or EEPROM which houses the system program.
 CSGEN– (general chip select) on PG6. This is best used for additional external RAM when
the internal RAM is not adequate for the control application. It can also be used for an
additional extra external larger EEPROM. It can be programmed to be high active or low
active.
 CSIO1– (chip select for an additional I/O device) on PG5. This flexible pin can be
programmed to be high active or low active. A narrow range of memory is reserved in a fixed
place in the same page as that of the internal configuration and control registers to reduce
wastage of memory address space. The memory range is $x060 through $x7FF. The
internal configuration registers occupy the address range $x000 through $x05F.
 CSIO2 – (chip select for another additional I/O device) on PG4. Identical in operation to
CSIO1 except that its reserved address range is $x800 through $xFFF. The internal
configuration registers and the two I/O devices therefore occupy a 4 kilobyte block which
each I/O device occupying quite a large address range. External additional decoding can be
used for each I/O chip select and its range so that several I/O devices can be accessed through
each. Design this for two ACIAs on CSIO1 and two PIAs on CSIO2.

It is possible for different memory ranges to overlap. This is so given that internal EEPROM, internal
RAM and the configuration registers and external I/O devices, external RAM, and external ROM
have ranges which are programmable. There are two default priorities which have been allocated
depending on the value of the bit GCSPR (General Purpose Chip Select Priority) in the register
CSCTL (chip select control). See the two tables below. An address in an overlapping range will
access the higher priority device.
Chip Select Priorities Clock Clock
GCSPR = 0 GCSPR = 1 Stretch Stretch
On-Chip Registers On-Chip Registers Bits A,B
On-Chip RAM On-Chip RAM 00 0 E Cycles
Bootloader ROM Bootloader ROM 01 1 E Cycle
On-Chip EEPROM On-Chip EEPROM 10 2 E Cycles

76
I/O Chip Selects I/O Chip Selects 11 3 E Cycles
Program Chip Select General-Purpose Chip Select
General-Purpose Chip Select Program Chip Select

Each external memory and I/O device can be programmed for clock stretching up to a maximum of
three additional Enable clock cycles. See figure 7.7.

No clock stretching AB = 00 3 E cycle stretching AB = 11

1 E cycle stretching AB = 01 2 E cycle stretching AB = 10


Figure 7.7 Clock Stretching with large access time devices

The chip select control register CSCTL allows each of the internal I/O controls to be enabled by
setting its enable bit to ‘1’. The default value after hardware reset for each is ‘0’, thus disabling it.
The active polarity for each control is also set in each register. ‘0’ configures a low active select
while ‘1’ configures a high active select.

Four sizes are defined and can be programmed for the low active only program chip select. All end at
$FFFF to accommodate the reset and interrupt vectors. See the table below. The program space is
either the entire 64K address space, the last half, the last quarter or the last eighth of memory.

PSIZA PSIZB Size Address Range


0 0 64 Kbytes $0000 to $FFFF
0 1 32 Kbytes $8000 to $FFFF
1 0 16 Kbytes $C000 to $FFFF
1 1 8 Kbytes $E000 to $FFFF

CSSTRH Clock Stretching $105C


IO1SA IO1SB IO2SA IO2SB GSTHA GSTHB PSTHA PSTHB

CSCTL Chip Select control $105D


IO1EN IO1PL IO2EN IO2PL GCSPR PCSEN PSIZA PSIZB

CSGADR General Purpose Chip Select Starting Address $105E


GA15 GA14 GA13 GA12 GA11 GA10

CSGSIZ General Purpose Chip Select Size Register $105F


IO1AV IO2AV GNPOL GAVLD GSIZA GSIZB GSIZC

For the general purpose chip select, CSGADDR defines the start address of the range for that
memory or I/O device. The actual size is determined by the bits GSIZA:GSIZB:GSIZC in the control
register GCGSIZ. See the tables below.
77
General Purpose CS Starting Address General Purpose CS Size Control
CSGEN Block Size CSGADR Bits Valid GSIZ[A:B:C] Address Size
0 Kbytes None 000 64 Kbytes
1 Kbytes GA15-GA10 001 32 Kbytes
2 Kbytes GA15-GA11 010 16 Kbytes
4 Kbytes GA15-GA12 011 8 Kbytes
8 Kbytes GA15-GA13 100 4 Kbytes
16 Kbytes GA15-GA14 101 2 Kbytes
32 Kbytes GA15 110 1 Kbytes
64 Kbytes None 111 0 Kbytes
(Disabled)

7.17 Bootstrap Mode


When the MCU is reset in the special bootstrap mode, a small on-chip ROM is enabled at address
$BF40–$BFFF. Sometimes the range is $BF00-$BFFF. The reset vector is fetched from this
bootstrap ROM, and the MCU proceeds to execute the firmware in this ROM. The program in this
ROM initializes the on-chip SCI system, accepts a variable length program of raw data bytes (not
encapsulated in Motorola S format or Intel Hex format records) through the SCI, and then jumps to
the loaded program at address $0000 in the on-chip RAM. During this download, there should be no
large gaps between the raw data bytes which are being loaded. The bootloader waits for a significant
delay after the last raw data byte downloaded to determine that there are not more bytes following.
There are almost no limitations on the programs that can be loaded and executed through the
bootstrap process. While the MCU is operating in bootstrap mode, the MDA control bit can be
written; thus, it is possible to turn on the multiplexed expansion bus. This possibility makes the
bootstrap mode useful in both single-chip and expanded systems. In some systems, it may be
necessary to disable the bootstrap ROM by writing a zero to the RBOOT control bit to allow access
to external devices in $BF40–$BFFF. If the bootstrap ROM is disabled, it is necessary for the user to
externally provide reset and interrupt vectors at $BFC0–$BFFF or switch the SMOD control bit back
to zero so interrupt and reset vectors return to $FFC0–$FFFF.

The bootloader ROM program initializes the SCI so that the receiver and transmitter are enabled and
the baud rate is E clock/16/16 (7812 baud if E = 2 MHz). A break character is then transmitted. For
normal use of the bootloader, the user then sends an $FF character at a baud rate of either E
clock/16/16 (7812 baud if E=2 MHz) or E clock/16/13 (1200 baud if E = 2 MHz). This initial
character is used to establish the baud rate for the rest of the transfer and is not echoed to the
transmitter as the remaining characters are. Note that bit DWOM is set and pullup resistors are
required on PortD, at least for TxD.

Other Applications of the Bootstrap Mode


In an end user system, the system software would normally be resident on the on CHIP EPROM or
custom ROM. Special diagnostics, which are not resident on the system can be downloaded in
bootstrap mode and used to exercise the system to perform any tests as may be required from time to
time. The bootstrap mode is especially useful for programming the internal EEPROM.
During the development of a new system, the bootstrap mode, which has a fast turnaround time can
be used to exercise the system and obtain system parameters or determine the operational mode of
the system and this information documented. Gathered information during this process can then be
used in the development of the final system with complete confidence that the final system will work
as desired.
When the microcontrollers ICs have been fabricated from the semiconductor foundry, they must be
tested for functionality before the costly packaging process can begin. Faulty chips are discarded. A
test rig is set up to test for the functionality of the different systems. This includes testing for the
integrity of the internal EEPROM, testing the linearity of and the correct functioning of the analogue
78
to digital converter and any other tests. These tests can be carried out by successively loading into
RAM the various test programs, one after the other for the different subsystems. Only after an
unpackaged chip has successfully passed all the required tests will it be accepted for packaging.
The bootstrap mode can be used for calibrating instruments in situ.
In the hardware design of an HC11 microcontroller based system, there must be flexible hardware
facilities which allow for the end user to decide which mode of operation is going to be used through
the use of hardware jumpers, or links, together with the use of pull up resistors.

79
Chapter Eight: 25LC640 Serial EEPROM
8.1 Introduction
The 25LC640 is a 64 kilobyte serial EEPROM comprising 8192 bytes of storage housed in an 8 pin
DIP package. It addresses these bytes in the range $0000 through $1FFF. The three most
significant address bits are therefore always ‘0’s. It is constructed out of CMOS technology and
interfaces to a controlling microcontroller using the 4 pin SPI interface. It is always an SPI slave
device with its low active chip select input, CS, being the equivalent of slave select SS. In addition it
has a low active write protect input, WP, and a low active hold control: HOLD. Access to internally
stored data is sequential for both reading and writing. However, after each sequential read or write, it
is possible to jump to another random address for another serial read or write. Figure 8.1 shows the
pin configuration of the chip together with its interfacing to the MC68HC11 microcontroller.

After power up, the chip select input, CS, must make a high to low transition before the serial
EEPROM can be used. The chip select input allows several EEPROMs to be connected in parallel on
the SPI bus since, when deselected, its serial output line, SO, is driven into the high impedance state
(i.e. floats). Figure 8.2 shows SPI timing for read and write operations. Note that serial data is
sampled or clocked on the rising edge of the synchronous clock, SCK, and serial data bits change on
the falling edge of the clock. The synchronous clock is seen to idle at ‘0’. The microcontroller SPI
interface must therefore be programmed so that CPOL = ‘0’ and CPHA = ‘0’.

CS

CPOL = ‘0’
CPHA = ‘0’

MSB BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 LSB


Figure 8.2 SPI Serial Data timing

8.2 EEPROM Instructions


The 25LC640 has six instructions. Two instructions are for reading and writing data from and to data
memory. Two instructions enable and disable the write enable latch. The last two are for reading and
writing to an internal 8-bit status register. The six instructions and their codes are given in table 8.1.
The write enable latch is a protective measure to prevent accidental writes to the EEPROM and is an
additional measure over and above the block protection of selected ranges of the memory. To write
to either the status register or to data memory, the write enable latch must be enabled. This is done

80
by sending the instruction code $06 to the serial EEPROM in an SPI byte exchange. The CS input
must be activated to ‘0’, followed by the byte exchange, followed by deactivating of CS back to ‘1’.
That sequence causes the write enable latch to be enabled. It can be disabled by sending the
instruction code $04 through a similar byte exchange. The write enable latch is disabled after the
device is powered up. It is also disabled after a successful write operation to either the status register
or to data memory. The state of the write enable latch is recorded by the bit WEL (write enable latch)
in the status register.

Table 8.1 25LC640 Instructions


Instruction Instruction Code Instruction Description
Name
READ 0000 0011 $03 Read data from memory starting at selected address
WRITE 0000 0010 $02 Write data to memory starting at selected address
WREN 0000 0110 $06 Set the Write enable Latch (enable write operations)
WRDI 0000 0100 $04 Reset the Write Enable Latch (disable write operations)
RDSR 0000 0101 $05 Read from Status Register
WRSR 0000 0001 $01 Write to Status Register

8.3 Reading Data from the EEPROM


Figure 8.3 shows the sequence of SPI byte exchanges required to read data from the serial EEPROM.
First, the chip is selected. This is followed by sending the read command $03 to the serial EEPROM
in an SPI byte exchange. This is followed by two SPI byte exchanges for the upper and lower
address bytes in that order. Any further byte exchanges thereafter return the data stored starting with
the byte at the specified starting address. Bytes from consecutive memory locations are read in series
for as long as they are byte exchanges. A byte exchange will occur with every 8 SCK clock pulses.
The reading of bytes will only stop after the CS input goes back to ‘1’. There is no limit on the
number of bytes which can be read in one read operation. After the last byte at address $1FFF has
been read, the internal address counter rolls over to $0000 and reading of bytes continue.

CS

SCK 0 1 2 3 4 5 6 7

SI 0 0 0 0 0 1 1 0

SO
Figure 8.4 Write Enable Latch Instruction

81
8.4 Writing Data to the EEPROM
To write a block of data to the EEPROM, first the write enable instruction is issued and CS must go
high to enable the latch after the byte exchange of the instruction code $04 as depicted in figure 8.4.

The chip is selected again for the write sequence which begins with the exchange of the write
command $02, followed by the higher order address byte, then the lower order address byte.
Thereafter the data bytes to be written, starting at the specified address, are in further byte exchanges
until the last byte has been written. A maximum of 32 bytes can be written in any one page write
sequence. The 32 bytes must reside in the same 32 byte page. A 32 byte page will have only the least
significant 5 bits changing from all 0s to all 1s with the higher order address bits remaining fixed. If
the last address of the page is reached and further byte exchanges occur, a roll over to the first
address of the page occurs. While writing is in progress, the bit WIP (write in progress) in the status
register will be set. It is only cleared at the end of the write operation.

8.4 Data Write Protection


The 25LC640 has a low active write enable input, WE. The 8 bit status register has a high active
WREN (write enable bit). The two are used to implement write protection on two protected bits in
the status register: BP1 and BP0. Table 8.2 shows the selected of areas of memory which are
protected from being written to, based on the combinations of the two block protect bits. Table 8.3
summaries write protection. Note that the protected block as specified by BP1:BP0 will always be
protected. If the bit Write Enable Latch WEL in the status register is ‘0’, no writing can take place
and all memory and the status register will be protected. For the status register bits to be protected
with the write enable latch enabled, then both the write enable WE input must be low and the write
protect enable bit, WPEN, in the status register must be set to a ‘1’.

Table 8.2 Block Protection of memory ranges


BP1 BP0 Protected Block
0 0 None
0 1 Upper ¼ ($1800 - $1FFF)
1 0 Upper ½ ($1000 - $1FFF)
1 1 Entire Memory ($0000 - $1FFF)

Table 8.3 Write Protection Summary


WPEN WP WEL Protected Blocks Unprotected Blocks Status Register BP bits
X X 0 Protected Protected Protected
0 X 1 Protected Writable Writable
1 Low 1 Protected Writable Protected
X High 1 Protected Writable Writable

82
In a real system, subroutines will be developed for write enable latch, write disable latch, read status
register and write status register. There will be two other key subroutines. One subroutine will read a
block of a given number of data bytes from a given specified address. Typically one of the
accumulator registers will bring in the number of bytes to be read while one of the index registers
would bring in the start address of the block within the serial EEPROM to be read. The other
subroutine will write a specified number of bytes starting from the specified address with the use of
similar parameters. All these subroutines, together with assembly language calling code are given
below. The chip select input to the serial EEPROM is assumed to be driven by PD5, the slave select
output of the SPI on the microcontroller. The SPI byte exchange subroutine in section 7.11 is also
assumed to have been given.

PORTD EQU $1008


WRITE_ENABLE PSHA WRITE_DISABLE PSHA
LDAA PORTD LDAA PORTD
ANDA #$1F ANDA #$1F
STAA PORTD STAA PORTD
LDAA #$06 ; WREN LDAA #$04 ; WRDIS
JSR SPI_EXCHANGE JSR SPI_EXCHANGE
LDAA PORTD LDAA PORTD
ORAA #$20 ORAA #$20
STAA PORTD STAA PORTD
PULA PULA
RTS RTS
Subroutines for write enable and write disable
-------------------------------------------------------------------
; ACCB <= no. of bytes to be read ; IX <= start address in SEEPROM
; IX <= start address in SEEPROM ; IY <= start address of source
; IY <= start address of dest. SERIAL_READ PSHA
SERIAL_READ PSHA PSHB ;count value
PSHB ;count value LDAA PORTD
LDAA PORTD ANDA #$1F
ANDA #$1F STAA PORTD
STAA PORTD LDAA #$02 ; WRITE
LDAA #$03 ; READ JSR SPI_EXCHANGE
JSR SPI_EXCHANGE XGDX
XGDX JSR SPI_EXCHANGE
JSR SPI_EXCHANGE TBA
TBA JSR SPI_EXCHANGE
JSR SPI_EXCHANGE PULB ;count value
PULB ;count value WRITE_LOOP LDAA 0,Y
READ_LOOP JSR SPI_EXCHANGE JSR SPI_EXCHANGE
STAA 0,Y INY
INY DECB
DECB BNE READ_LOOP
BNE READ_LOOP LDAA PORTD
LDAA PORTD ORAA #$20
ORAA #$20 STAA PORTD
STAA PORTD PULA
PULA RTS
RTS
;ACCB <= no of bytes to be written
83
Subroutines for reading and writing between RAM and serial EEPROM

84
Chapter Nine: I2C (Inter Integrated Circuit) Interface
9.1 Background
Philips Semiconductors developed the I2C bus. It was developed as a simple interface to allow
several devices on a printed circuit board or in close proximity to communicate using a three wire
bus thus reducing the required number of pins for the interface. In its simplest implementation, this
requires the use of open collector or open drain drivers / receivers on the common bus. One device
normally assumes the role of a master device controlling all data transfers although there can be
several masters on the bus. Additional devices can be easily added onto the I2C bus. There is no
maximum limit on the number of devices connected onto the bus. The limit is determined by a
maximum bus capacitance of 400pF. The Motorola MC68HC11 microcontroller does not have an
inbuilt I2C interface.
9.2 I2C Features and Communication Procedures
In addition to a common ground reference, two bus lines are required. These are a serial data line
SDA and a serial clock line SCL. Both serial lines idle at ‘1’, as all the pull-down transistors of all
the interface devices will be OFF. Each device on the I2C bus is assigned a unique address. To
communicate with another IC (referred to as the slave), the initiating IC (the master) must wait until
there is no bus activity. The initiating IC creates a START condition, followed by transfer of
messages and ending in a STOP condition.
 a transmitter is a device which sends data to the bus.
 a receiver is a device which receives data from the bus.
 a master initiates a transfer and generates the clock signal and terminates the transfer. A
master can operate as a master transmitter or a master receiver.
 a slave is a device addressed by the master. A slave can operate as a slave receiver or a slave
transmitter. A slave can stretch a clock signal when a busy condition arises.
 a multi-master configuration has several masters connected to the bus.
 arbitration is the process of resolving a “collision” in the event two masters initiate transfers
at the same time.
Figure 9.1 shows several I2C devices connected onto the bus through open collector or open drain
drivers. Each output is also connected to an internal receiver since the interface is bidirectional.
VDD
RP RP
SDA

SCL

DATA IN CLOCK IN DATA IN CLOCK IN

DATA CLOCK DATA CLOCK


OUT OUT OUT OUT

2
Figure 9.1 Two I C devices on a common bus
85
When the bus is idle, all the pull-down transistors will be switched OFF and the two lines default to
‘1’s. Any supply voltage can be used through it is normally +5 volts.

SDA
START 1 0 STOP
SCL
(a) (b) (c)
Figure 9.2 (a) START condition (b) Normal Data Clocking (c) STOP condition
Figure 9.2(b) shows that during normal data bit transfer, the data line does not change its state while
the clock line is high. It only changes state when the clock line is low. This rule is only violated
during the START condition (S) (figure 9.2(a)) and the STOP condition (P) (figure 9.2(c)) which
can only be generated by a master device. From the idle condition, a START condition occurs when
the data line changes from ‘1’ to ‘0’ while the clock line remains high. The clock will then go low
and normal data bit transfer can take place. At the end of a message exchange, the STOP condition is
generated by the master when the clock line goes high first followed by the data line going high. A
message frame is therefore encapsulated between a START condition and an STOP condition.
A REPEATED START condition (Sr) can be generated instead of a STOP condition and is
otherwise identical to the normal START condition. This would occur at the end of message
exchange.
A COLLISION occurs when, after a period of idleness, two or more masters on the bus
simultaneously generate the start condition. The two or more masters, which thus collide, will be
able to detect the collision and go through a bus arbitration procedure to determine which master
keeps control of the bus and continues with its transmission (the winner) and which master(s) must
abort its or their transmissions for a later time (the loser(s)). The arbitration procedure is simple.
Devices will generate the SDA and SCL signals as necessary until a device, which has generated a
‘1’ by switching off its pull down transistor senses back a ‘0’, i.e. some other device generated a ‘0’
at that same time. A device, on detecting this condition, will back out of the contention. This carries
on until only one master is left which completes its transmission uninterrupted until its message
exchange is completed.
9.3 Data Transfers
All bytes (whose number is unrestricted) placed in the SDA line are 8 bits long. Each byte is
followed by an acknowledge bit (ACK), the nineth bit, which is a ‘0’. A ‘1’ during the nineth bit is a
negative acknowledge (NAK). Data is transmitted Most Significant Bit (MSB) first. The clock line is
normally generated by the master by switching ON and OFF its clock pull-down transistor. However,
a slave receiver, to force a wait condition, when it is not ready for the next byte transfer, can pull its
clock line low and keep it low and thus pause the master. Data transmission only resumes when the
slave receiver releases the SCL line.
During the acknowledge clock, the transmitter releases the data line to allow the receiver device to
respond by pulling the data line low.
9.4 Addressing
Each device on the bus is assigned a unique address. The master always sends an address after the
start condition to identify a slave device to participate in the message transfer. 7 bit addresses are
used with the eighth bit indicating a Read Operation when ‘1’ or a Write Operation when ‘0’. The
86
addressed device acknowledges its presence by pulling down SDA during the acknowledge clock. If
no such device is using the address, or the addressed device is busy, there will not be an
acknowledge bit and the master generates a STOP condition. 10 bit addresses are also sometimes
used and require two bytes. If the first five bits of the first address byte is the pattern 11110, the
next two bits to make it seven, are the two higher order address bits. These are followed by the R/W
bit and an acknowledge bit. The next byte consists of the lower 8 bits of the address followed by the
acknowledge bit. After the one or two address bytes have been sent, the rest of the message can then
be sent. See figure 9.3

7 bit address 10 bit address


S A6A5A4A3A2A1A0 R/W ACK S 1 1 1 1 0 A9A8 R/W ACK A7A6A5A4A3A2A1A0 ACK
2
Figure 9.3 I C Bus addressing: 7 and 10 bit addresses

With most I2C devices, the first 4 bits of the 7 bit address are fixed as determined by the type of the
device. The other three address bits are determined through DIP switches or jumpers together with
pullup resistors on the printed circuit board, meaning there can be up to 8 devices of the same type
on an I2C bus. The R/W is set to ‘1’ for a read operation and to ‘0’ for a write operation.
Figure 9.4 shows two transmissions of two message exchanges each which incorporate repeated start
and both read and write operations to possibly two different slaves initiated by the same master.

S slave address W A byte A byte A Sr slave address R A byte A byte A P

S slave address R A byte A byte A Sr slave address W A byte A byte A P


2
Figure 9.4 Complete message exchanges on the I C Bus
9.5 I2C Subsystem
For a chip to be connected to the I2C bus, it normally must have an I2C subsystem within itself which
provides the I2C interface. The subsystem can then generate an interrupt to the chip when a byte
transfer is complete. It is therefore a semi-autonomous system which handles all the hardware issues
and only interrupts the processor after completion of a byte transfer. The MC68HC11
microcontroller does not have a built in I2C subsystem and interface. If it became necessary to
connect it to an I2C bus, then open drain pins would have to be allocated for the bus, and software
would have to handle all transfers. Although it can be implemented in software, the overheads
associated with the management of the interface would be too great. Another and better alternative is
to interface the microcontroller (through a parallel bus) to a predesigned standalone I2C interface
module. The Phillips PCF8584 is one such peripheral chip which features the following:
 Parallel bus to I2C bus protocol converter and interface
 Compatible with most microprocessor buses
 Can function as both a master and as a slave
 Automatic detection and adaptation to bus interface type
 Programmable interrupt vector
 Multi-master capability’
 I2C bus monitor mode
 Long distance mode (use of 4 wires)
87
COMPILED

BY

ALI
88

You might also like