Fünfkanallauflicht (und: Was ist ein Port?)



Dies ist nicht einfach nur die Erweiterung des Dreikanallauflichtes.

In diesem Experiment lernst Du, wie Du mit etwas Mikrocontrollerwissen das Programm verkürzen kannst.

Außerdem lernst Du, wie Du mit etwas Mikrocontrollerwissen die Möglichkeiten Deines Arduinoboards mit Funktionen erweitern kannst, die eigentlich gar nicht vorgesehen sind. Ja - das nennt man HACKEN!










Hier das Programm, wie es die Arduino-Programmiersprache eigentlich vorsieht:

/*
  5-Kanal-lauflicht
  LEDs an den Ausgängen: 8..12
  LED Strombegrenzung: R1 = 220 Ohm
   
  www.arduinospielwiese.de 
*/
 
 
void setup() {               
  pinMode( 8, OUTPUT);
  pinMode( 9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
}


void loop() {
  digitalWrite(8, HIGH);
  delay(200);
  digitalWrite(8, LOW); 
  digitalWrite(9, HIGH);
  delay(200);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(200);
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH);
  delay(200);
  digitalWrite(11, LOW);
  digitalWrite(12, HIGH);
  delay(200);
  digitalWrite(12, LOW);
}

Fertig!



Achtung: Hier nur weiterlesen, wenn Du ein Hacker werden willst!
(Aber das bist Du doch schon, nicht wahr?)


Das obige Programm ist schon einiges an Schreibarbeit.

Aber es geht Kürzer (14 Programmzeilen weniger)!

Hier das Programm mit Anweisungen, wie es der avr-gcc erlaubt, der ja von der Arduino-Programmierumgebung benutzt wird:

/*
  5-Kanal-lauflicht
  LEDs an den Ausgängen: 8..12
  LED Strombegrenzung: R1 = 220 Ohm
   
  www.arduinospielwiese.de 
*/

 
void setup() {               
  DDRB = 0b00011111;
}


void loop() {
  PORTB = 0b00000001;  delay(200);
  PORTB = 0b00000010;  delay(200);
  PORTB = 0b00000100;  delay(200);
  PORTB = 0b00001000;  delay(200);
  PORTB = 0b00010000;  delay(200);
}


Mit "avr-gcc" bezeichnet man die für AVR-Mikrocontroller erweiterte Variante des GNU C-Compilers "gcc".


Was hast Du davon, solche Anweisungen zu kennen?

  1. Du sparst Dir Schreibarbeit.

  2. Du kannst Sachen mit Deinem Arduino machen, die gar nicht vorgesehen sind - also Hacken.

  3. Du wirst in die Lage versetzt, Quelltexte für Mikrocontroller zu lesen, die von anderen Leuten geschrieben wurden.

  4. Arduino ist nicht alles!
    Irgendwann wirst Du Mikrocontroller alleine, also ohne eine "riesige" Arduino-Platine drumherum verwenden wollen. Dann wirst Du den avr-gcc verwenden.


Erklärung dieser "komischen" Anweisungen:

Schauen wir uns einmal die Pinbelegung unseres Mikrocontrollers an:



Als digitale Ausgänge (also Ausgänge, die HIGH und LOW liefern können) können wir all die Anschlusspins benutzen, die da heißen:
PB0 bis PB7, PC0 bis PC6 und PD0 bis PD7.

Es handelt hierbei um sogenannte Ports. Vielleicht erinnert Dich das Wort "Port" an einen Hafen, wo die Schiffe ein- und ausfahren - das ist gar nicht mal so falsch.

Unser Atmega328 hat drei Ports, nämlich Port B, Port C und Port D.

So ein Port hat gewöhnlich 8 Anschlüsse (nur beim Atmega328 hat der Port C wegen Platzmangels lediglich 7 Anschlüsse).
Der Port B hat die Anschlüsse PB0 bis PB7.
Der Port C hat die Anschlüsse PC0 bis PC6.
Der Port D hat die Anschlüsse PD0 bis PD7.
Diese Anschlüsse kann man als digitale Ausgänge oder als digitale Eingänge benutzen.

Man kann auch noch mehr damit machen, doch dazu später.

Nehmen wir einmal PB0 bis PB7. Diese Beinchen gehören zum PORT B.
Zu diesem PORT B gehört außerdem das Datenrichtungsregister DDR B (Data Direction Register B).

Ein Register ist im Prinzip eine Aneinanderreihung einiger Speicherzellen (z. B. 8 bit).

irgendein Register:
7. bit 6. bit 5. bit 4. bit 3. bit 2. bit 1. bit 0. bit

Wenn PB0 (also Anschlussbeinchen 14 des Atmega328) ein Ausgang sein soll, dann muss im Datenrichtungsregister DDRB das 0. bit gesetzt sein, so wie hier:

DDRB:
0
0 0 0
0
0
0
1


Das Datenrichtungsregister legt fest, ob's rein (Eingang) oder raus (Ausgang) gehen soll. Wenn PB0 ein Ausgang sein soll, muss im Datenrichtungsregister B das nullte Bit gesetzt sein. In der Programmiersprache C geht das z. B. so: DDRB = 0b00000001;

Statt: "0. bit vom Port B" kann man auch sagen: "PB0".

Sollen PB0 und PB1 Ausgänge sein, ginge es mit: DDRB = 0b00000011;


Die binäre Zahl 00000011 bekommt in der Programmiersprache C vorn ein "0b" dran. Das "b" steht für "binär".

Soll nun der Ausgang PB0 auf HIGH gesetzt werden, geht das mit: PORTB = 0b00000001;
Soll der Ausgang PB0 auf LOW gesetzt werden, geht das mit: PORTB = 0b00000000;

Eine am PB0 angeschlossene LED würde nun an und aus gehen - allerdings so schnell, dass man es nicht mehr sehen könnte.
Darum enthält ein LED-Blinkprogramm häufig Verzögerungen (engl. delay).

Mit diesem Wissen im Hinterkopf, ist unser "komisches" Programm nun ganz leicht zu verstehen:

void setup() {               
  DDRB = 0b00011111; //im Datenrichtungsregister für Port B werden die Ausgänge festgelegt: PB4, PB3, PB2, PB1, PB0
}


void loop() {
  PORTB = 0b00000001;  delay(200); //in den 5 Zeilen wird gesagt, welcher Pin des Port B wann HIGH ausgeben soll
  PORTB = 0b00000010;  delay(200);
  PORTB = 0b00000100;  delay(200);
  PORTB = 0b00001000;  delay(200);
  PORTB = 0b00010000;  delay(200);
}


Wie bekommt man nun raus, welcher Arduino-Anschluss welchem Mikrocontroller-Port entspricht?
Nun: Du könntest Dir mal den Schaltplan des Arduino näher ansehen.
Aber bitte nicht erschrecken! Der ist ganz schön groß. Was Du suchst, findest Du unten rechts.


Und was ist jetzt mit Hacken?

Nur mal ein Beispiel:
Wenn Du obige Anweisungen kennst, kannst Du die analogen Arduino-Eingänge A0 bis A5 ebenfalls als digitale Ausgänge für weitere 6 LEDs benutzen. Das sind nämlich einfach PC0 bis PC5.