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?
- Du sparst Dir Schreibarbeit.
- Du kannst Sachen mit Deinem Arduino machen, die gar nicht
vorgesehen sind - also Hacken.
- Du wirst in die Lage versetzt, Quelltexte für
Mikrocontroller zu lesen, die von anderen Leuten geschrieben wurden.
- 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:
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.
|