Programming the Arduino in Pure C.

For hack #2, I started looking at how I could program an Arduino; an affordable hobby development board which uses an Atmega AVR microcontroller. More information here. We add a twist by not using the Arduino IDE and instead using the old faithful text editor.

Stuff You Need

Total cost, £30 or so. All of the software is free and open.

Implementation

On the web you will find the Arduino port map. From here you can figure out how to hook 6 LEDs (with a resisitor each) up to port B pins 0-5. It’s pretty simple stuff, you don’t need a schematic. Now we need to make those leds-a-blinken.

What I needed then was a tutorial. Google quickly lead me to Chris Kuethe’s Arduino tutorial. As it turns out, ckuethe is the avr-gcc maintainer for OpenBSD — small world. By following these tutorials, you can easily get up to speed. Half an hour later and I had a “Knight Rider Emulator” using 6 LEDs:

/* $CSK: lesson1.c,v 1.3 2009/05/17 06:22:44 ckuethe Exp $ */
/*
 * Copyright (c) 2008 Chris Kuethe <[email protected]>
 *
 * Permission to use, copy, modify, and distribute this software 
 * for any purpose with or without fee is hereby granted, 
 * provided that the above copyright notice and this permission
 * notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 
 * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR 
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 
 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Adapted as Knight Rider LEDs on an Arduino Duemilanove
 * (c) Edd Barrett 2010
 */

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

int main (void)
{
	uint8_t		leds = 1;

	/* set PORTB for output*/
	DDRB = 0xFF;

	while(1) {
		for (leds = 1; leds <= (1 << 5); leds <<= 1) {
			PORTB = leds;
			_delay_ms(200);
		}
		for (leds = (1 << 4); leds >= 2; leds >>= 1) {
			PORTB = leds;
			_delay_ms(200);
		}
	}

	return 0;
}

Uploading with AvrDude

But how do we upload the binary onto the storage of the arduino?
This part I had already figured out the night before and it took me quite some time, partially because I did not know what baud rate the Arduino was expecting. Once I had it figured, I adapted the sample makefile found on the arduino wiki — this one is for BSD make (suffix rules work a little differently to GNU make).

# tools
AVRDUDE=avrdude -F -V
OBJCOPY=avr-objcopy
CC=avr-gcc
RM=rm -f

# parameters
MCU=atmega328
F_CPU=16000000UL
BIN_FORMAT=ihex
PORT=/dev/cuaU0
BAUD=57600
PROTOCOL=arduino
PART=ATMEGA3290
CFLAGS=-Wall -Os -DF_CPU=$(F_CPU) -mmcu=$(MCU)
PROG=addr
SUDO=sudo

.SUFFIXES: .elf .hex

.c.elf:
	$(CC) $(CFLAGS) -o $@ $<

.elf.hex:
	$(OBJCOPY) -O $(BIN_FORMAT) -R .eeprom $< $@

.PHONY: all
all: ${PROG}.hex

${PROG}.hex: ${PROG}.elf

${PROG}.elf: ${PROG}.c

.PHONY: clean
clean:
	$(RM) ${PROG}.elf ${PROG}.hex

.PHONY: upload
upload: ${PROG}.hex
	${SUDO} $(AVRDUDE) -c $(PROTOCOL) -p $(PART) -P $(PORT) \
		-b $(BAUD) -U flash:w:${PROG}.hex

Conclusion

I was pretty impressed with how easy it really was to program an AVR on OpenBSD. The compiler is familiar – it’s just GCC cross targeting, and the editor is familar — in my case it’s vim and not a bloated java GUI.

Ofcourse, this just scratches the surface. Expect further hacks later.

Thanks to ckuethe@ for his tutorial.

About Edd

Edd is a open-source enthusiast, PhD student, OpenBSD developer and general computer pessimist :)
This entry was posted in Arduino, Hardware, Programming. Bookmark the permalink.

6 Responses to Programming the Arduino in Pure C.

  1. Shaun says:

    Very nice Ed, loved the elegance of the solution.

  2. Pingback: Programming Arduino Uno in pure C « Balau

  3. clvrmnky says:

    I suspect “PART=ATMEGA3290″ is wrong, but the warning is being suppressed by the -F option passed to avrdude.

    The Duemilanove either has a ‘168 or a ‘328, so the partno is going to match that. If you have a later device, the partno is going to almost certainly be “ATMEGA328P”.

    In fact, the PART and MCU variables in the makefile can be set to this same string.

  4. Mahdi says:

    what if we wanna to the work with arduino Ethernet shield? can we use arduino library with pure C? is there any way to stick to Ansi C and also take advantage of the library in some cases like Network programming or even work with memory stick?

  5. dagon666 says:

    Hi, nice post. You can check my Makefile, which is targeted for arduino Uno Rev 3 with atmega328p: https://gist.github.com/dagon666/6654222

  6. Vikki Ford says:

    I find it easier to use ICC7AVR C compiler (only because I use it at work) and AVRISP Mk2 if I want to program in a non-Arduino environment but use the Arduino board. To be honest I rarely do that. I tend to stick an Atmel on a breadboard and programmed to use its internal oscillator. One Atmel, one reset tie high resistor and anything else you want. Hmmm, I also use and AVR Dragon with the zif socket in place to program the chip. Mind you, the little projects I’m doing at the moment are only using Tiny25’s and 44’s. Don’t need the whopping memory of the 328p for these. My compiler is a 4k limited expired demo but at some point I’ll cough for the student/hobbyist license to unlock it to 64K.

    Note that the AVRISP Mk2 will attach directly to an Arduino board and is run from AVR Studio 4 (I don’t like Studio 6, far too slow).

    Hope that is of some help to others further along the Atmel road.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>