MAS.863: How To Make (Almost) Anything


Week 5: Microcontroller Programming

Vagaries of assembly syntax


I spent a lot of time this week trying to understand the available AVR assemblers. They each have slightly different syntaxes and command lines. Here's a minimal example for each; they turn on pin B2 (which had an LED connected to it on our board for this week).

GNU's Assembler


#include <avr/io.h>


command line

avr-gcc -c -mmcu=attiny44 -o led.out led.S
avr-objcopy -j .text -O ihex led.out led.hex
GNU's assembler is conveniently included in the CrossPack package for Mac OS X, WinAVR for Windows, and the gcc-avr packages on various Linux distributions. Unfortunately, it has awkward syntax, requiring _SFR_IO_ADDR() around the names of the I/O registers. Confusingly, you'll need to compile your code with avr-gcc, even though it's assembly. If you try avr-as, you'll get a message like "Error: constant value required".

Gerd's AVR Assembler (gavrasm)


.device attiny44

sbi DDRB, 2
sbi PORTB, 2

command line

gavrasm led.asm
This is the assembler used by most of the class. Pre-compiled binaries for Windows and Linux are available from the gavrasm homepage. On Mac OS X, gavrasm can be compiled using Free Pascal (which provides Mac binaries). You can try the version I compiled under Snow Leopard (10.6): gavrasm; or the one Kelly made under Leopard (10.5): gavrasm.zip. It's okay to use .include "tn44def.inc" (as in Atmel's AVR assembler) instead of .device attiny44 but you'll get a warning. The gavrasm program doesn't actually include (or require) the .inc file but uses its name to determine your device.



.include "tn45def.inc"

sbi DDRB, 2
sbi PORTB, 2

command line

avra led.asm
This is another open-source assembler that's compatible with Atmel's AVR Assembler. It has the advantage of being written in C, so you can compile it with the standard development tools (e.g. Xcode on the Mac). There are also Windows binaries available. Unfortunately, avra doesn't support newer AVRs like the ATtiny44A that was on our boards this week. To use it, you'll need the .inc file for your microcontroller (e.g. tn45def.inc for the ATtiny45). These are included in the AVR Studio distribution.

Atmel's Assembler


.include "tn44def.inc"

sbi DDRB, 2
sbi PORTB, 2
The official (Windows only) AVR assembler from Atmel (avrasm). You should be able to compile your code from within AVR Studio (registration required for download).
My board for this week (hello.echo.44.mellis.cad). I added the button and a big pad (using the wire() command). I was hoping to do simple capacitance sensing with the pad, but it didn't seem to work.


The output from my modified assembly program. When the board receives a character over the serial port, it sends back the current value of the button pin (1 or 0). This was a minimal change, the main code for which is:

      ldi txbyte,49
      sbis button_pins, button_pin
      ldi txbyte,48
      rcall putchar

Once gavrasm was working on my Mac, modifying the assembly code was straightforward.

I've also been working on an easily fab-able AVR programmer, currently titled "FabISP". The parts should arrive this week, and then I'll build one and test it.