stk500 avr atmega16 linux gcc hello, world
April 4, 2009 2 Comments
Does my title sound like buz-word central? You bet it does. That’s because it was a bit difficult to find any good introductory material on this. Maybe that’s because there’s so much information out there…
Anyway, here is some. The README:
Rich Lundeen
lundrich@isu.eduThe Specification:
———————————The purpose of this assignment is to introduce you to the software tools we will use for the
AVR microprocessor, and to give you a better understanding of the run-time environment that
a C program operates under.
For this assignment, you will write a C main program and two subroutines – one in AVR
assembly, and the other in C. The subroutines should each do the same thing:
1. Monitor a port (your choice) that is connected to a switch. Wait until the switch is
pressed.
2. Once pressed, the routine should keep track of how long the switch is held down.
3. Wait for approximately one second.
4. Using another port (your choice) connected to a LED, turn on the LED for the same
amount of time that the switch was pressed earlier.
In addition to writing the code, determine the size of the code (main and both subroutines) in
your program.———————————-
This code requires avrdude, avr-gcc, and objcopy are installed.
To compile the C version, type:
make
To compile the asm version, type:
make asm
After it’s compiled, to install to a connected and powered on atmega16 board, type:
make install
homework1.avi contains a short demonstration of the C version – however, both do the same thing. It
will play with vlc or mplayer.
Here is a demo of the program.. oooh blinky lights. Yeah, and anyway, the hardest part is just to find a hello world. This includes one in both C and assembly, so good hunting!
Download the source here,
/*main.c*/ #include "portstuff.h" int main (void) { DDRB = 0xff; /*11111111 means all output */ DDRD = 0x00; /*00000000 for all input */ PORTB = 0xff; portmon(); return(0); }
/*portstuff.h*/ #include #include #include void portmon();
/* portstuff.c */ #include "portstuff.h" /*this is in clock cycles for my board. * 30000 seems to be close to about a sec */ const DELAY = 30000; void portmon() { while(1) { unsigned long timer = 0; unsigned long i; /*while a button is pressed */ while (PIND != 0xff) { /*light up the button pressed */ PORTB = PIND; timer += 1; } PORTB = 0xff; /*if the timer is not zero, we need to handle a button pressed */ if (timer != 0) { /*delay for about a second */ for (i = DELAY; i!=0; i--); PORTB = 0x00; /*delay for timer roughly equal to how long button was pressed */ for (i = timer; i!=0; i--); timer = 0; } } }
#Makefile #c specific - this is the default homework1.hex: homework1.out objcopy -S -O ihex homework1.out homework1.hex homework1.out: main.o portstuff.o avr-gcc -mmcu=atmega16 main.o portstuff.o -o homework1.out main.o: portstuff.h main.c avr-gcc -c -mmcu=atmega16 main.c portstuff.o: portstuff.h portstuff.c avr-gcc -c -mmcu=atmega16 portstuff.c #assembly specific rules asm: howework1asm.out objcopy -S -O ihex homework1.out homework1.hex howework1asm.out: main.o portstuffasm.o avr-gcc -mmcu=atmega16 main.o portstuffasm.o -o homework1.out portstuffasm.o: portstuff.h portstuff.s avr-gcc -c -mmcu=atmega16 portstuff.s -o portstuffasm.o #clean and install clean: rm ./*.o ./*.hex ./homework1.out install: avrdude -y -C /etc/avrdude/avrdude.conf -p atmega16 -P /dev/ttyS0 -c stk500v2 -U flash:w:homework1.hex:i
/*portstuff.s*/ #include "portstuff.h" .file "portstuff.c" PORTB = 56-0x20 PORTD = 48-0x20 ALLON = 31 WAIT = 0xa .text .global portmon .type portmon, @function portmon: /*initialize count to zero */ .BEGIN: /*r18 is our counter*/ ldi r18,0x00 /*initialize port values*/ in r24,PORTD out PORTB, r24 .LEDWAIT: in r24,PORTD nop /*see if the button is currently pressed - if it is then continue if not jump to .LEDWAIT */ cpi r24, lo8(-1) breq .LEDWAIT .BUTTONPRESSED: out PORTB, r24 /*measure the number of delays the button is pressed*/ rcall delay inc r18 /*see if button is still currently pressed - if it is then jump to Buttonpressed */ in r24, PORTD cpi r24, lo8(-1) brne .BUTTONPRESSED out PORTB, r24 ldi r23, WAIT .DELAYSECOND: /*theoretically this delays a second */ rcall delay dec r23 cpi r23,0 brne .DELAYSECOND .LEDSON: /*light up all leds for the amount of time the one was pressed*/ out PORTB, ALLON rcall delay dec r18 cpi r18,0 breq .BEGIN rjmp .LEDSON /*delay function makes time reasonable to deal with */ delay: ldi r17,0x60 waitouterloop: ldi r16,0xFF waitinnerloop: subi r16,0x01 brne waitinnerloop subi r17,0x01 brne waitouterloop ret .size portmon, .-portmon