(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.
Ken Yap
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.