I’ve lost touch, and probably memory too. I like Microcontrollers. I will make a Megatron out of these little things one day (if I can stick to it though). So, now that I have decided to revive the hobby again, I think I’ll start with the basics. The difference this time will be, that we’d be using Linux for this purpose in a bid to learn it more and more (psst, Let’s keep an audacious goal of making an OS someday) instead of windows. In windows, I was used to compile in an IDE and burn it using another software and I never gave an iota of thought of how a Makefile worked. Now I do, seriously, my butter on bread depends on it. I’ve worked with AVR16 specifically in the past, mainly because it was the microcontroller that I was introduced to and the only one I had, along with a small kit. It should suffice for the moment, but it would be nice to see if we can learn the 8051 too and probably start venturing into the ARM domain. If I am to make a Megatron, 8-bit will not suffice, now will it, unless we hack around and do something unthinkable (unthinkable because I cannot think of it yet.) That reminds me of Massively Parallel Processing algorithms that I have not read anything about. But hey, take that in the shopping basket too. We'll check out someday.
Okay, so we have a ATMega16 microcontroller, a USBasp ISP programmer, a 9V DC supply adapter and necessary connecting cables. Earlier I used to use the Serial Programmer, but since Serial Ports aren’t seen on Laptops nowadays, I’ll go with the USB. Someday, we’ll use JTAG interface, but it’s this as of now.
Now, remember when we wrote our first program, what did we write? “Hello World”. Well, in this simplistic setup, we definitely cannot write hello world. But we can make it symbolic, like a SOS signal, a LED that blinks continuously.
Now, information presented here (in this section, this post is just a quickie) will make equal emphasis on the hardware specifications and will be fraught with lots of digressions to consider possibilities with which we may evolve. I am probably going to blabber, but hey, you want the code, or you want to learn? If learning is the key, then join the thought trail too, or else, code is given at the end of each post (of course under an adfly link). Also, there will be problems that I will encounter, and if I find an answer to them, I’ll share them here. If I don’t, you’ll probably not know I had them in the first place. Or maybe I will, you might be Bill Gates or Dennis Ritchie (May his blessed soul rest in peace) or who knows a new prodigy.
So, without further ado, let’s write the first code:
#include<avr/io.h> //To tell the Compiler where all the AVR input/output definitions are. #define F_CPU 8000000ul //The logical clock value to be used to compute the timing #include<util/delay.h> //Clock routines here
Now, to make a SOS, it has to be intermittent, or the rescue party will think there is a party going on here. So, we’ll need to turn ON and OFF the LED. This is done using this custom function.
void sleep(uint8_t millisec) { while(millisec) { _delay_ms(1);/* 1 ms delay */ millisec--; } }
I know, I know, it could be done without much fuss, by simply telling a full scale value. But sometimes the system does not accept it, so, we’ll be incremental in our timings.
Now, the main function where we first set the 0th pin of Port A as output port and set it one and zero alternatively, indefinitely.
main() { DDRA |=1<<PA0; /* PA0 will now be the output pin */ while(1) { PORTA &= ~(1<<PA0);/* PA0 LOW */ sleep(100);/* 100 ms delay */ PORTA |=(1<<PA0); /* PA0 HIGH */ sleep(100);/* 100 ms delay */ } }
This is pretty much C (easy?).
Now, we need to compile it. Now, we could make a Makefile and use that template everywhere. But since we are starting from ground zero, let us hand compile it.
So, on the terminal, type:
avr-gcc -mmcu=atmega16 -Os blinky.c -o blinky.o
This basically invokes the AVR-GCC compiler (which I assume you have installed, no?) with the target microcontroller family as atmega16 to compile blinky.c (yes we named it blinky) and also create an object file by the same name and a .o extension.
Then, we need to create a HEX file out of it, because that is what the system understands:
avr-objcopy -j .text -j .data -O ihex blinky.o blinky.hex
This is another program that you must have installed.
This HEX file needs to be burned into the Microcontroller, so connect the USBasp programmer to the PC and to the target board if you haven’t till now and run the following:
avrdude -c usbasp -p m16 -u -U flash:w:blinky.hex
Bummer!
avrdude: Warning: cannot query manufacturer for device: error sending control message: Connection timed out avrdude: error: could not find USB device "USBasp" with vid=0x16c0 pid=0x5dc
Try doing this in root (with sudo)
sudo avrdude -c usbasp -p m16 -u -U flash:w:blinky.hex avrdude: Warning: cannot query manufacturer for device: error sending control message: Connection timed out avrdude: error: could not find USB device "USBasp" with vid=0x16c0 pid=0x5dc
Now now, I think I did it all right. Let’s check if the device is even detected:
lsusb Bus 002 Device 004: ID 16c0:05dc VOTI USBasp AVR Programmer Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Yep, there it is. Then why in the world would it not work. I searched online and someone suggested that the microcontroller is dead. But I am sure it is not. Some say, check if the self program jumper of the USBasp programmer is shorted, it isn’t. So, I search some more. I disconnect my target board and do the same thing again.
sudo avrdude -c usbasp -p m16 -u -U flash:w:blinky.hex
Again, the same.
Then, by divine intervention, I decide to be the superuser and type ‘su’ and password (Yep, even on Ubuntu, I have enabled the admin account, so what?)
Now:
avrdude -c usbasp -p m16 -u -U flash:w:blinky.hex avrdude: error: programm enable: target doesn't answer. 1 avrdude: initialization failed, rc=-1 Double check connections and try again, or use -F to override this check. avrdude done. Thank you.
Aah, finally, some action!
I plug the target back in and do it again.
sudo avrdude -c usbasp -p m16 -u -U flash:w:blinky.hex avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.04s avrdude: Device signature = 0x1e9403 avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file "blinky.hex" avrdude: input file blinky.hex auto detected as Intel Hex avrdude: writing flash (206 bytes): Writing | ################################################## | 100% 1.53s avrdude: 206 bytes of flash written avrdude: verifying flash memory against blinky.hex: avrdude: load data flash data from input file blinky.hex: avrdude: input file blinky.hex auto detected as Intel Hex avrdude: input file blinky.hex contains 206 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 1.17s avrdude: verifying ... avrdude: 206 bytes of flash verified avrdude done. Thank you.
Voila!
Now, just to test if it is working, I connect a resistor and an LED on the Pin 0 of Port A and the negative terminal of LED is connected into the negative terminal of the microcontroller and boy, do I see a dancing light! That is good start. Just to make sure I am not faking it, you can see the video here (I know I know it isn't that good. The music is some track from Dewarists playing on Youtube):
Things to learn, first make necessary check to see if the devices are functioning properly. Do not assume, or you’d be just as haphazard as this post was. There is a flow in which things are to be done, and its name is not emotion.
Link to Source: Here
References:
http://www.linuxjournal.com/article/7289?page=0,2
http://wiki.tldp.org/Avr-Microcontrollers-in-Linux-Howto