AVR Butterfly Primer
I have been curious about the AVR micros for some time now. I was excited to see that
Digi-Key was selling (among others) the AVR Butterfly
evaluation board. And its only $19.99 plus shipping! I could not pass that up even if
I ended up not using the thing. I have had it for a number of weeks now just looking at
it wondering, "Okay, so where do I start". That is what this web page is all about, I
am still quite the newbie when it comes to the AVR, but I have not been able to find anything
useful on the web for the Butterfly, so I decided to do my own page.
The breakthrough for me was the AVR for beginners tutorial at
www.avrfreaks.net. Basically all it did was blink the port
b bits on and off, but that was enough. I am getting ahead of myself, you are welcome to head
over to avrfreaks and get a step by step, button by button, walk through of your first program.
I am not going to go so slow.
Step 1: Serial Cable
I dont know if this is an AVR thing or a mega169 thing but all you need to program your AVR
Butterfly is three wires and a connector. The following diagram comes from section 3.7 in
the AVR Butterfly Eval Kit Users Guide The smaller table is unreadable
in the pdf, so dont bother trying to read it here or in the pdf, use the larger table to hook
up your three wires...Some soldering is required/recommended.

Step 2: Software Tools
I am almost completely Windows free at home (I run Linux almost all the time, rarely Windows), but
for the moment I only know about Windows tools for the AVR (please send links if you have Linux tools).
You might has well get AVR Studio 4 for Windows and start there. One way to get there is start
at www.atmel.com search on "butterfly", go to the AVR Butterfly page
(the first hit), then select Tools & Software on the left and go to the AVR Studio 4 link. Download,
install, all of that stuff. You can work through the IDE or you can pull out the important tools.
C:\Program Files\Atmel\AVR Tools\ is where you want to start. In the AvrAssembler directory grab
avrasm32.exe and in the Appnotes directory under that grab the m169def.inc file. Under AvrProg
grab avrprog.exe.
Step 3: First Program
Use the AVR Studio IDE or your favorite text editor to write your first AVR program:
.include "m169def.inc"
.org 0x0000
rjmp RESET
RESET:
ldi R16, 0xFF
out DDRB,R16
Loop:
dec R16
out PORTB, R16
rjmp Loop
What I did was stick an led on the port b pins on the AVR board, which is the 10 pin horizontal
group on the lower left side of the board. The first 8 pins are port b, pin 9 is gnd. I put the
led on pins 9 and 8 (port b bit 7). With the program above the led just turns on, the next example
will slow it down.
So you have entered your program. If in the IDE do a build project and it will make a .hex file.
If you are using the command line tool then:
C:\>avrasm32 -fI -o one.hex one.asm
AVRASM: AVR macro assembler version 1.57 (Nov 15 2002 10:58:00)
Copyright (C) 1995-2002 ATMEL Corporation
Creating 'one.hex'
Assembling 'one.asm'
Including 'm169def.inc'
Program memory usage:
Code : 6 words
Constants (dw/db): 0 words
Unused : 0 words
Total : 6 words
Assembly complete with no errors.
I did not feel the Atmel documntation was clear on how to program this thing. If you have the as-shipped
example application loaded, you can follow the menus down to a point to load the program, but since you
are not re-loading that app, it is a one shot deal, not worth discussing. Here is how to load a program,
no matter what is currently in there. The two holes on the lower right corner of the board along the
right side (one on above the other) are a reset and ground.
1) Short these together and release, this puts it into a bootloader program I presume
which is in eeprom.
2) Now press and hold the joystick (press straight down like it is a push-button, not in a direction
like a joystick).
3) Run the avrprog.exe program (or AvrProg from the IDE, under Tools I think). This only works if the
board is plugged in, and the battery is in, and you have done a reset and you are holding the button when
the avrprog program starts. If you do it right you will get a window that looks like this:

4)[Browse...] and find your .hex file (it will remember from the last time so you dont have to do this
very often)
5)Under Flash press the Program button, this will load and verify your program.
6)Exit completely out of avrprog. If you dont you may forget you left it running and you will go nuts
trying to figure out why you cant get a second copy of avrprog to run and recognize the board.
7)Press the joystick in the up direction this will start your program.
Now if you hook up an led from port b bit 7 to ground (mine is soldered on) the led will light, you wont see
it flashing. If you change your program to this:
.include "m169def.inc"
.org 0x0000
rjmp RESET
RESET:
ldi R16, 0xFF
out DDRB,R16
Loop:
ldi R17, 0x01
aloop:
inc R17
cpi R17, 0x00
brne aloop
dec R16
out PORTB, R16
rjmp Loop
The led will blink, AND, the piezo will buzz. Bit 6 of port b goes to the piezo.
Step 4: LCD
The lcd is not what I am used to but thats okay it does work. There are a number of ways
to solve the problem, and I will leave that up to you. You may want to pick up a
couple of application notes from Atmel. AVR064, and AVR065. Search for "AVR064"
on their website. AVR064 also has some software, you will want to download it too.
The butterfly documentation talks about the lcd being the same as the STK502 and they
reference the above app notes. Looking at the app notes and other documentation I
pieced together this program:
.include "m169def.inc"
.org 0x0000
rjmp RESET
RESET:
ldi r16, 0xB7
sts LCDCRB, r16
ldi r16, 0x10
sts LCDFRR, r16
ldi r16, 0x0F
sts LCDCCR, r16
ldi r16, 0x80
sts LCDCRA, r16
ldi r16,0xFF
sts LCDDR0,r16
sts LCDDR1,r16
sts LCDDR2,r16
sts LCDDR3,r16
; sts LCDDR4,r16
sts LCDDR5,r16
sts LCDDR6,r16
sts LCDDR7,r16
sts LCDDR8,r16
; sts LCDDR9,r16
sts LCDDR10,r16
sts LCDDR11,r16
sts LCDDR12,r16
sts LCDDR13,r16
; sts LCDDR14,r16
sts LCDDR15,r16
sts LCDDR16,r16
sts LCDDR17,r16
sts LCDDR18,r16
; sts LCDDR19,r16
hang:
rjmp hang
The ATmega169 docs walk you through setting up the LCD, and looking at the c code provided with AVR064
you can piece together the rest of the story. The above code will turn on all of the lcd segments.
Good, bad, or otherwise, you have to deal with each segment individually, you cant just tell some
lcd controller I want you to put an 'A' on the first segment, you have to go and turn on some segments
and turn off others to get what you want.
This code was supposed to be like the C example and the asm example in the manual where the 0x80 for the LCDCRA
register for example is not written as 0x80 but 1 shifted left LCDEN, but I am having a bit of an html problem
with a double less than so I just figured out the bits instead. Since the settings above are pretty ridgid
for the butterfly you wont need the flexibility to change them so I guess it doesnt matter.
The LCD itself is capable of displaying the segments in the top picture but only the segments in the bottom
picture are wired up on the butterfly.

The next figure shows the relationship between the segments and bits in the register.

What they are trying to say here is that the lower nybble of LCDDR0, LCDDR5, LCDDR10, and LCDDR15
control the segments of the first digit. The upper nybble of LCDDR0, 5, 10, and 15 controls the second
segment. The lower nybble of LCDDR1, 6, 11, and 16 control the third digit and so on. If you look in the
AVR064 example, the LCD_character_table has all the stuff already figured out for you. If you look at
the figure above showing the letter A you will see that the first nybble gets a 0x1 because the A segment
is set but the K segment is not. The next nybble gets a 0x5, because the B and F segments need to be on
and H and J segments need to be off. Basically the registers for the letter A are 0x1, 0x5, 0xF, 0x0. If
you look at the table in the AVR064 C example you will see that they have the value 0x0f51 for the letter A.
Which has all the nybbles just in the reverse order of what you would think. From there I went down the
list to get the values for HELLO.
;H 0x0f50,
;E 0x1e41,
;L 0x1440,
;L 0x1440,
;O 0x1551,
And wrote another small program:
.include "m169def.inc"
.org 0x0000
rjmp RESET
RESET:
ldi r16, 0xB7
sts LCDCRB, r16
ldi r16, 0x10
sts LCDFRR, r16
ldi r16, 0x0F
sts LCDCCR, r16
ldi r16, 0x80
sts LCDCRA, r16
ldi r16,0x00
ldi r17,0x10
sts LCDDR0,r17
ldi r17,0x00
sts LCDDR1,r17
ldi r17,0x01
sts LCDDR2,r17
sts LCDDR3,r16
; sts LCDDR4,r16
ldi r17,0x45
sts LCDDR5,r17
ldi r17,0x44
sts LCDDR6,r17
ldi r17,0x05
sts LCDDR7,r17
sts LCDDR8,r16
; sts LCDDR9,r16
ldi r17,0xef
sts LCDDR10,r17
ldi r17,0x44
sts LCDDR11,r17
ldi r17,0x05
sts LCDDR12,r17
sts LCDDR13,r16
; sts LCDDR14,r16
ldi r17,0x10
sts LCDDR15,r17
ldi r17,0x11
sts LCDDR16,r17
ldi r17,0x01
sts LCDDR17,r17
sts LCDDR18,r16
; sts LCDDR19,r16
hang:
rjmp hang
The documentation and the C example in AVR064 lean towards using interrupts so that you can update all of the
segments within one refresh cycle. I have not looked into that yet, perhaps it is important, perhaps it doesnt
matter, most likely it depends on the application. Either of the examples above clearly show that if the
content is static you dont need to bother, just set it and leave it.
There are a number of holes left out of the above register specs, for example bits 1, 2, 5 and 6 of LCDDR0
and other bits in simliar registers control the segments above and below the main digits. I dont know
the specific mapping for these bits at this time
Step 5: ADC
If you look at the downloads section below and grab the light.asm example (too big to embed in this web
page) it shows you how to sample from the adc, specifically the light sensor. Also note that I am not
doing any of that LCD interrupt stuff they talk about in the mega169 document, and the display looks
fine.
The ADC code was derived from the C example that is loaded in the Butterfly when you buy it. The AVR064
example, which is geared towards a different eval board, helps for the LCD but doesnt help for the ADC.
I started with the AVR064 C code and it didnt work then moved over to the actual Butterfly C code, subtle
differences.
temp.asm reads the temperature input on the adc
Step 6: Linux
Cool, now I dont have to boot windows if I dont want to. First off you can run avrasm32.exe using
wine. Second, the AVR109 Self Programming app note, just does not apply to the butterfly. Dont bother
with it at all. The source code for the bootloader is available on atmels website, looking at the
code (main.c mostly) its pretty simple to see what you have to do to make it work. So I wrote my
own loader for Linux. ser.c is hardcoded for com2 BTW.
- xterm.c
- ser.c
- ser.h
Step 7: Auto-Start
I followed the wrong path for a while on this one, but it is solved now. If you want to use your
Butterfly in a project and you dont want to have to push the joystick up to start it running,
the solution is pretty simple. Short the joystick in the up position.

First off on the right side of port D you will find external power pins, remove the battery and
apply power to these pins plus on the top, ground on the bottom. I have been using 5v from a
pc power supply and have not harmed anything yet. On right side of port B you will find ground
and the joystick up pin, short these together and anytime you apply power to this board it will
start running your application. I recommend using pins and a jumper so you can remove the jumper
and re-program the board.
Step 8: Uart
The uart is setup for 19200 N81 send and receive by the boot loader, so you dont have to
set it up if you dont want to. To send wait for UDRE to be clear in UCSRA, to receive
check RXC. Here is an example program that echos whatever comes in, checking UDRE is
not necessary here other than to have some code to cut and paste from.
mainloop:
getit:
lds r20,0xC0
andi r20,0x80
breq getit
lds r18,0xC6
sendit:
lds r20,0xC0
andi r20,0x20
breq sendit
sts 0xC6,r18
rjmp mainloop
Documents and Downloads
- AVR Butterfly Manual
- AVR Instruction Set
- AVR ATmega169
- AVR ATmega169 supplement
- AVR065: LCD
- AVR064: Temp and LCD
- first.asm
- second.asm
- lcdall.asm
- lcdhello.asm
- light.asm
- temp.asm
Links
- http://www.ecrostech.com
That is all for now, I will add more as I figure it out
avr ta dwelch tod com