AVR: Programming the EMSL Target Board from Mac OS X

EMSL Atmega168 Target Board

The EMSL Target Board is built around the ATmega 168 micro-controller (same controller as the Arduino — which, frankly, I couldn’t care less about other than as a source of knowledge…).

It is an extremely easy to use and surprisingly powerful micro-controller. If it weren’t so convenient, I wouldn’t be writing this.

Seriously. If you have any interest in screwing around with micro-controllers, there is little excuse not to dive in now. It is cheap, easy, and powerful.

Beyond the EMSL Target Board, you’ll also need a Lady Ada USBTinyISP programmer that has been appropriately patched (when assembled).

First, grab and install AVR Mac Pack from the fine folks at Objective Development (same source of LaunchBar and Little Snitch — both awesome products in their own right).

AVR Mac Pack has everything needed to talk to the AVR, a compiler that can target the AVR, and support for Xcode based development.


Once installed, the next step is to verify that the programmer can talk to the board using avrdude (all commands assume that $PATH has been updated to include the AVR Mac Pack stuff — be forewarned that the installation of AVR Mac Pack will edit some files in /etc/ to change the shell. It doesn’t work if you are using tcsh):

avrdude -p m168 -c usbtiny -P usb

avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

Uh oh! That ain’t good! Oh, that happened because I hadn’t flipped on the “power the target board” switch on my programmer. With the stock USBTinyISP, it’ll be a jumper. Replace it with a switch. You’ll be happier.

Anyway, once on:

avrdude -p m168 -c usbtiny -P usb

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9406

avrdude: safemode: Fuses OK

Woot!

You could use AVR Mac Pack’s avr-project command to create an Xcode project, but it produces an Xcode project that can’t install the built executable from within Xcode. I find it easier to start with the Peggy Makefile. Xcode’s Organizer can be trivially configured such that cmd-b will cause the makefile to build and install the desired chunk of code.

Firs,t you’ll need to edit the opening bits of the maekfile to successfully target the m168 part (this assumes that your source file

PRG            = buttflip
OBJ            = buttflip.o
PROGRAMMER     = usbtiny
PORT		   = usb
MCU_TARGET     = atmega168 
AVRDUDE_TARGET = m168
OPTIMIZE       = -Os
DEFS           =
LIBS           =

Now, the makefile claims no need to edit below that particular header. It lies. There are these evil things called “fuses” in AVR micr-controllers that you have to deal with exceedingly carefully. Seriously. Wrong value can lead to a nice bit of inert plastic encased silicon.

Actually, you really want to change the makefile preamble to also include a CPU speed indicator (which is set via the ungodly confusing fuse values mentioned below):

AVRDUDE_TARGET = m168
OPTIMIZE       = -Os
DEFS           =
LIBS           =

HZ          = 1000000

And, slightly below that, change the definition of CFLAGS to this:

override CFLAGS = -g -DF_CPU=$(HZ) -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)

You’ll see why in a second.

Ben pointed me to the AVR Fuse Calculator. God send. For now, I’m sticking with the default fuse values because I’m too lazy to go read the spec sheet closely enough to figure out what the more optimal settings might be:

install:  $(PRG).hex
	avrdude -p $(AVRDUDE_TARGET) -c $(PROGRAMMER) -P $(PORT) -v  \
	 -U lfuse:w:0x62:m \
	 -U hfuse:w:0xDF:m \
	 -U efuse:w:0x01:m \
     -U flash:w:$(PRG).hex

I totally don’t understand the fuse values. The default fuse calculator came up with a different value for efuse. avrdude complained. I set it to 0x01 because that was the value avrdude indicated was expected. It works. I have no clue why.

Blinky

OK… great… now… need some kind of Hello, World! for a micro-controller. Sounds like it is time to Blink an LED or something.

Of course, you’ll need an LED. I used a random red LED because they are the cheapest and most commonly available. Thus, if I melted the LED, no real pain incurred.

You’ll also need a resistor to drop the voltage a bit for the LED. I used a 120 ohm resistor as that was handy — anything in the 120 to 220 ohm range should do fine.

LEDs have polarity. That is, they only work one way. The lead coming out of the flattened side of the LED is the negative lead (or, if you haven’t clipped them, the longer lead is the positive lead).

To make this code make the most sense, I wired up the LED such that it turns on when the output pin is turned on and turns off when off. That is, the positive lead of the LED — the round side — is connected to the PB0 pin of the ATmega168 chip. The negative is connected to one lead of the resistor. The other lead of the resistor is then connected to ground (GND) on the target board.

Aside: Usually, the LED will be hooked from VCC [positive] to the chip through the resistor. I’m not fully sure why, but it makes the code backwards– setting the bit turns off the LED, and vice-versa. Confusing. For this, I hooked it up the intuitive way.

The code is rather straightforward:

#include <avr/io.h>
#include <util/delay.h>

int main(void) {
    DDRB = 255U; // Make all PB* pins output
    
    while (1) {
        PORTB = 0x1; // high 
        _delay_ms(250);  // 1/4 second on
        PORTB = 0X0; // low
        _delay_ms(2500); // 2.5 seconds off
    }
}

That is it!

Setting DDRB simply configures all PB# pins to be outputs. Overkill for only one pin, assuredly.

Setting PORTB to 0x1 simply turns on pin PB0 — takes pin PB0 high [5v]. If the LED were hooked to PB1, that would be 0x2. PB3? 0x4. PB4? 0x8. Etc… It is just basic bitwise I/O.

The calls to _delay_ms() entirely rely upon the setting of HZ in the makefile (which sets F_CPU). The ATmega168 part has an internal oscillator running at 8 MHZ, but that is subdivided to yield a 1 MHZ CPU speed.

End result?

The LED should blink; short tim on, longer time off.

Next up?

Two LEDs & some useful tools for manipulating bits. And the circuit will be refactored into a more standard form (LEDs connected to VCC).

The latest source code for this project is available in my personal subversion repository here: http://svn.red-bean.com/bbum/trunk/avr/ATmegaXX8/one-led-blinker/.



5 Responses to “AVR: Programming the EMSL Target Board from Mac OS X”

  1. n[ate]vw says:

    > If you have any interest in screwing around with micro-controllers, there is little excuse not to dive in now.

    I still have two AVR microcontrollers (ATMega32?) in my electronics stash from a piezo->MIDI converter I started in high school but lost momentum while at college. Great to know that there is a good toolchain for Mac, but my excuse now is that there are more pressing matters I should be attending to in Xcode. (I must ship.) I’ve bookmarked this, though, in hope of having a chance to return. Maybe when I have kids, I can get them interested in this kind of stuff!

  2. dave says:

    Don’t knock Arduino…it’s a nice little widget with a free development environment, written in Java, ready to go. The language is very C like. Forty bucks will get you an Arduino board with microcontroller and away you go. I’ve done dozens of projects on that little board, it’s very useful…and yeah, I use XCode the rest of the time for my other stuff.

  3. bbum says:

    Arduino is a terribly useful/cool platform, for what it is. It just happens to not be something I care about in that it is too close to a computer for what I need.

    If I were to build, say, something like the Stoker, I would base it on an Arduino so I could have a TCP stack.

  4. Peter says:

    Usually, the LED will be hooked from VCC [positive] to the chip through the resistor. I’m not fully sure why…

    It’s because most microcontrollers can sink more current than they can source. Page 80 of the datasheet for the AVR Tiny12 chip I’m playing with shows the ability to sink up to 50mA, but it can only source 4(!) mA while providing 4.5V of the 5V supply. Pull as much as 16mA from it as a positive output and it drops the voltage to just 2V.

  5. bbum’s weblog-o-mat » Blog Archive » Using a Vertical Stack Counter to Debounce Switches says:

    […] left is a simple EMSL AtmegaXX8 Target Board (same board I have written about before) 3 bit up/down counter […]

Leave a Reply

Line and paragraph breaks automatic.
XHTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>