Wie funktioniert das Blinksdings-Programm?



#include <avr/io.h>     // Bibliothek einbinden, die die AVR-Bezeichnungen kennt
#define F_CPU 1200000UL // 1,2 MHz (wird von "delay.h" benoetigt)
#include <util/delay.h> // die Bibliothek "delay.h" enthält den Befehl "_delay_ms()"

int main(void)
{
  DDRB |= _BV(PB4);     // PB4 ist jetzt Ausgang


  while (1) {

    PORTB &= ~_BV(PB4); // PB4=Low -> LED an
    _delay_ms(250);     // Warte 250ms

    PORTB |= _BV(PB4);  // PB4=High -> LED aus
    _delay_ms(250);     // Warte 250ms
  }

  return 0;
}



Wenn Du noch gar nicht die Programmiersprache C kannst, kannst Du sie hier erlernen.


Wenn Du die Programmiersprache C bereits einwenig kannst, sind Dir folgende Befehle vielleicht noch unbekannt:


  DDRB |= _BV(PB4); 
  
  PORTB &= ~_BV(PB4);
  
  PORTB |= _BV(PB4);


Betrachten wir einmal die Pinbelegung eines Attiny13:

pinout

Vcc ist die Betriebsspannung (Plus) und GND (engl. Ground) ist Masse (Minus).

Als Ausgänge können wir die Anschlußpins benutzen, die da heißen: PB0, PB1, PB2, PB3, PB4 und PB5.
Es handelt sich hierbei um sechs digitale Ein-/Ausgänge eines Ports mit Namen: "PORT B".

Vielleicht erinnert Dich das Wort "Port" an einen Hafen, wo die Schiffe ein- und ausfahren - das ist gar nicht mal so falsch.
Unser Attiny hat nur einen Port mit Namen B. Andere Mikrocontroller mit mehr Anschlußpins, wie z. B. Atmega8, haben sogar mehrere Ports.

Diese Anschlüsse kann man als digitale Ausgänge oder als digitale Eingänge benutzen.
(Mann kann auch noch mehr damit machen, doch dazu später.)

Zu diesem PORT B gehört außerdem das Datenrichtungsregister DDR B (data direction register B):

DDRB:
5. bit 4. bit 3. bit 2. bit 1. bit 0. bit

Das Datenrichtungsregister legt fest, ob’s rein (Eingang) oder raus (Ausgang) gehen soll.

Wenn PB4 (also Anschlußbeinchen 3 des Attiny13) ein Ausgang sein soll, dann muß im Datenrichtungsregister DDRB das 4. bit gesetzt sein, so wie hier:

DDRB:
0 1
0
0
0
0


In der Programmiersprache C geht das z. B. so:  DDRB |= _BV(PB4);

Es ginge auch mit: DDRB = 16;
Warum 16? Eine 16 in Binärschreibweise sieht so aus: 010000


Soll nun der Ausgang PB4 auf HIGH gesetzt werden, geht das mit: DDRB |= _BV(PB4);
Soll der Ausgang PB4 auf LOW gesetzt werden, geht das mit: DDRB &= ~_BV(PB4);
(Das Setzen und Löschen von Bits wird hier ausführlich erklärt.)

Eine am PB4 angeschlossene LED würde nun aus und an gehen - allerdings so schnell, dass man es nicht mehr sehen könnte.
Darum enthält das Programm zwei Wartezeiten (engl. delay).


Und damit es das Ganze nicht nur einmal tut, passiert das Setzen und Löschen von PB4 in einer Endlosschleife.

Du erinnerst Dich:


 while(1){
    // --- diese Schleife endet nie ---    
  }