The following examples are listed by the lab exercise they will be used with, or by a general topic heading. The link in the topic heading points to a general description of the relevant concepts related to the code example. At the bottom of the page are various GCC links that I found useful when writing the examples.
GCC code examples:
- lab 0
- sched1gcc.c -- Just three tasks blinking the lights and checking a button.
- sched1proj.zip -- Blinking lights + UART interface + uart.h + uart.c, sort of a basic debuging environment.
- Assertproj.zip -- Uses the assert macro to demo debugging which requires uart activation. The assert() macro may be removed at compile time by defining NDEBUG as a macro (e.g., by using the compiler option -DNDEBUG).
- lab 1 -- Capacitance measurement/stopwatch/reaction time
- TimerDemo.zip -- Three timers: T0 runs time base, T1 captures, T3 generates square wave. Uses proper names for i/o bits.
- LCD demo
- lab 2 -- Cricket call/DTMF dialer/
- lab 3
-- Concurrent devices -- keypad and UART
- lab 4 -- Video game/DSO/ Pulse Finger Plethysmograph
- lab 5 -- Motors: thermostat/ IR tachometer
- IIR filters 2-pole The function
y=IIR2(x) returns a filtered sample in 202 cycles.
- This project contains the general 2-pole IIR, 2-pole Butterworth high, low, bandpass, and 4-pole Butterworth bandpass. The 2-pole butterworth high and low pass execute in 151 cycles, the 2-pole bandpass in 148 cycles and the 4-pole butterworth bandpass in 242 cycles. Note that the linker options (click on
[Linker options] in
Project-> configure options->Custom options) must include the following specifications:
-Wl,-u,vfprintf -lprintf_flt -lm
in order for floating point printing to work. See AVRLIB description and a tutorial.
- A/D and D/A
- Mega32 protoboard test -- blinkD2gcc.c
GCC Examples from Ruibing Wang.
- GCC docs
- Mega32 i/o definitions (including interrupt vectors) iom32.h
- GCC tutorial
- AVR libc users manual
- Library Reference
- inline assembler
- avr-libc and assembler programs
- GCC FAQ
- ASM FAQs
- (3) How to permanently bind a variable to a register
- (9) How do I use a #define'd constant in an asm statement
- (13) What registers are used by the C compiler
Function call conventions:
Arguments - allocated left to right, r25 to r8. All arguments are aligned to start in even-numbered registers (odd-sized arguments, including
char, have one free register above them). This allows making better use of the
movw instruction on the enhanced core. If too many, those that don't fit are passed on the stack. Return values: 8-bit in r24 (not r25!), 16-bit in r25:r24, up to 32 bits in r22-r25, up to 64 bits in r18-r25. 8-bit return values are zero/sign-extended to 16 bits by the caller (
unsigned char is more efficient than
signed char - just
clr r25). Arguments to functions with variable argument lists (printf etc.) are all passed on stack, and
char is extended to
Call-used registers (r18-r27, r30-r31):
May be allocated by gcc for local data. You may use them freely in assembler subroutines. Calling C subroutines can clobber any of them - the caller is responsible for saving and restoring.
Call-saved registers (r2-r17, r28-r29):
May be allocated by gcc for local data. Calling C subroutines leaves them unchanged. Assembler subroutines are responsible for saving and restoring these registers, if changed. r29:r28 (Y pointer) is used as a frame pointer (points to local data on stack) if necessary. The requirement for the callee to save/preserve the contents of these registers even applies in situations where the compiler assigns them for argument passing.
Fixed registers (r0, r1):
Never allocated by gcc for local data, but often used for fixed purposes:
r0 - temporary register, can be clobbered by any C code (except interrupt handlers which save it), may be used to remember something for a while within one piece of assembler code
r1 - assumed to be always zero in any C code, may be used to remember something for a while within one piece of assembler code, but must then be cleared after use (
clr r1). This includes any use of the
[f]mul[s[u]] instructions, which return their result in r1:r0. Interrupt handlers save and clear r1 on entry, and restore r1 on exit (in case it was non-zero).
- (26) Which AVR-specific assembler operators are available
- Debugging FAQs