Arduino und WinAVR

Der Arduino bringt von Hause aus die entsprechende Programmierumgebung Arduino IDE mit, Funktionen werden über Makros dargestelllt, dem Programmierer wird viel Arbeit abgenommen.

Einige Dinge sind nicht implementiert und müssen dann doch zu Fuß programmiert werden.

WinAVR ist die Programmierumgebung für Programmierer, die auf Schnickschnack verzichten möchten, und auch die volle Kontrolle über ihr Programm besitzen wollen.

WinAVR wird leider zZt nicht mehr weiter entwickelt, der verwendete Compiler AVRGCC reicht jedoch in den meisten Fällen vollkommen aus.

Das Beste an der Sache ist, daß das geschriebene und kompilierte Programm direkt in den Arduino Uno geladen werden kann.

Wieso geht das und wie funktioniert das?

Welche Parameter muss man einstellen?

Nun, eigentlich braucht man ein Programmier-Gerät wie den AVR MKII, der das Programm über die ISP-Schnitstelle in den Flash-Speicher des Mikrocontroller überträgt ( der eigentliche "Brennvorgang" findet intern im Mikrocontroller statt ).

Der Arduino Uno ( das ist das Board, daß ich gerade habe ) hat von Haus aus einen Bootloader im Speicher des ATmega328p. Das kompilierte Programm wird als ASCII-Datei übertragen, dh, es werden nur druckbare Zeichen übertragen und vom Bootloader wieder zurückkonvertiert. Der Bootloader sorgt nun weiter dafür, daß das selbstgeschriebene Programm in den Flashspeicher geflasht, dh programmiert wird.

Ein Knackpunkt ist das Einstellen der richtigen Parameter im Makefile.

 

1. Einstellen des richtigen Mikrocontroller

# MCU name
MCU = atmega328p

# Processor frequency.
...
F_CPU = 16000000

2. Einstellen der Programmierschnittstelle

#---------------- Programming Options (avrdude) ----------------

# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
# -v -F -C c:\avrdude.conf -p m328p -P com4 -c arduino -b 115200 -U flash:w:{FILE}:a
#
#AVRDUDE_PROGRAMMER = stk500v2
#AVRDUDE_PROGRAMMER = stk500v1
AVRDUDE_PROGRAMMER = arduino

# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com4    # programmer connected to serial device

AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep

#AVRDUDE_BITS_PER_SEC = -b 19200
AVRDUDE_BITS_PER_SEC = -b 115200

...

AVRDUDE_FLAGS = -v -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)

 

Die roten Stellen müssen überprüft, ggf. der eigenen Hardware angepaßt werden, zB ist der ComPort bei jedem PC anders, hier hilft ein Blick in den Gerätemanager, auf welchem Port der Arduino sich befindet.

 

Das sollte es gewesen sein. Hier ein kleines Programm zum testen, das kleine gelbe LED blinkt, wenn alles funktioniert hat:

#include <avr/io.h>
#include <util/delay.h>  

// MCU name
#define MCU = atmega328p

// Konstanten
#define LED_Arduino    PB5

/*** SUBROUTINES ***/

/* Function delay_ms
    Funktion:        wartet Millisekunden
    Parameter:    Zeit in Millisekunden
    Rückgabe:        keine

*/
void delay_ms(uint16_t ms)
{
  for(uint16_t t=0; t<=ms; t++)
    _delay_ms(1);
}

/*** Ende SUBROUTINES ***/

int main (void) {
 
    DDRB |= (1<<LED_Arduino);            // DDR PortB.5 auf Ausgang
  PORTB |= (1<<LED_Arduino);            // PortB.5 einschalten
    

    while(1) {
        delay_ms(500);
        PORTB ^= (1<<LED_Arduino);    // invertiere PortB.5
    }
        
    /* wird nie erreicht */
    return 0;
 
}

Hier die Projektdatei incl Quellcode (WinAVR)

Valid XHTML and CSS.