Читать книгу Mit Arduino die elektronische Welt entdecken - Erik Bartmann - Страница 158
Register direkt beeinflussen
ОглавлениеIm Bastelprojekt 2 über die Low-Level-Programmierung des Arduino haben wir gesehen, wie einfach es ist, die digitalen Pins über die Manipulation von Registern zu beeinflussen. Hinsichtlich des Lauflichts kann man sich die Sache zunutze machen. Der nachfolgende Schaltplan verfügt lediglich über sechs LEDs mit den entsprechenden Vorwiderständen, wobei ich aber jeder LED eine kleine Zahl beigestellt habe. Wozu das ganze sinnvoll ist, werden wir gleich sehen.
Abb. 8: Der Schaltplan für unser kleines Lauflicht
Werfen wir noch einmal einen Blick auf das Register PORT B.
Die acht Bits eines Ports werden zu einem sogenannten Byte zusammengefasst. Jedes einzelne Bit dieses Bytes besitzt eine Nummer, die von rechts nach links aufsteigend bei 0 beginnt, wie das in der oberen Reihe zu erkennen ist. Somit können wir jedes einzelne Bit eindeutig von 0 bis 7 adressieren. Jedes einzelne Bit besitzt neben seiner Position innerhalb des Bytes einen Stellenwert oder eine Wertigkeit, die eben genau von der betreffenden Position innerhalb des Bytes abhängt und ebenfalls von rechts nach links zunimmt. Die untere Reihe zeigt die Wertigkeit jedes einzelnen Bits an. Die Frage ist nur, wie diese Werte eigentlich zustande kommen. Das ist sehr einfach! Da das binäre System lediglich die beiden Zustände 0 und 1 kennt, ist die Basis zur Berechnung der Stellenwertigkeit die Zahl 2. Wir erinnern uns, dass unser Dezimalsystem die Ziffern 0 bis 9 kennt und demnach zehn mögliche Zustände vorhanden sind. Die Basis zur Berechnung der Stellenwertigkeit ist demnach die Zahl 10.
Doch kommen wir zurück zum binären System. Wie berechnet man die Stellenwertigkeit? Das erfolgt nach folgender Formel:
Wie groß ist also die Wertigkeit des Bits an der Position 4? Dann wollen wir mal sehen:
Sehen wir uns jetzt die Variante an, die mithilfe der Register- beziehungsweise Bit-Manipulation realisiert wird. Um das gewünschte LED-Muster zu erzeugen, muss lediglich an den Stellen innerhalb des Bytes eine 1 stehen, an denen die LEDs leuchten sollen. Zum besseren optischen Verständnis habe ich hier anstelle der LED-Bar, wie sie auf dem Arduino Discoveryboard zum Einsatz kommt, richtige LEDs mit 5mm Durchmesser verwendet, was du natürlich ebenfalls machen kannst:
Der entsprechende Sketch-Code dazu sieht wie folgt aus:
void setup() { DDRB = 0b11111111; // PORT B komplett als OUTPUT PORTB = 0b00010101; // Erzeugung des LED-Musters } void loop() { /* leer */ }
Wir sehen, dass die Zeile mit der verwendeten Bit-Kombination
PORTB = 0b00010101;
genau dem LED-Muster entspricht. Natürlich muss bei der Initialisierung keine Binärzahl verwendet werden. Es funktioniert auch mit einer Ganzzahl. Machen wir ein kleines Experiment und lassen uns ein paar Bit-Kombinationen von 0 bis 63 anzeigen. Dazu muss lediglich ein Wert immer um 1 inkrementiert – also erhöht werden. Diesmal muss sich aber ein Teil des Codes innerhalb der loop-Funktion befinden, denn es soll ja in regelmäßigen Zeitabständen eine Änderung bewirkt werden:
byte pattern = 0; void setup() { DDRB = 0b11111111; // PORT B komplett als OUTPUT } void loop() { PORTB = pattern++; // Inkrementieren von pattern delay(100); // Kurze Pause von 100ms }
Die Variable pattern ist vom Datentyp byte und hat somit acht Bits und kann Werte von 0 bis 255 speichern. Wenn wir sie innerhalb der loop-Funktion inkrementieren, dann wird irgendwann einmal ein sogenannter Überlauf erfolgen, wenn der Inhalt der Variablen 255 beträgt und anschließend noch einmal der Wert 1 addiert wird. Das funktioniert natürlich nicht, denn das Fassungsvermögen ist erschöpft. Es erfolgt der genannte Überlauf und das Spiel beginnt bei 0 von vorn. Mit folgender Zeile erfolgt das Inkrementieren der Variablen, wobei der Inkrement-Operator, der durch die beiden Pluszeichen repräsentiert wird, die Aufgabe des Hochzählens übernimmt:
PORTB = pattern++;
Man hätte das Gleiche auch mit den folgenden Zeilen erreicht:
pattern = pattern + 1; PORTB = pattern;
Das ist natürlich Geschmackssache, aber Programmierer lieben es, Dinge zu verkürzen und so wenig Code wie möglich zu formulieren.