Ein erstes Programm für den Controller

Nun, da der Controller läuft und wir mit ihm kommunizieren können, ist es Zeit, ein erstes Programm für den Controller zu schreiben. Das Programm wird vorerst nichts besonderes tun, es geht nur darum, die Grundstruktur, die ein solches Programm haben sollte, zu demonstrieren.

Der Code

// Hier sind die Ports etc definiert, also auf jeden Fall einbinden!
#include <avr/io.h>
 
// Unser Hauptprogramm. Weitere Funktionen sind natürlich - wie wir sehen werden - kein Problem
int main (void)
{
  // Setze die Datenflussrichtung von Bit 4 in Port B auf Ausgang
  DDRB = 0x0 | (1 << DDB4);
  // Setze Bit 4 von Port B auf High
  PORTB |= (1 << PB4);
 
  // Diese Schleife wird ausgeführt, solange der Controller Strom hat
  while(1)
  {
    // Nur um sicher zu gehen, dass der Compiler die while Schleife nicht wegoptimiert!
    // Sinnlos ... einfach Bit 4 von Port B auf High setzen ... wieder und wieder.
    PORTB |= (1 << PB4);
  }
 
  // Hier sollten wir niemals ankommen...
  return 0;
}

Das Programm erklärt sich dabei größtenteils durch die Kommentare. Eine kurze Erklärung zu dem Begriff „Datenflussrichtung“:

Jeder einzelne Pin des Controllers kann sowohl als Ausgang, als auch als Eingang funktionieren. Ob der Pin als Ausgang oder als Eingang (beides gleichzeitig geht nicht) betrieben wird, wird mit der Datenflussrichtung spezifiziert. Ein gesetztes Bit bedeutet, dass der Pin als Ausgang verwendet wird.

In unserem Programm hier setzen wir also nur Bit 4 von Port B (das ist Pin 3 laut Datenblatt) als Ausgang.

Anschließend setzen wir eben diesen Pin auf „high“, d.h. wir setzen ihn unter Strom. Wenn wir - während unser Programm auf dem Controller läuft - zwischen Pin 3 und GND die Spannung messen, werden wir feststellen, dass es eine Spannungsdifferenz gibt, also Strom fließt.

Anschließend kommt die while-Schleife. Diese Schleife sollten wir nicht mehr verlassen (denn was macht der Controller wenn unser Programm zu Ende ist? Nichts sinnvolles auf jeden Fall!), deshalb habe ich ein wenig sinnfreien Code in die Schleife gepackt, so dass der Compiler die Schleife nicht wegoptimiert.

Compilieren und Linken

Das geht so:

 avr-gcc -g -mmcu=attiny13 -Wall -Wstrict-prototypes -Os -mcall-prologues -c programm.c

Kompilieren … (für den ATTINY13, mit Optimierung auf Größe)

 avr-gcc -g -mmcu=attiny13 -Wall -Wstrict-prototypes -Os -mcall-prologues -o programm.out -Wl,-Map,programm.map programm.o

Linken …

 avr-objcopy -R .eeprom -O ihex programm.out programm.hex

Zu einer Datei im Intel-Hexformat konvertieren …

TODO(Erklärungen?)

An den Controller übertragen

 avrdude -pt13 -cstk500 -P/dev/ttyUSB0 -U flash:w:programm.hex