In diesem Kapitel geht es unter anderem um die arithmetischen Instruktionen:
Die arithmetischen Instruktionen behandeln nicht die Festpunkt-Multiplikation; sie wird später thematisiert. Bevor es losgeht, hier eine Übung zum Anwärmen.
Du solltest jede einzelne Programmzeile durchgehen und beschreiben können, was der Controller dort macht. Sollten unbekannte Instruktionen auftauchen, schlage im Instruction Set Summary nach. Beachte, welche Flags jeder einzelne Befehl möglicherweise beeinflussen kann und beantworte dann die Frage,
Programm: Simulation1.asm
Einschränkungen für die Arithmetik-Befehle
Die richtige Lösung zur Frage aus Übung 1 lautet: PORTB.0, PORTB.1 und PORTB.2 leuchten auf. Der Rest ist ausgeschaltet.
Nach den beiden Grundrechenarten Addition und Subtraktion wenden wir uns jetzt der Multiplikation zu. Dafür stellen ATmega-Prozessoren sechs Instruktionen bereit, von denen erst einmal nur die ganzzahligen Produkte interessieren. ATtiny-Bausteine der älteren Bauart verfügen nicht über diese Instruktionen.
Dem Instruction Set Summary des ATmega8 ist zu entnehmen:
Neben drei Instruktionen zur Multiplikation werden auch zwei Befehle zur Datenübertragung und ein weiterer Verzweigungsbefehl in einem Simulationsprogramm genauer angeschaut.
Einschränkungen
In diesem Kapitel werden die folgenden Befehle angesprochen und in Simulationsprogrammen genauer untersucht (siehe Tabelle 1).
Übung 2 - Simulation zu den Multiplikationsbefehlen: MUL, MULSU, MULS | |
Material |
|
Aufgaben |
|
Das Programm Multiplikation_1.asm
Wir arbeitet das Programm Multiplikation_1.asm?
Abb. 1a - Nach sieben Instruktionsschritten wurde die Multiplikation zweier vorzeichenloser Zahlen mit MUL R16,R17 ausgeführt und das Ergebnis in R1:R0 abgelegt: 0000 0000 0011 1000 (siehe Programmzeile 28). Die binäre Zahl entspricht der positiven Dezimalzahl 56 und ist das Produkt aus 8 und 7. Flags wurden keine gesetzt.
Abb. 1b - Nach acht Instruktionsschritten wurde die Multiplikation zweier negativer Zahlen mit MULS R18,R19 ausgeführt und das Ergebnis in R1:R0 abgelegt: 0000 0000 0011 1000 (siehe Programmzeile 31). Die binäre Zahl entspricht der positiven Dezimalzahl 56 und ist das Produkt aus -8 und -7. Flags wurden keine gesetzt.
Abb. 1c - Nach zwei weiteren Instruktionsschritten wurde die Multiplikation mit MULSU R18,R16 ausgeführt und das Ergebnis in R1:R0 abgelegt: 1111 1111 1100 1000 (siehe Programmzeile 34). Das MSB ist 1; es liegt ein negatives Ergebnis vor. SREG(C) ist gesetzt. Durch Zweierkomplement-Bildung kann das Ergebnis in eine lesbare Form gebracht werden. Es ist - wie zu erwarten - die Zahl -56, das Produkt aus -7 und 8.
Achtung: R18 (Rd) muß die vorzeichenbehaftete Zahl enthalten, R16 (Rr) muss vorzeichenlos sein. Vertauscht man die beiden Inhalte, ist das Ergebnis verfälscht.
Für die Division stellen die 8-Bit ATmega-Typen keine direkt einsetzbaren Instruktionen bereit. Man muss dann über andere Instruktionen das Problem softwaremäßig lösen. Darauf gehen wir hier nicht ein.
Statt dessen wenden wir uns jetzt den Auf- und Abwärtszählern zu. Die dazu notwendigen Befehle sind
In den folgenden beiden Übung 2 und 3 nähern wir uns dem Verhalten dieser beiden Instruktionen über Simulationsprogramme, um anschließend die Ergebnisse auf einem STK200 Board auf der LED Bargraf Anzeige sichtbar zu machen.
Der Befehl INC lässt sich auf alle Arbeitsregister anwenden. Sobald der höchste Zählerstand erreicht ist - bei 8-Bit ist das die Zahl 255 - beginnt der Zähler wieder bei Null. Das lässt sich in einer Zählschleife abfragen.
Übung 3 - Simulation zum Aufwärtszähler - Instruktion: INC | |
Material |
|
Aufgaben |
|
Das Programm zaehler_rauf.asm
Wie arbeitet das Programm zaehler_rauf.asm ?
Abb. 3 - Das Bild zeigt einen Zwischenstand nach 388 Befehlsaufrufen und 517 µs. Sobald das MSB (Bit 7) im Zählerstand gesetzt wird, werden im SREG die Flags V und N gesetzt (siehe Abbildung).
Wenn der Zählerstand 1111 1111 erreicht ist, springt der Zähler mit der nächsten INC-Anweisung auf 0000 0000 zurück, die Flags VN werden gelöscht und Z gesetzt.
Das Programm benötigt 3 Zeittakte zur Ausführung der Instruktionen:
Bei einer Taktfrequenz von 1 MHz entspricht das einer Zeit von 3 µs pro Zählerstandsanzeige. Zu schnell für das menschliche Auge, um einzeln wahrgenommen zu werden; in einem Realexperiment "sehen" wir, dass alle LEDs irgendwie leuchten.
Wie lässt sich die Ausgabegeschwindigkeit reduzieren?
Dies läßt sich dadurch erreichen, dass nach jeder Ausgabe am PORTB (LEDs), das Programm eine Warteschleife durchläuft. Dies wird in der folgenden Übung 4 gezeigt.
Übung 4 - Aufwärtszähler mit Warteschleife | |
Material |
|
Aufgaben |
|
Das Programm zaehler_warteschleife.asm
Die Ausgabe auf der LED Bargrafanzeige eines STK200
LED7 blinkt in dem Kurzfilm mit einer vom Auge deutlich wahrnehmbaren Frequenz von ca. 3 Hz, während die Blinkfrequenz von LED0 mit den Augen nicht mehr aufgelöst werden kann.
Wie arbeitet das Programm zaehler_warteschleife.asm ?
R19 (zaehler_ab oder Abwärtszähler) wird mit dem Wert 220 geladen. Anschließend werden die PortB-Pin eingelesen und in zaehler_auf (R16) abgelegt.
Der Aufwärtszaehler (R16) wird um 1 erhöht (INC) und der neue Wert an die Portausgänge von PORTB übergeben. Sind an PORTB im Simulationsprogramm LEDs angeschlossen, dann wird ein binärer Aufwärtszähler von 0 (0b0000 0000) bis zur Zahl 255 (0b1111 1111) gezeigt. Die Warteschleife bei der Marke warten dient der Zeitverzögerung.
Marke warten;
In Klammern sind die Takte für die Ausführung der jeweiligen Instruktion angegeben (siehe ATmega8 ISS). Für das Ein- und Ausschalten einer LED benötigt der Controller 2210 Takte. Bei einer Taktfrequenz von 1 MHz entspricht das 2,21 msec oder einer Frequenz von ca. 452,5 Hz. LED7 leuchtet dann mit einer Frequenz von ca. 3,5 Hz.
Das wird mit einem Oszilloskop überprüft (siehe Abb. 5).