(Updated for Arduino 2 IDE.)
As all my friends know, my mugshot is used to illustrate the word lazy in dictionaries. 😉
Anyway I found this AVR MCU in my junkspares box and wanted to test it out. I quickly ascertained that I should install the AVR-gcc toolchain. Work! Four-letter word!
Wait a moment, isn't the toolchain already included in the Arduino IDE which I already have? I didn't want to use the IDE for bare metal programming because it assumes a bootloader to transfer to a boilerplate main() that calls setup() and loop(), a programmer like an Arduino board, and a definition for your MCU's board. (But if you want to go that way, look into MiniCore.) I just wanted the tools. In Arduino 1.8 they lived under /opt/arduino-1.8.12/hardware/tools/avr on my Linux machine, and the binaries were under bin/. However in the Arduino 2 IDE, the toolchain is a package and installed under ~/.arduino15, in particular ~/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/ Note that this may be different depending on the release version, so check it yourself. So the iinstructions differ just a bit between the versions.
For Arduino 1.8:
So, first I make a symbolic link
$ ln -s /opt/arduino-1.8.12 /opt/arduino
and use /opt/arduino for other symlinks so that when I upgrade I only have to shift the arduino link and not redo all the other symlinks.
Now there are two ways to make the executables available, add /opt/arduino/hardware/tools/avr/bin to $PATH, or make symlinks from another PATH directory to them. I used the latter.
$ cd /usr/local/bin $ ln -s /opt/arduino/hardware/tools/avr/bin/* .
End Arduino 1.8.
For Arduino 2 IDE:
Only the binary directory differs. You may wish to make a symbolic link as above but that's optional.
$ cd /usr/local/bin $ ln -s ~/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/* .
End Arduino 2 IDE.
Check that it works
$ which avr-gcc /usr/local/bin/avr-gcc
Setting that up only took a few minutes. By the way you probably need to use sudo or su to do some of those things.
Now to write a very special program, blink.c: 😉
#define __AVR_AT90S8515__ 1
#include <avr/io.h>
#include <util/delay.h>
void delay(unsigned int ms)
{
while (--ms)
_delay_ms(1.0);
}
int main(void) {
PORTB = 0;
DDRB = 0xFF; // LED bank
while (1) {
PORTB = 0x55;
delay(500);
PORTB = 0xAA;
delay(500);
}
}
The Makefile that controls the build:
CC=avr-gcc
F_CPU=4000000
DEBUG=
CFLAGS=-Wall $(DEBUG) -Os -DF_CPU=$(F_CPU)
INCLUDES=
AVRSIZE=avr-size
OBJCOPY=avr-objcopy
blink.hex: blink.bin
blink.bin: blink.c Makefile
%.s: %.c
$(CC) $(CFLAGS) $(INCLUDES) -S $<
%.bin: %.c
$(CC) $(CFLAGS) $(INCLUDES) $< -o $(<:.c=.bin)
$(AVRSIZE) -C $(<:.c=.bin)
%.hex: %.bin
$(OBJCOPY) -j .text -j .data -O ihex $< $(<:.bin=.hex)
clean:
rm -f *.s *.bin *.hex
As it turned out I didn't need any -I options because the Arduino toolchain implicitly includes .h files from the toolchain include directory. All you have to do is define the MCU type before the #include <avr/io.h>. F_CPU is defined to be the crystal frequency for correct delays. Notice that there is no flash rule that calls avrdude. This because I will be flashing the program with my programmer.
And here is the resulting blink.s:
.file "blink.c" __SP_H__ = 0x3e __SP_L__ = 0x3d __SREG__ = 0x3f __tmp_reg__ = 0 __zero_reg__ = 1 .text .global delay .type delay, @function delay: /* prologue: function */ /* frame size = 0 */ /* stack size = 0 */ .L__stack_usage = 0 .L2: sbiw r24,1 brne .L3 /* epilogue start */ ret .L3: ldi r30,lo8(999) ldi r31,hi8(999) 1: sbiw r30,1 brne 1b rjmp . nop rjmp .L2 .size delay, .-delay .section .text.startup,"ax",@progbits .global main .type main, @function main: /* prologue: function */ /* frame size = 0 */ /* stack size = 0 */ .L__stack_usage = 0 out 0x18,__zero_reg__ ldi r24,lo8(-1) out 0x17,r24 ldi r29,lo8(85) ldi r28,lo8(-86) .L5: out 0x18,r29 ldi r24,lo8(-12) ldi r25,lo8(1) rcall delay out 0x18,r28 ldi r24,lo8(-12) ldi r25,lo8(1) rcall delay rjmp .L5 .size main, .-main .ident "GCC: (GNU) 7.3.0"
I flashed this to the MCU with the programmer. Unfortunately when I put it on the development board described in #Adventures with a STC89C52 development board nothing happened. Maybe the chip is bad, or maybe the board isn't suitable for it. I did at first make the mistake of using the onboard 11.0592 MHz crystal until I realised that was out of the specifications of the AVR MCU I had, but substituting a slower crystal didn't help. Maybe I'll have to put the MCU on a breadboard.
But that's for another day. I'm satisfied that I now have a toolchain so I can cross AVR off my to-do list.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.