Ads

Friday, October 24, 2008

Great success!



I was having lunch with a good friend on Wed and we mentioned some interesting projects that we could get into. I stopped myself from dreaming because I have not worked on the alarm clock for a long time. I resolved to write code, flash it, and blink an led by the end of the week.

As you can see above, I made the LED blink. Next step is to setup 4 or 8 LEDs and make them "count" from 0000->1111 (0->16). Then do the same, but using a shift register.

The reason that I have not done it before is because I was scared. It really was as easy as reading 1-2 pages in the datasheet. I had to figure out how to make a "nop" (no operation) but I could have just made the device add a number or something. There seems to be delay code already written in util/delay.h so I will try and use that in the 0->16 counter step to make it change once a second. I also turned all of the ports in "B" to output and on, so I should be able to just add LEDs and have 8 that flash together.

Summary:
xn ... so x can be like, C or B and n can be lik 0-7 (makes sense if you see the pin names)
DDxn: 1->output , 0->input
DDxn configures how the PORTxn acts.
PORTxn: input: 1->pullup resistor active,0->pull up resistor inactive
ouput: 1->driven high,0->driven low
PINxn: 1 -> toggle PORTxn
There was some warning about switching between input and output, it works better if you make sure that you use a specific sequence if you don't want the pin to be in a random state for a period of time.

My LED was on Pin 14 on the DIP, otherwise known as PORTB0 (PB0).

Code (blinkin.c):
#include < avr/io.h >
#define nop() __asm__ __volatile__ ("nop")

int main(void)
{
int i = 0;

DDRB = 0xFF; // set all B's to output
while(1)
{
PORTB = 0xFF; //All On
for(i=0;i<30000;i++)
{ nop(); }

PORTB = 0x00; //All off
for(i=0;i<30000;i++)
{ nop(); }
}

return 0;
}

for the record, these are the commands used to compile/flash:
avr-gcc -I. -I/usr/local/AVR/avr/include -g -mmcu=atmega168 -Os -fpack-struct -fshort-enums -funsigned-bitfields -funsigned-char -Wall -Wstrict-prototypes -Wa,-ahlms=blinkin.lst -c blinkin.c -o blinkin.o

avr-gcc -Wl,-Map,blinkin.out.map -mmcu=atmega168 -lm -o blinkin.out blinkin.o

avr-objcopy -j .text -j .data -O ihex blinkin.out blinkin.hex

avr-objcopy -j .eeprom \

--change-section-lma .eeprom=0 \
-O ihex blinkin.out blinkin.ee.hex

avrdude -c bsd \
-p m168 -P /dev/parport0 -e \
-U flash:w:blinkin.hex


I didn't write those all by hand, I found a nifty Makefile online that I configured, all I have to do is type "make writeflash" to compile/flash it onto the device. I can post the Makefile if anyone is interested.

The big problem that frustrated me was that I wasn't exactly sure how to "start" the code. So for a while I thought I did it wrong because I couldn't even make the LED light. I originally just kept cycling the power. That does not work if you have the programmer still plugged in. Turns out that if you pull the reset line out (pin 1), you start the device.You can leave the other programming pins attached. I might wire a switch to that line so that I can leave the programmer attached and run the code without pulling out a wire and reinserting it.

Should be relatively smooth sailing from here, I am assuming that the hardest parts are setting up the compiler/flasher, learning how to make the code run, and plugging everything into the correct pins.

1 comment:

Spatchcock said...

Excellent work! Now that your software toolchain is proven, and confidence has replaced hope, you should prototype something new: demonstrate working shift registers.

Serial to parallel is pretty useful.

Then, learn about the timer interrupts and flash your name with 8 LEDs.