Файл: Programming Microcontrollers in C, 2-nd edit (Ted Van Sickle, 2001).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 15.06.2025
Просмотров: 4075
Скачиваний: 1
Input/Output 129
similar to EEPROM and it is inexpensive enough to allow rather large amounts of programmable memory on a microcontroller chip. You will find chips with 30,000 bytes and more of FLASH and the intent is to use these chips for production runs. The FLASH is programmed as part of the production cycle. We will see many details on programming FLASH memory in later chapters.
The architecture of Motorola microcontrollers is strictly Von Neumann. That is, within the microcontroller chip, there is only one data bus over which all program, data, and input/output must pass. In a Harvard architecture system, each of these different data types will have a dedicated bus over which the information will pass. Therefore, the Harvard architecture microcontroller is able to access data, program, and I/O simultaneously. The simultaneous availability of these different data paths can result in a significant increase in overall processor speed. It also increases the area of the microcontroller die and, hence, the cost of the microcontroller. In general, most of the applications to which the microcontrollers are directed do not require extreme speed. Thus, the Von Neumann architecture is completely satisfactory.
Input/Output
The Motorola microcontrollers use an architecture called memorymapped I/O. Each I/O device input and output registers, its control registers, and status registers are mapped into memory locations. I/O transactions require no special computer instructions. It is merely necessary to know the memory locations of the pertinent registers and the uses of the register bits to be able to handle any I/O function. Listed below are brief descriptions of several microcontroller I/O peripherals found on Motorola microcontrollers. Not all of these peripheral systems are found on each microcontroller. It is possible to pick and choose between needs for the several peripheral systems and select a microcontroller that has exactly those peripherals required.
Timer Subsystems
There are four popular timer systems that you will find on different microcontrollers. The first is a general-purpose timer. Motorola refers to the general-purpose timers as either 8- or 15-bit timers. These timers are different. The 8-bit system contains a prescaler that counts down from system clock. The output from the prescaler is fed into a
130 Chapter 3 What Are Microcontrollers?
counter that counts down from it the value stored in it. When the counter underflows, a flag is set, and an interrupt can be executed.
The 15-bit timer is a strictly Motorola name, and it is even simpler than the 8-bit timer. This timer has a 15-bit minimally programmable prescaler. An interrupt can be taken from two locations in this ripple counter.
A second class of timer is the 16-bit timer. This timer is often called a general purpose timer. These timers contain a 16-bit counter that is clocked by the system clock. There are two associated subsystems: the first is called an input capture system, and the second is the output compare.
The input capture system simply captures the value of the system timer counter when an input occurs. These inputs can set a flag or request an interrupt so the input can be processed either synchronously or asynchronously. The important fact is that the exact time of the input relative to the 16-bit clock is saved when the input occurs. Applications for input capture systems are interpulse period measurements or frequency measurements.
The output compare system allows the programmer to specify a time relative to the 16-bit counter when an output is to occur. This time is calculated by adding the time offset value to the current value of the 16-bit counter. This result is stored in the output compare register. When the 16-bit counter counts to the value in the output compare register, the output occurs, a bit is set, and an interrupt can be processed if desired.
Input capture and output compare functions are sometimes called high-speed inputs and outputs. The number of input captures and output compare systems vary from as few as one each to as many as 16 programmable timers, each of which can be either input capture or output compare.
There is another style of timer subsystem that is used on high-end microcontrollers. This system is called the timer processor unit (TPU). In most conventional computers, the contents of a memory location are called an operand, and the processor has built-in operators that operate on the operands. A TPU is also a computer, but rather than using memory location contents as operands, time is the main operand used by the TPU. Most TPUs contain many complex systems to implement their operation. The TPU of the M68300 family and the M68HC16 family contains sixteen registers, each of which can be
Input/Output 131
operated as either an input capture or an output compare. Each output compare can have its events coupled to other registers to control intricate timing events with fine time resolution. We will not see the direct programming of a TPU in this text, but we will see some of the types of events that are controlled by the TPU programmed with the usual 16-bit timer.
On the newer computers, such as the MCORE architecture, a time-of-day (TOD) clock has been introduced. This clock is based on a 32768-Hz watch crystal. These crystals are readily available, small, very accurate, and quite inexpensive. Their only problem is that they are slow, and are not very good for fine time measurements unless the crystal is used as a time base to a frequency synthesizer.
Another timer function found on most microcontrollers is the computer operating properly (COP) or watchdog timer. Most microcontrollers are placed in embedded controls. That is, the microcontroller is a part of a larger system, and usually an operator never deals directly with the microcontroller. Even though great care has been taken in the design of the microcontroller, it is possible to cause these devices to get lost from the program that they are executing. The power might dip, or a large transient magnetic field might cause the part to go into abnormal operation. In such a case, the easiest way to restore normal operation is to send the part through a reset sequence. Such a sequence will restore all of the initial internal status of the microcontroller, execute the initialization code procedure of the program, and restart the execution of the application loop. A COP timer provides just this function. A COP timer is a timer with a relatively long period. Once the COP timer is started, it is necessary for the main program to reset the COP periodically prior to the expiration of the COP period. The COP timer is never allowed to time out. If the computer gets lost, the program no longer resets the COP, so the timer will eventually overflow, and this operation causes the microcontroller to reset. Therefore, if the part ever gets lost from its normal program sequence, the COP will force a reset and restore the normal operation of the system.
Digital Input/Output
Most microcontrollers have several digital I/O ports. Usually a port consists of eight or fewer bits, and the bits in these ports can be outputs, inputs, or often bit programmable as either input or output bits. If a
132 Chapter 3 What Are Microcontrollers?
port has programmable I/O, it will have an associated data direction register—DDRA, DDRB, and so forth. The ports are usually named PORTA, PORTB, and so forth. DDRA is associated with PORTA. Each bit in DDRA has a corresponding bit in PORTA. If a bit in DDRAis set, the corresponding bit in PORTA is an output. The same is true for PORTB, PORTC, PORTD, PORTE, and so forth if these ports exist on the part.
A port pin can be made into an output. When this occurs, this pin becomes a latched output. In other words, when this bit is set it will remain set until it is reset by the program, and vice versa. Just because a port pin is designated to be an output does not mean that its state cannot be read by the computer. When a port is read in, the state of all of the outputs as well as the state of the inputs will be shown in the result.
Some I/O pins are multiplexed and serve multiple functions. For example, microcontrollers with analog-to-digital converters, ADC, usually allow the ADC pins to serve as digital input pins as well. In that case you need merely read the input port, and those pins that are above the high threshold will indicate one, and those below the low threshold will indicate zero. Reading the port does not affect the ADC operation at all.
Analog-to-Digital Converters
The ADC subsystem on most microcontrollers consists of a single successive approximation analog-to-digital converter preceded by an analog multiplexer that can switch the converter to any of several input pins. The program controls this switching. The electromagnetic environment of the surface of a microcontroller die is about as bad as can be found anywhere. Therefore, attempts to do fine resolution measurements of analog voltages in these parts is fraught with problems. Most ADCs use a resistive ladder to act as a digital-to-analog converter. The inputs to this ladder are sequenced in a prescribed manner to build a voltage that matches the voltage being measured. The input to the D- to-A is then the digital equivalent to the voltage being measured.
Precision resistors are very difficult to manufacture on silicon, and even precision matching between resistors is extremely difficult. While making precision capacitors is very difficult on a silicon die, it is possible to make several capacitors with highly accurate ratios between the capacitor values. Therefore, the approach is to use a set of matched capacitors and a charge balance technique to accomplish
Input/Output 133
the successive approximation of the analog voltage. This method works well, and 8- and 10-bit systems are available on microcontrollers with plus or minus one-half bit accuracy.
Serial Input/Output
Where would the computer be without serial input/output? The serial system was probably the first direct human interface with any computer system. It has expanded, and today, relatively low-speed asynchronous serial interfaces are used for terminal and modem and network interfaces. High-speed synchronous serial links are used for all of the above plus inter-computer connections, hardware peripheral communications, and other types of devices where high-speed, secure communication is required.
Many microcontrollers have both asynchronous and synchronous communications peripherals built in. Usually, an asynchronous interface is called a serial communications interface (SCI) while the synchronous interface is called a serial peripheral interface (SPI).
Typically SCI systems can communicate at any of the popular asynchronous serial bit rates. These systems have built-in baud rate generators, double buffered input and output registers, and all of the error detection found on a universal asynchronous receiver-transmitter (UART) chip. These I/O devices can be either polled or interruptdriven by the computer portion of the microcontroller.
The SPI is designed to communicate at high speeds with other microcontrollers or perhaps with hardware devices with a synchronous serial interface. These devices typically run at megabit per second rates. Since synchronous systems require a system clock, each microcontroller SPI can act as either a master or a slave. The main difference between the master and the slave is which chip generates the system clock. The master generates the system clock, and the data are clocked into and out of the slave by the system clock. Communications with the microcontroller and the SPI can be either polled (synchronous) or via interrupt controller (asynchronous).
Different Controllers
Not all of these peripheral systems are found on each microcontroller. It is possible to pick and choose between needs for the several peripheral systems and select a microcontroller that has
134 Chapter 3 What Are Microcontrollers?
exactly those peripherals required. The smallest microcontroller has only a 15-bit timer, and the most complete MC68HC05 part has everything but a SPI system. All varieties in between these extremes exist. In the larger chips, some of the basic requirements for the microcontroller change. We will see these larger chips in later chapters.
Programming Microcontrollers
The preceding brief description of what microcontrollers are gives a rather bleak picture of a potential programming environment from a computer standpoint. Most programmers are used to having an operating system that handles such mundane things as I/O, memory management, time management, program loading, error processing, interdevice or intertask communications, and so forth. Be prepared for a giant step backwards when you address the microcontroller. There is usually no operating system, no libraries of useful functions, no I/O handling, nothing but a bare-bones computer with a bunch of hard-to-tame peripheral components onboard the single-chip device.
C compilers for the microcontrollers have been available long enough that they are thoroughly tested and do a good job of creating proper code. Anyone who has programmed a microcontroller in assembly language knows that the programs must be very direct and have no fancy overhead. Memory is strictly limited, and the compiler must generate assembly code that is as resourceful as can be created by any thoroughly qualified assembly language programmer for the machine.
The development environment, while quite sophisticated in terms of how it works, does little for the programmer in terms of direct help in debugging a program. There are two different types of development systems that are in common use. Both of these systems require a host computer to run the device. The simplest of these systems goes by names like evaluation module, evaluation system, or evaluation board. These devices are usually board-level products that require a power supply in addition to a host computer.
The software to run the development boards is merely a good terminal emulator. Assemblers and linkers for the different chips are provided as part of the development board. The programmer writes the code for the part in the host computer. This code is assembled, compiled, and linked in the host computer. The code is then
Programming Microcontrollers 135
down-loaded to the development board through either a serial or a parallel link depending upon the individual system.
The development board has the microcontroller that is to be emulated on board. This microcontroller sometimes operates in a nonuser mode that allows internal bus access. A second computer on the development board controls the operation of the microcontroller. Code delivered from the host is put into memory accessed by the microcontroller, and the microcontroller can operate as if the code were contained within its internal memory.All of the I/O lines associated with the microcontroller are brought to a header on the development board, and a cable can be attached to this header to a plug-in device that plugs into a target board. This target system then operates as if it had a programmed microcontroller plugged into its socket.
The microcomputer on the development board has a complete monitor system in its firmware. This monitor provides communications with the host, down-loading and up-loading capability and, most important, complete debugging firmware for the microcontroller.
There is a single line assembler and disassembler in the firmware. This package allows the programmer to examine and change memory in assembly mnemonics. The microcontroller program can be single stepped, run, address breakpointed, and the memory can be displayed in normal hexadecimal format. The microcontroller runs at full speed when emulating operation in a target board.
An experienced programmer will be able to debug code in a microcontroller with the help of such a development board. There is additional software available that provides a nice display of all pertinent information in a single screen on the host computer. In this area, you will also find that the microcontroller can be controlled from a display of C source code on the host computer. This technique is called source level debugging.
On later chips, another feature is incorporated to help the development environment. This feature is called Background Debug Mode, or ONCE. Both of these similar operations allow debug to take place in an external computer without any access to the microcontroller resources such as interrupts or memory. When a chip is put into BDM, certain pins become a special serial input/output port. There are several commands that can be delivered to this port from an external computer. These commands allow the computer to
136 Chapter 3 What Are Microcontrollers?
set memory, examine memory, examine registers, set and clear registers, execute code, set and clear break points, and so forth. All of the operations normally needed to debug a program can be executed through this special serial port. There is no need for an on-board monitor on the microcontroller, and it is not necessary to make use of the chip interrupts by the debugger during the debug operation. All of the programming needed for the debugger can reside in a host computer. Most modern chips have this type of interface, which greatly simplifies debugging of microcontrollers.
All of the above capabilities are available with the development boards. Another level of capability is available. These devices are box level, and usually have a built-in power supply. Most development systems require a host computer, and usually they come with special software to interface with the host computer. These systems have all of the capabilities outlined above plus some significant improvements. The breakpoint capability of these systems is much improved over the simple address breakpoint above. Here a complicated breakpoint can be employed that will break the program operation on read or write, at any data or address location, on access of data or program, or access of a range of data or address locations. Also, the breakpoint can occur after a specified number of occurrences of the breakpoint conditions.
Another major difference in the development systems is the trace buffer. A trace buffer is a memory that is as many as 48 or 64 bits wide. Each clock cycle of the microcontroller, the condition of all address bits, the data bus, the internal microcontroller control bus, and as many as 16 external test point lines are captured in the trace buffer.
Usually, the trace buffer is 4 to 16 kilowords deep, so it can hold a significant number of microcontroller clock cycles. Even if the microcontroller is running slowly, one million clock cycles per second, such a trace buffer represents an insignificant execution time. To help make the data contained in the trace buffer, trace buffer capture can be controlled by a system that is the same as the breakpoint operation. Therefore, the portion of the program that is traced is under the detailed control of the programmer.
The data in the trace buffer can be displayed in several different manners. The simplest, of course, is to print to the computer screen the I/O pattern of all the lines captured. This type of display is extremely difficult to interpret, but it is useful in some cases. To help the programmer determine where the microcontroller is operating, it
Coding Tips for Microcontrollers |
137 |
is possible to read the data bits and display a disassembled version of the code being read into the microcontroller. This display is also quite useful in debugging the code.
Yet another display is called a logic analyzer. A logic analyzer is an oscilloscope display that shows the logical status of the various lines captured in the trace buffer. A logic analyzer is a separate device, but it can have a built-in disassembler that displays the disassembled code along with the condition of the designated lines.
The devices with logic analyzers and trace buffers are quite a bit more expensive than the development boards discussed earlier. Some of the development systems provide source level debugging capability for high-level languages like C.
Another approach to development systems has been made available in some of the newer microcontrollers. The microcontrollers from the MC68HC16 family and those from the MC68300 family all have a background mode of operation. When operating in the background mode, these chips stop their normal computing and start serial communications with an external computer. The background mode can be entered as the result of an internal command or an external signal. There are enough debug commands that can be communicated over this port to allow complete debug of any program that the microcontroller might be running. Minimum external circuitry is needed to support the debug mode, so these high-powered chips can operate as their own development environment. Here, the development support is mostly software contained within the host computer, and the deliverable system can contain all of the essential components of a development system.
Coding Tips for Microcontrollers
One of the major tasks facing a programmer when writing code in a high-level language for any microcontroller is to make the resulting program as readable as possible. Other people who might later need to read or modify your code must be able to understand what is going on in your program. It is extremely important that mnemonics be used as much as possible when dealing with various registers, their bit contents, and special memory addresses throughout your programs; otherwise, the resulting code will be a “quasi-C” program filled with many numbers and funny-looking cast operations that will be largely incomprehensible to others trying to maintain your program.