Getting started with AVRs on Debian and Debian-derived linux distros
1. Installing the necessary tools
The commands can be found
here.
I included them here in case of the server being taken down:
sudo apt-get update
sudo apt-get install gcc-avr binutils-avr avr-libc gdb-avr avrdude
Make sure that sudo is operational!
If it's not, edit '/etc/sudoers' using 'visudo', including your username.
2. My script
Using the above tools on their own can cause a lot of unexplained artifacts. To mitigate that, I made a script.
This script uses some 2-step process and unexplained options that somehow work. I also added the MCU frequency
to the command line.
I call this script 'avrc'.
To integrate it into your shell, put in /usr/local/bin or somewhere else, adding that directory to $PATH.
#!/bin/sh
cp $1 temp.c
# -D THING=12 -> #define THING 12
avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=$2 -DF_CPU=$3 -D__DELAY_BACKWARD_COMPATIBLE__ $1 -o temp.o
avr-gcc -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=$2 -o temp.elf temp.o -lm
3. Hardware
Unlike the Arduino IDE, this method can be used to program ANY AVR microcontroller with an SPI interface.
Buy a programmer (I recommend USBASP), an IDC 10 wire, and an IDC 10 breadboard breakout board.
Find actual pin numbers in datasheets (I recommend
https://www.alldatasheet.com).
Hook this up like so:
Wiring diagram
WARNING! If you're wiring this from the plug, remember to flip this diagram!
Example for ATTINY85
3a. Special pins that appear in some MCUs
This is not a comprehensive list!
- ~PEN - Must be connected to ground during powerup to enable SPI programming
- AVCC - connect to 5V
4. Configuration and fusebits
Fusebits are configuration bits that are programmed through the programmer like any other memory.
Fusebits determine the clock frequency and several other fearures.
Use
this to interactively set them and when you're done,
run:
'avrdude' + '-c' + your programmer name, mine is usbasp + '-p' + MCU name (if you fail, it will display the list) + all the -U's that the calculator yielded
5. Let's get coding!
Here's an example code that plashes the PD7 pin on and off:
#include <avr/io.h>
#include <util/delay.h>
#define BIT0 1
#define BIT1 2
#define BIT2 4
#define BIT3 8
#define BIT4 16
#define BIT5 32
#define BIT6 64
#define BIT7 128
int main() {
DDRD |= BIT7;
while (1) {
PORTD |= BIT7;
_delay_ms(1000);
PORTD &= ~BIT7;
_delay_ms(1000);
}
return 0;
}
I won't dive into how this works, since this is not the article about ports.
So how do we upload this? Firstly we use my avrc script:
avrc blink.c atmega32a 16000000UL
blink.c is the filename, atmega32a is the MCU name, 16000000UL is the clock frequency in Hertz. Remember to add the UL at the end!!!
Then to upload that, we use avrdude once again, but with flash this time.
avrdude -cusbasp -pm32a -Uflash:w:temp.elf
I already discussed about the first 2 parameters in the fusebits section, so I won't repeat myself.
The -Uflash:w:temp.elf indicates to write the program that avrc generated - temp.elf into flash memory.
And that's it! You have a blinking LED!