Issue
142 May 2002
Taking
a Swim with Atmel's STK500
Start
The Atmel STK500 Imagecraft
AVR C Compiler
Sources
& PDF
IMAGECRAFT
AVR C COMPILER
Just
like many of you, I cut my embedded teeth writing assembler
applications. Then, one day I decided to try C on an
important embedded project and I’ve never returned to
pure assembly coding. The problem is, with C you can
choose the wrong compiler for your needs. With that
in mind, I began searching for a suitable AVR C compiler
on the Internet.
I
wanted an AVR C compiler that could handle all of the
AVR families without having to purchase extra cost modules
or build kludgy workarounds. It would also be good if
the AVR C compiler supported the STK500 development
board directly. I don’t plan to delve into the 8-pin
AVR devices so lack of support for those devices wasn’t
a problem.
I
didn’t have to look far. ImageCraft’s ICCAVR supports
all of the AT90Sxxx and ATmega devices including the
FPSLIC, but not the tinyAVRs and ’1200, which are supported
by another ImageCraft product, ICCTiny. Having used
other embedded C compilers, I knew that I needed inline
assembly capability and strong string handling support.
Because the AVR targets will be performing bit and byte
I/O operations, the AVR C compiler I chose needed to
have a good handle on that functionality as well. A
robust set of AVR-specific library routines is mandatory
seeing as I don’t want to write all of the standard
AVR I/O routines from scratch or in assembler.
As
it turned out, ICCAVR offered much more than I expected.
I opted for the professional version as it contains
a unique Code Compressor optimizer that could come in
handy when the larger AVR TCP/IP implementations come
to call. The professional version also has some interesting
features that are being developed for AVR Studio. These
additions will be available via a maintenance upgrade
when they show up online.
The
ImageCraft AVR C compiler has its own IDE that supports
long file names and acts much like the AVR Studio IDE
in that there is an integrated project manager, C editor,
ANSI terminal emulator, and an application builder to
generate peripheral initialization code. ICCAVR also
supports symbolic debugging in the AVR Studio.
The
designers of ICCAVR realized the importance of efficient
string handling in embedded microcontroller applications
and included several flavors of the printf function
to suit differing environments. The best ICCAVR feature
is the price. Even the ICCAVR maintenance prices are
way below sea level.
I
figured I would forego discussing the blinking lights
as I entered ICCAVR territory, but the ICCAVR AT90S8515
demo program uses the LEDs to make its point as well.
Again, I’ll use the AT90S8515 that’s already on the
STK500 development board.
Take
a look at the AT90S8515 program 8515intr.c in Photo
5. At first glance, the program seems simple enough.
What you don’t immediately see is the functionality
packed into these seemingly simple lines of text. The
first line of code is a standard include statement referencing
an include file filled with AT90S8515 I/O and register
definitions. What you don’t see is a reference to another
include file named io8515v.h.
|

(Click
here to enlarge)
|
Photo
5—This small program demonstrates that there is
power behind the simplest of statements. It’s obvious
that real embedded programmers solving real-world
problems wrote the ICCAVR C compiler. |
The
C header files io8515.h and io8515v.h have been designed
to define consistent global names for interrupt vector
numbers and use the AVR datasheet names for clarity.
For instance, Listing 1 is a definition
table for the AT90S8515 interrupt vector numbers taken
from the C header file io8515v.h. The second line of
code,
#pragma
interrupt_handler timer:5
generates
the interrupt vector code based on the interrupt vector
number found in io8515v.h. The pragma statement also
declares the function timer() as an interrupt handler.
Knowing that the timer function is now an interrupt
handler, the AVR C compiler generates a reti (return
from interrupt) instead of a standard ret for the timer()
function turned interrupt handler and saves and restores
all of the registers the timer() function uses.
The
main() function simply sets up the AT90S8515’s port
B, loads Timer1 with values for a 100-ms interval, enables
the Timer1 Compare A interrupt, starts the timer, and
runs forever. The timer() interrupt handler is called
every 100 ms and simply increments the value of port
B, thus producing a binary counting pattern on the STK500
development board’s LEDs.
Note
here that the interrupt handler function timer() is
written entirely in C. Counting cycles to make delays
or intervals is not one of my favorite things to do
when it comes to programming. Obviously, as you can
see in Photo 6, Jack Tidwell and I have something in
common. Thanks to Jack, the values loaded into the compare
registers to affect the 100-ms interval were not computed
by hand. ICCAVR has a built-in calculation tool that
does it for you. The AVR Fp & Calc Tool is shown
providing the compare register values for a 100-ms interval
with the STK500 board’s 3.69-MHz target clock prescaled
by 1024.
|

(Click here to enlarge)
|
Photo
6—The AVR Fp & Calc Tool program also calculates
the value to reload into the timer count registers
in case you want to generate an interval with that
method. I played with the Baud Rate Calc to get
an idea of how fast I could run a serial port with
a 32-kHz clock. |
The
window you see in Photo 7 is yet another reason I chose
the ICCAVR AVR C compiler. After the LED-counting code
was compiled, I clicked on Tools>In System Programmer
on the ICCAVR tool bar, selected the STK500 development
board on COM1, clicked on Chip Erase, made sure my target
hex file was listed in the "Manual Program Now!" panel
and clicked on the Program FLASH/EEPROM button. A few
seconds later, the AT90S8515 on the STK500 development
board took control of the LEDs and the familiar binary
counting pattern was blinking away.
|

(Click here to enlarge)
|
Photo
7—This is really simple to use. It even includes
an option to automatically program the target part
after a successful compile. |
A
SURPRISE PACKAGE
It
looks like I have a great start toward developing embedded
applications with the Atmel AVR parts, but I want to
clear something up. I failed to mention the differences
in the ATmega16 and the ATmega163 parts I will be using.
Both parts are essentially identical with the exception
of the inclusion of a JTAG interface on the ATmega16.
The
ATmega16 JTAG interface is IEEE standard 1149.1 compliant
and includes the boundary-scan capabilities set forth
in the standard. The AVR JTAG interface opens debugger
access to everything internal to the ATmega16. With
the right hardware, you can read and program the flash
memory, EEPROM, fuses, and lockbits of the ATmega16
through the JTAG port (see Photo 8).
|

(Click here to enlarge)
|
Photo
8—The STK501 development board comes with a dedicated
JTAG header. The STK500 development board has no
such header. A 10-pin male header with pigtails
comes with the JTAG ICE to allow it to be connected
to the STK500 development board and to any JTAG-capable
AVR. The JTAG port resides on four pins of port
C on the ATmega16. |
The
version of AVR Studio I downloaded earlier is designed
to work hand in hand with the JTAG ICE. The JTAG ICE
also directly supports the STK500 development board.
I took a quick look at the ICCAVR library and there
are support files for the ATmega16, ATmega64, and the
ATmega323, all of which offer JTAG capability.
JTAG
ICE operation is a bit different than that of more familiar
emulators. The standard microcontroller emulator contains
a special bondout device that runs the code and emulates
the actual micro in hardware. Special pins and sequences
allow you to extract the register, CPU, I/O, and memory
debug data from the bondout device. JTAG ICE does not
contain a bondout device. Instead, JTAG ICE uses the
AVR on-chip JTAG port and the AVR’s built-in, on-chip
debugger (OCD) to control the emulation process. With
JTAG ICE, the emulation is actually code running on
the target AVR microcontroller. The JTAG interface coupled
with the AVR OCD and AVR Studio gives you a view into
the AVR microcontroller’s inner works in real time.
The
JTAG ICE is an interesting piece of equipment and deserves
more attention. Next month, I’ll go into detail about
the JTAG ICE and cook up some AVR Internet code to show
you that the union of ICCAVR, JTAG ICE, and the ATmega16
isn’t complicated, it’s embedded.