Electronic cam significantly eases development of microcontroller code
Scott Rosenthal
September, 1991
Once I discover something that works for me, I stick with it until something clearly
superior comes along. For years I used the venerable 8085 microprocessor for
instrumentation designs because the instruction set held no surprises, costs were low, and
as time went on the speed increased while power requirements decreased. Did it really
matter what was under the hood as long as it ran and ran economically? About four years
ago, though, the growing popularity of C and skeptical customers (not to mention skeptical
employees) concerned about bits and megahertz pushed me into looking for another
processor. In my mind that next device had to be revolutionary, not evolutionary. I wanted
something that would carry me forward for the next ten years just as the 8085 had done for
the previous decade. The processor, or more formally the microcontroller, I found was
Intel's 80C196KC. This device is designed for control applications requiring high-level
language support, quick reaction to external or internal events and offloading to hardware
of some of the repetitive operations that are the heart of many embedded designs.
The 80C196KC is an outgrowth of the 8096 Intel developed for the auto industry in the
mid 80s. As the chip evolved, each generation has maintained software compatibility
with previous versions while adding new features. Examples of improvements include new
instructions, more I/O and additional interrupts. Some generations of the chip are even
pin compatible. In addition, the device fulfills my requirement for a revolutionary
processor with features that are truly amazing for a single-chip microcontroller. It
incorporates a UART with three modes of operation; three pulse-width modulated outputs;
two timers; 28 interrupt sources; a watchdog circuit; parallel I/O with built-in FIFO; 232
8-bit registers; a content-addressable memory (CAM); and an 8-channel 10-bit A/D
converter. Other interesting features include a dynamically configurable bus that can
change between 8- and 16- width on each instruction, opcodes optimized for the C language,
and low-power operating modes. (For a full discussion of these features, get Intel's
handbook titled "16-Bit Embedded Controllers," order number 270646-003.)
What's a CAM?
In my mind, the neatest feature of this microcontroller is the CAM. To understand how
this mechanism works, start with a model that you might be more familiar with---mechanical
cam logic. It's what causes an auto's valves to open and close synchronously with piston
position; designers previously used it to control dishwashers and traffic lights.
Basically, a mechanical cam consists of a shaft with a series of actuators spaced at
predetermined locations. As the shaft turns, the actuators cause events to occur by
closing switches or moving linkages at predetermined shaft positions.
The CAM unit in the 80C196KC operates in an analogous manner (Fig 1). Each of the CAM's
eight slots is composed of a time and an action. As a given timer increments, logic in the
chip compares its current value to all slots in the CAM. If any slot's time matches the
current timer value, the chip performs the specified action. Possible actions would be to
assert an internal interrupt, reset the clock, or trigger an external event using one of
the chip's High Speed Outputs (HSOs). In addition, when a CAM slot matches the timer, you
decide whether the CAM slot becomes available for a different action or if the action is
locked in the CAM slot. The greatest feature of the CAM, however, is that it continues
operating even if the microcontroller crashes!
To understand how you might use that feature, consider the following simple
application. I once designed an instrument that had to blink an LED with very high drive
currents. The pulse rate and duty cycle were programmable, but if the LED stayed on too
long it would blow out. Even with carefully written software, there was always a chance
that during emulation the program would stop at a breakpoint with the LED on and cause it
to fail. Unfortunately, the requirement for a programmable duty cycle ruled out a one-shot
and would've required a fairly complex fail-safe circuit. However, the 80C196KC makes this
problem easy to solve. Fig 2 shows the code and a simplified schematic of how to approach
the problem using three CAM slots. The first sets the blink's period by resetting the
timer, in this case Timer2, to zero when it reaches this time. The second slot sets HSO0,
high, and the third slot sets HSO0 low; together these two slots set the duty cycle. The
CAM repeatedly pulses HSO0, enabling and disabling the LED driver circuit without any
software intervention.
The CAM unit can also repeatedly acquire data from many different sources at specific
time periods. In addition, using data structures allows you to reuse program code so
you'll end up with very little code doing a lot of work.
I've only found two problems with the CAM unit. First, CAM-generated software timer
interrupts are level sensitive instead of being edge triggered. In simple terms this
limitation means that if an ISR executes in less than a clock tick, the CAM generates
additional interrupts until the clock changes its value. Typically Timer1 isn't a problem
because it consists of the system clock divided by 16. However, Timer2 comes from an
external source and can run at any speed. The other problem is with myself---I've found so
many uses for the CAM that Im constantly filling it up. If only it had more slots
then I could... Well, I guess I'll have to wait for the next generation.
Reconfigurable bus width
The dynamically configurable bus is also exciting. It allows any bus-width combinations
of memory or I/O. In one of my applications the boot code resides in an 8-bit ROM. When
the controller starts running, it gets a new program downloaded serially and loads it into
a 16-bit RAM. Once the controller downloads the program, it shifts execution to the RAM.
Due to this trick I was able to avoid the expense of a 16-bit ROM for the bootstrap but
get full speed during normal operation. Here's something I learned about 16-bit
memories---don't write a word to an odd address and keep your stack off odd addresses. The
problem is that the processor assumes even-byte word boundaries, and attempting to use odd
addresses results in unpredictable operation.
Now that I've convinced you to incorporate this device into a design, what about
support tools? Im aware of at least four firms that market emulators for the
80C196KC---Annapolis Micro Systems (Annapolis, MD (301)269-8096, Huntsville Microsystems
(Huntsville, AL (205)881-6005), Softaid (Columbia, MD (410)290-7760) and Intel (Hillsboro,
OR (800)468-3548.
I don't have any experiences with emulators from the first three companies, but I've
used the Intel tool a great deal and find it less than ideal. I use the PC version, which
is more of a software development system than a true emulator. Hence most serious software
errors cause the emulator to lose all trace data. In addition, even when it's available,
trace data doesn't actually show what the emulator read at an address. It only records the
addresses accessed and during a listing goes out to the memory and gets the data. With
unknown hardware, this shortcut renders the trace function useless for debugging. In fact,
it masks problems. The other difficulty with the PC version of the Intel emulator is that
you must purchase a new model for each generation, whereas some other tools seem to work
with each new generation. PE&IN
Adapted from an article that appeared in Personal Engineering & Instrumentation
News.
Return to the article index.
|