Startseite

AVR Assembler Workshop

Anhand eines kleinen elektronischen Spiels lernt der Schüler in kleinen Schritten, einen AVR Mikrocontroller in Assembler zu programmieren.

Empfohlen für den Technik-Unterricht ab 9. Klasse, die Schüler sollten zuvor die Funktion von LED's und Widerständen kennen gelernt haben. Der Lehrer soll bereits mit dem AVR Studio und dem Programmieradapter vertraut sein.

Wir werden den ATtiny 13 benutzen. Er hat insgesamt 8 Pins, davon können 5 Pins frei programmiert werden. Der Befehlssatz der AVR Mikrocontroller ist im AVR 8bit Instruction Set ausführlich dokumentiert.

Die Materialliste befindet sich ganz unten.

1) Entwicklungsumgebung

Zum Programmieren brauchen Sie eine Entwicklungsumgebung. In dieser Anleitung verwenden wir das AVR Studio 4.19.

Bildschirmfoto vom AVR Studio. Zeigt links die CPU Register des Simulators und rechts ein Stück Assembler Code

2) Die ISP Schnittstelle

AVR Mikrocontroller haben eine serielle Schnittstelle, durch die man das Programm vom PC in den Chip überträgt. Für diese Schnittstelle verwendet man einen 6-poliger Pfostenstecker. Dies ist die Pinbelegung aus Sicht des Mikrocontrollers:

Daten, Ausgang MISO 1 2 VCC Spannungsversorgung
Takt, Eingang SCK 3 4 MOSI Daten, Eingang
Eingang, Low=Programmieren /RESET 5 6 GND Masse

Pin 1 ist in der Regel rot oder mit einem Pfeil markiert.

Diese Schnittstelle heisst ISP, was "In System Programming" bedeutet. Der Name soll andeuten, daß diese Mikrocontroller in der Schaltung programmiert werden können. Wir werden den Chip allerdings zum Programmieren aus der Schaltung heraus nehmen.

3) Programmiergeräte

Mit einem ISP Programmer überträgt man das Programm vom Computer in den Mikrocontroller. Ich empfehle den Diamex USB ISP Stick:

Foto von einem handelsüblichen ISP Programmer mit USB Anschluß

Für diesen Workshop eignen sich prinzipiell auch andere ISP Programmieradapter, sofern sie eine Stromversorgung mit 3,3V oder 5V bereit stellen und einen 6 Poligen ISP Stecker haben. Falls Ihr Programmieradapter ohne Software geliefert wurde, lesen Sie die Vorschläge auf der AVR Tools Seite.

Wir werden den Mikrocontroller mit Hilfe eines kleinen Adapters an den Programmer stecken:

Schaltplan für eine Adapterplatine zur Programmierung eines AVR außerhalb der Schaltung

4) Senso Spiel

Wir werden ein elektronisches Spiel nachbauen, daß in den 80er Jahren von MBO mit dem Namen "Senso" vertrieben wurde. Es ist auch unter dem Namen "Simon" bekannt. Das Spiel könnte so aussehen:

Foto vom Senso Nachbau, große Version Foto vom Innenleben des Senso Nachbaus, große Version

Oder so: Foto vom Senso Nachbau, kleine Version

Die vier Tasten sind beleuchtet und das Teil kann Musik von sich geben. Jeder Taste ist ein bestimmter Ton zugeordnet, wie bei einem Mini-Klavier. Ein Zufallsgenerator erzeugt eine kurze Melodie, die der Spieler nachspielen muss. Bei Erfolg, wird die Melodie um einen Ton verlängert, der Spieler muss sie erneut nachspielen. Je besser der Spieler ist, um so länger werden also seine Melodien.

4.1) Schaltplan

Das Gerät besteht aus verblüffend wenig Bauteilen, deswegen ist es zum Erlernen der AVR Grundlagen sicher gut geeignet.

Schaltplan des Senso Nachbaus

Planen und Löten sie nun eine Platine gemäß diesem Schaltplan. Lassen Sie sich dabei von jemandem helfen, der damit Erfahrung hat.

4.2) Funktionsweise

Wenn man eine der vier Tasten drückt, leuchtet die entsprechende LED und der Mikrocontroller empfängt ein "Low" Signal. Umgekehrt kann auch der Mikrocontroller die Led's einschalten. Da normalerweise immer nur eine LED von den vieren leuchten soll, können sie sich alle einen einzigen Vorwiderstand teilen. Hier wird sehr schön demonstriert, daß die I/O Anschlüsse des Mikrocontroller wechselweise sowohl als Eingang als auch als Ausgang verwendbar sind. Das Programm kann die Signalrichtung einfach umschalten.

Wenn man eine Taste loslässt, sollte der Mikrocontroller eigentlich ein eindeutiges "High" Signal empfangen, doch das ist zunächst nicht der Fall, weil an den LED's zuviel Spannumg abfällt. Die Lösung besteht in den per Software zuschaltbaren Pull-Up Widerständen, welche sich quasi im Chip befinden:

Detailzeichnung vom internen Pull-Up Widerstadn im AVR Controller

Diese Pull-Up Widerstände haben einen Wert von etwa 50k Ohm und sorgen dafür, daß bei losgelassenem Taster ein eindeutiges "High" Signal erkannt wird.

Der Piezo-Schallwandler wirkt elektrisch wie ein Kondensator mit etwa 12nF Kapazität. Bei Gleichspannung fließt kein Strom, je höher die Frequenz ist, um so mehr Strom fließt und um so lauter wird er. Im Bereich 400-2000Hz ergibt sich eine angenehme Lautstärke.

Der /Reset PIN wird nicht benutzt, weil der Mikrocontroller intern schon ein Reset-Signal erzeugt. Selbst der Takt wird vom Chip intern erzeugt, so daß der sonst übliche Quarz entfällt.

Das Gerät benötigt keinen Ein/Aus Schalter, weil der Mikrocontroller im Power-Down Modus fast keinen Strom verbraucht. Bei der Programmierung werden wir den Power-Down Modus so oft wie möglich verwenden und außerdem die Taktfrequenz soweit wie möglich herabsetzen.

4.3) Programmierung in kleinen Schritten

Das Programm setzt sich aus vielen kleinen Bausteinen zusammen, die alle einzeln ausprobiert werden. Dabei wird der Simulator im AVR Studio sehr hilfreich sein. Zum Schluß wird aus diesen Teilen das Spiel zusammengesetzt.

Wir werden nicht alle Funktionen des Tiny13 nutzen (z.B. den ADC Wandler). Nach dem Reset sind alle Register mit sinnvollen Standardwerten initialisiert. Mit uninteressanten Funktionen brauchen Sie sich daher auch nicht zu beschäftigen. Tun Sie einfach so, als würden diese Funktionen nicht existieren.

Starten Sie also das AVR Studio und beginnen Sie ein neues Projekt mit dem Namen Senso. Als Programmiersprache wählen Sie bitte den Atmel AVR Assembler. Als Debug Plattform wählen Sie den AVR Simulator und stellen das richtige Device (Tiny13) ein. Im Menü Tools/Optons/Editor ändern Sie die Tabulator-Breite auf 8.

4.3.1) Eine Led einschalten

Geben Sie dieses Programm ein.

#include "tn13def.inc" lädt Chip-Spezifische Einstellungen in den Assembler. Dieser Befehl erzeugt keinen Programmcode.
sbi ddrb,1 schaltet den Port B1 als Ausgang um, standardmäßig sind alle Pins Eingänge. Da das Port-Register PORTB standardmäßig auf 0 steht (also alle Bits auf Low) geht dadurch die Led an.
ende: rjmp ende ist eine Endlosschleife und bildet somit das Programmende. Ohne diesen Befehl würde der Mikrocontroller den unprogrammierten Rest des Programmspeichers abarbeiten. Ungenutzter Programmspeicher enthält je nach Programmiergerät Zufallswerte oder lauter 0xFF, so daß völlig unbestimmt ist, was passieren würde.

Drücken Sie Strg-F7, um den Simulator zu starten. Es erscheint ein gelber Pfeil vor dem ersten Befehl:

Bildschirmfoto von der Assembler Applikation im Simulator in AVR Studio

Drücken Sie F11, um das Programm Schrittweise auszuführen. Im Fenster links oben können Sie die Auswirkungen direkt nachvolziehen. Der Befehl sbi ddrb,1 setzt im Register ddrb das Bit 1 auf High, was als schwarzes Kästchen angezeigt wird.

Bewegen Sie den Cursor auf den sbi Befehl und drücken Sie F1. Es erscheint eine Beschreibung dieses Befehls. Schauen Sie bitte ins Datenblatt auf Seite 158, dort finden Sie die Übersicht der I/O Register. Wozu das Register ddrb gut sein soll, geht aus dieser Seite allerdings nicht hervor. Diese Beschreibung der einzelnen Register befinden sich in den vorherigen Seiten des Datenblattes, in diesem Fall ab Seite 49. Lesen Sie dieses Kapitel durch, von besonderem Interesse ist momentan der Absatz "Configuring the Pin" auf Seite 50 und die Seite 51.

Wenn Sie jetzt noch ein paar mal F11 drücken, sehen Sie, daß der letzte Befehl unendlich oft wiederholt wird.

Sie sollten bei allen weiteren Schritten ebenso das Datenblatt und die Hilfe zu Rate ziehen, um die verwendeten Befehle und Register kennen zu lernen.

4.3.2) Mikrocontroller flashen

Schließen Sie den AVR Chip an den ISP-Programmieradapter an. Starten Sie das Programm, das zu ihrem Programmieradapter gehört und stellen Sie den Mikrocontroller Typ ein.

Klicken Sie auf den Erase Knopf um den Chip zu löschen. Öffnen Sie dann die *.hex Datei, die Sie mit dem AVR Studio erstellt haben. Durch den Program (oder write) Knopf übertragen Sie das Programm in den Chip. Mit dem Verify Knopf können Sie den Erfolg überprüfen.

Sie können den Chip jetzt aus dem Adapter heraus nehmen und in das Spiel stecken. Dann die Batterie einsetzen und: Led1 leuchtet. Wahnsinn :-)

Sorgen Sie dafür, daß der Chip Spannungsfrei ist, wenn Sie ihn aus einem Sockel ziehen oder einstecken. Falls Sie dafür zu faul sind, verwenden Sie dazu wenigstens ein isolierendes Werkzeug, damit Sie keinen Kurzschluß herbeiführen.

Über Fuse-Bits:

Jeder AVR Chip hat ein paar Konfigurations-Schalter, die Fuse-Bits genannt werden. In unserem Fall passt die Standard-Einstellung, darum lassen Sie am Besten die Finger davon. Durch ungeschickte Programmierung der Fuse-Bits kann man die ISP Schnittstelle ungewollt und unreparabel deaktivieren. Folgende Einstellungen sollten Sie vermeiden:

4.3.3) Eine Taste abfragen

Folgendes Programm soll geschrieben werden:

Zunächst sollen alle Led's aus sein,
die Pull-up Widerstände sollen an allen vier Tastern aktiviert werden.
Das Programm soll warten, bis irgendeine Taste gedrückt wird.
Dann soll es die Led1 einschalten und sich beenden.

Geben Sie dieses Programm ein. Lesen Sie die Kommentare und vergleichen Sie die Befehle mit der Hilfe und den Datenblatt, um sie zu verstehen.

Drücken Sie Strg-F7 und dann 10 mal F11. Sie sollten dann ungefähr folgendes

Bildschirmfoto von der Assembler Applikation im Simulator in AVR Studio

Im linken I/O-View Fenster können Sie die Auswirkungen des Programmes nach dem ersten Durchlauf sehen. Am Register ddrb erkennen Sie, daß Port B1 als Ausgang umgeschaltet wurde und das Port B1 Low ist. Das Programm hat offensichtlich nicht gewartet. Warum denkt der Simulator, daß eine Taste gedrückt worden sei? Sie haben doch gar keinen entsprechenden Befehl gegeben.

Achten Sie auf die Anzeige von Pinb. Dort erscheinen alle Bits als Low. Low ist das Signal, welches bei gedrückter Taste an den Mikrocontroller gesendet wird. Nun machen Sie den Gegentest:

Drücken Sie Shift-F5, um das Programm neu zu starten. Wie gewohnt hält der Simulator wieder vor dem ersten Befehl an. Er gibt Ihnen dadurch die Möglichkeit, die Eingangssignale der Taster einzustellen. Schalten Sie die vier Bits 1-4 im Register Pinb auf High, was losgelassenen Tastern entspricht. Sie brauchen dazu einfach nur mit der Maus drauf klicken.

Drücken Sie danach Alt-F5. Das Programm läuft nun automatisch weiter, der gelbe Pfeil zeigt, welcher Befehl gerade ausgeführt wird. Sie sehen, daß ein Teil des Programms in einer Endlosschleife wiederholt wird. Dieses mal wartet das Programm darauf, daß eine Taste gedrückt wird.

Simulieren Sie einen Tastendruck, indem Sie irgendein Bit in Pinb wieder aus klicken. Das Programm erkennt dies als Tastendruck und schaltet daraufhin wie gewünscht die Led1 an. Dann endet es.

Übertragen Sie dieses Programm jetzt in den Mikrocontroller und probieren Sie es innerhalb der Schaltung aus.

Dies ist eine gute Gelegenheit, die Stromaufnahme der Schaltung zu messen. Bei 3V und ohne gedrückten Taster verbraucht er etwa 0,7mA. Das ist schön wenig, aber es geht noch viel besser.

4.3.4) Taktfrequenz herabsetzen

Das obige Programm soll so verändert werden, daß es weniger Strom verbraucht.

Geben Sie dieses Programm ein. Es hat nur vier zusätzliche Zeilen ganz am Anfang. Lesen Sie die Kommentare und vergleichen Sie die Befehle mit der Hilfe und dem Datenblatt, um sie zu verstehen. Von besonderem Interesse sind die Seiten 26 und 28.

Hier wird der Clock-Prescaler genutzt, um die Taktfrequenz herab zu setzen. Standardmäßig ist der Teilerfaktor 8 durch die Fuse-Bits eingestellt, also 1,2Mhz, denn der interne RC-Oszillator schwingt mit ungefähr 9,6Mhz. Das Programm ändert diesen Teilerfaktor auf 256. Dadurch wird die effektive Taktfrequenz auf 37,5kHz reduziert.

Die geringere Taktfrequenz bewirkt eine geringere Stromaufnahme, wir sind jetzt bei etwa 0,15mA (bei 3V). Das hat sich gelohnt!

4.3.5) Einschlafen

Das obige Programm soll so verändert werden, daß es noch weniger Strom verbraucht.

Geben Sie dieses Programm ein. Dieses mal habe ich das Programmende verbessert. Nachdem die Led eingeschaltet wurde, durchläuft das Programm eine kurze Warteschleife und schaltet sie dann wieder aus. Dann schläft der Mikrocontroller ein. Vergleichen Sie die Befehle des letzten Abschnittes mit dem Datenblatt Seite 30 und 33.

Wenn der Mikrocontroller einschläft, schaltet er sämtliche Taktsignale aus, was logischerweise die Stromaufnahme noch weiter reduziert. Er kann aus diesem Zustand nur durch ein Interrupt-Signal wieder aufgeweckt werden. Da dieses Programm aber keine Interrupt-Signale aktiviert, wird der Mikrocontroller nie wieder aufwachen. In diesem Fall ist das so beabsichtigt. Sie müssen die Batterie eine Weile lang heraus nehmen und wieder einsetzen, um das Programm neu zu starten.

Probieren Sie das Programm in der Schaltung aus. Wenn Sie eine Taste kurz antippen, geht die Led1 für eta 5 Sekunden an und dann wieder aus. Danach beträgt die Stromaufnahme unter 0,001mA, also Ziel ereicht.

Eine durchschnittliche Knopfzelle würde so rein Rechnerisch über 100 Jahre lang ausreichen. Natürlich ist keine Batterie so lange lagerbar. Dieses flache Rechenexempel zeigt jedoch, daß unser Senso Spiel tatsächlich keinen Ein-/Aus-Schalter benötigt.

Schauen Sie sich im Programmcode bitte den Absatz an, wo die Led aus geschaltet wird. Hier wird der Port B1 wieder als Eingang konfiguriert. Warum schalte ich den Ausgang nicht einfach auf High?

Stellen Sie sich vor, Sie würden den Taster1 gedrückt halten, während der Ausgang auf High geschaltet wird. Dann hätten Sie einen Kurzschluß durch den Taster. Dieses Beispiel zeigt, daß Sie den Chip unter ungünstigen Bedingungen tatsächlich kaputt programmieren können.

Gemäß Datenblatt Seite 51 können die Port Pins folgende Zustände haben:

  1. Eingang ohne Pull-up
  2. Eingang mit Pull-up
  3. Ausgang Low
  4. Ausgang High

Den Zustand 1) können wir gemäß Kapitel 6.2 nicht gebrauchen. Der Zustand 4) darf nicht benutzt werden, weil dabei ein Kurzschlußstrom durch die Taster fließen kann.

Der Befehl sbi portb,1 ist übrigens nicht unbedingt nötig, denn nach dieser Zeile werden die Eingänge nicht mehr abgefragt.

4.3.6) Einschlafen und wieder aufwachen

Beim Studieren des Datenblattes haben Sie sicher auch etwas über den Idle-Modus gelesen. In diesem Modus wird der Prozessorkern angehalten, während der Timer und die I/O Funktionen aktiv bleiben. Die Nutzung des Idle-Modus bringt uns allerdings keine Vorteile, denn wir haben die Taktfrequenz bereits sehr weit herabgesetzt. Der Unterschied zwischen 37,5kHz Taktfrequenz und Idle-Modus ist nur verschwindend gering.

Dennoch hat das Programm aus dem vorherigen Kapitel noch Verbesserungspotential. Die Wiederholschleife, in der auf einen Tastendruck gewartet wird, verschwendet regelrecht Energie.

Im vorherigen Kapitel haben Sie gelernt, daß der sleep Befehl den Mikrocontroller einschlafen läßt, bis er durch ein Interrupt-Signal aufgeweckt wird. Das haben wir noch nicht ausgenutzt. Schauen Sie ins Datenblatt auf Seite 47 und 48. Dort wird unter dem Namen "Pin Change Interrupt" erklärt, daß Pegeländerungen an jedem beliebigen Pin einen Interrupt auslösen können, man muß diese Funktion einfach nur für die gewünschten Pins (also die Tasten) aktivieren.

Genau das macht dieses Programm. Geben Sie das Programm in den Simulator ein und testen Sie es, indem Sie Strg-F7 drücken. Klicken Sie die vier Bits 1-4 im Register Pinb wieder auf High, um losgelassene Tasten zu simulieren. Drücken Sie dann Alt-F5, um das Programm automatisch laufen zu lassen. Ihr Programm wird an der Zeile hinter dem sleep Befehl stehen bleiben, bis eine Taste gedrückt wird.

Bildschirmfoto von der Assembler Applikation im Simulator in AVR Studio

Die Assembler Direktive .org 0x000 teilt dem Assembler mit, daß die dahinter stehenden Befehle ab Adresse 0x000 im Programmspeicher stehen sollen. Das ist übrigens auch die Standard-Vorgabe, wenn Sie keine .org 0x000 Direktive angeben.

Wenn der Mikrocontroller Resetted wird (also beim Einsetzen der Batterien), beginnt der Prozessor an Adresse 0x000. In diesem Fall steht dort ein Sprungbefehl rjmp start an den Beginn des Programmes.

Die Adresse 0x002 ist für Pin-Change Interrupts vorgesehen. Immer, wenn ein Signalwechsel an einem entsprechend aktiviertem Pin erkannt wird, unterbricht der Mikrocontroller das laufende Programm, um eine besondere Interruptroutine an eben dieser Adresse auszuführen. Diese Interrupt-Routine brauchen wir nicht, und darum steht an Adresse 0x002 nur der reti Befehl.

Alle Interrupt Routinen müssen mit dem Befehl reti enden. Leere Interrupt Routinen bestehen einfach nur aus diesem einen Befehl.

Die Interrupt Vektoren (0x000, 0x002 und weitere) sind im Datenblatt auf Seite 45 aufgelistet.

Etwas weiter unten im Programm steht der Befehl sbi acsr,acd. Er schaltet den Analog-Comparator aus, siehe dazu im Datenblatt ab Seite 80. Der Analog Comparator ist die einzige Funktion, die standardmäßig eingeschaltet ist. Da wir sie nicht brauchen, schaten wir sie ab, so sparen wir noch ein klein wenig Strom.

Direkt darunter kommt ein Befehlsblock, der den Pin-Change Interrupt für alle vier Tasten aktiviert. Daß Interrupts das laufende Programm unterbrechen, interessiert uns dabei gar nicht so sehr. Wir wollen nur den Power-Down Schlaf unterbrechen.

Das Programm wiederholt sich immer wieder, wobei es bei jedem Durchlauf solange einschläft, bis man eine Taste drückt. Das Programm ist nun so weit entwickelt, daß man die Batterie in der Fassung lassen kann. Überzeugen Sie sich davon, daß dies stimmt, indem Sie die Stromaufnahme nachmessen.

4.3.7) Prozeduren

Das Programm soll in Prozeduren zerlegt werden, um den Quellcode übersichtlicher zu machen. Geben Sie dieses Programm in den Simulator ein.

Die Prozeduren werden durch den rcall Befehl aufgerufen. Der Befehl ret springt zurück ins Hauptprogramm.

Die 5s Pause wurde durch eine 1s Pause ersetzt. In dieser Prozedur wird die Anzahl der nötigen Schleifendurchläufe durch den Ausdruck (1*37500/3) berechnet und durch high() und low() in zwei 8-Bit Werte zerlegt. Schließlich haben wir einen 8-Bit Mikrocontroller vor uns.

In dieser Formel wird die Taktfrequenz durch 3 geteilt, weil die innere Schleife (r17) genau 3 Taktzyklen lang dauert. Der Befehl dec r17 braucht einen Taktzyklus und der Befehl brne p1 braucht 2 Taktzyklen. Die Taktzyklen der anderen Befehle in dieser Prozedur habe ich vernachlässigt, denn hunderprozentig genau muss die Dauer der Pause nicht sein.

Die Prozedur takt_38khz müsste eigendlich takt_37.5khz heissen, aber der Assembler erlaubt weder Punkt noch Komma in den Labels.

Wenn die Led mehrmals blinken soll, brauchen Sie nur den Befehl rcall led_blinken mehrmals hintereinander zu schreiben. Spätestens dann dürfte ein weiterer Vorteil von Prozeduren offensichtlich werden. Sie verwenden die Prozedur wo sie wollen und so oft sie wollen, ohne den vielfachen Speicherplatz zu benötigen.

4.3.8) Töne wiedergeben

Das Programm soll so geändert werden, daß es einen Piepton von sich gibt, anstatt die Led blinken zu lassen. Geben Sie dieses Programm in den Simulator ein.

Die erste Änderung wurde im Hauptprogramm vorgenommen. Die Prozedur zum Led-Blinken wurde durch eine Prozedur zum Piepen ersetzt. In der Init-Prozedur ist der Befehl sbi ddrb,0 hinzugefügt worden, damit der Port B0 als Ausgang umgeschaltet wird, schließlich soll der Lautsprecher ja angesteuert werden.

Die 1s Pause wurde durch eine 500ms Pause ausgetauscht - nur so zum Spaß.

Der Ton wird mit dem Timer/Counter erzeugt. Vergleiche dazu das Datenblatt ab Seite 59. Dieses Kapitel im Datenblatt ist sicher das komplizierteste, weil der Timer/Counter so viele einstellbare Parameter hat. Es wird der CTC Modus verwendet, dabei Zählt der Counter die Taktzyklen wiederholt bis zu einem festgelegten Maximalwert. Jedes mal, wenn der Maximalwert erreicht wird, wechselt der Ausgang OC0A (das ist Port B0, der Lautsprecher) seinen Pegel.

Wenn der Timer also z.B. 3200 mal pro Sekunde seinen Maximalwert erreicht, schwingt der Lautsprecher mit 1600 Hz. Ist der Timer erstmal gestartet, Piept der Lautsprecher solange, bis der Timer wieder angehalten wird.

Bei dem 37,5kHz Systemtakt können Sie 255 unterschiedliche Töne zwischen 73 Hz und 18kHz wiedergeben. Für gut klingende Musik ist das viel zu wenig, für das Senso Spiel reicht das aber. Schließlich brauchen wir nur 4 Töne die eine harmonische Folge ergeben.

Wenn Sie Interesse haben, können Sie sich ja überlegen, wie sie feiner abgestufte Töne wiedergeben können. Tip: Ich würde dazu eine erheblich höhere Taktfrequenz verwenden und den Counter durch eine Interruptroutine per Software zu einem 16Bit Counter erweitern.

4.3.9) Watchdog

Geben Sie dieses Programm in den Simulator ein und erzeugen Sie die Hex-Datei durch Druck auf F7. Übertragen Sie das Programm in den Mikrocontroller und probieren Sie es aus.

Drücken Sie die Taste 1, dann Taste 2. Legen Sie das Spiel dann weg. Wenn jemand anders nun damit spielen möchte, muß er genau da weiter spielen, wo Sie aufgehört haben, nämlich bei Taste 3. Das ist blöd. Das Spiel sollte sich nach einer Gewissen Zeit automatisch zurück setzen, um diese Situation zu verhindern

Dazu verwenden wir den Watchdog. Eigentlich wurden Watchdogs erfunden, um abgestürzte Computer zurück zu setzen. In unserem Fall kann er das gerne tun, doch die Hautpaufgabe wird darin bestehen, liegen gelassene Spiele zurück zu setzen.

Geben Sie dieses Programm in den Simulator ein und erzeugen Sie die Hex-Datei durch Druck auf F7. Übertragen Sie das Programm in den Mikrocontroller und probieren Sie es aus. Drücken Sie die Taste 1, dann Taste 2 und dann warten Sie 6 Sekunden. Innerhalb dieser Zeit schlägt der Watchdog zu und setzt das Spiel zurück. Sie können nun also wieder mit Taste 1 beginnen.

Ganz am Anfang des Programmes habe ich eine Prozedur für den Pin-Change Interrupt geschrieben. Sie setzt den Watchdog zurück. Jedesmal, wenn eine Taste gedrückt oder auch losgelassen wird, setzt der wdr Befehl den Watchdog Timer zurück. Seine 4 Sekunden Auszeit beginnt dann wieder von neuem. Sobald Sie länger als 4 Sekunden keine Taste drücken, wird das Spiel zurück gesetzt.

Der Anfang des Hauptprogramm wurde etwas verändert. Zuerst wird der Mikrocontroller initialisiert, dann wird der Takt herabgesetzt. Danach wird der Watchdog aus geschaltet (falls er an war) und geschlafen. Die Arbeit beginnt mit einer Runde Schlafen :-). Da der Watchdog aus ist, kann dieser Schlaf beliebig lange dauern, das ist also der Ruhezustand des Spiels.

Im Ruhezustand darf der Watchdog nicht ständig eingeschaltet bleiben, denn er würde die Stromaufnahme unnötig erhöhen. Bei Batteriebetrieb ohne Ein-/Aus-Schalter sind solche "Kleinigkeiten" sehr wichtig.

Wenn Sie irgendeine Taste drücken, wacht der Mikrocontroller wieder auf. Nun beginnt das eigendliche Hauptprogramm. Als erstes schaltet es den Watchdog ein, denn ab jetzt soll das Spiel bei Nicht-Benutzung in den Ruhezustand zurück gesetzt werden. Dann wartet das Spiel wie gehabt darauf, daß die vier Tasten nacheinander gedrückt werden.

Wie man den Watchdog ein und aus schaltet, steht im Datenblatt ab Seite 36. Das Aus-Schalten erfordert absichtlich eine komplizierte Folge von Befehlen, wie das Datenblatt erklärt.

Anmerkung: Aufrund der zahlreichen Warteschleifen und Timer lassen sich die Programme dieses Kapitels nur noch sehr bedingt im Simulator testen.

4.3.10) Zufallszahlen-Generator

Für das Senso Spiel brauchen Sie einen Zufallszahlen-Generator. Er erzeugt die Melodien, die der Spieler nachspielen soll. Jedesmal, wenn der Spieler die Melodie richtig nachgespielt hat, soll sie durch einen neuen Zufallston verlängert werden. Sie könnten dazu die bisherige Melodie ins RAM abspeichern. Einfacher geht es mit einem Pseudo-Zufallszahlen-Generator.

Ein Pseudo-Zufallszahlen-Generator benötigt einen Startwert. Von diesem Wert ausgehend, erzeugt er bei wiederholtem Aufruf eine Folge von Zufallszahlen. Wann Immer Sie mit dem gleichen Startwert beginnen, kommt die gleiche Zahlenfolge hinten heraus. Eine solche Zahlenfolge könnte z.B. so aussehen:

5
5 2
5 2 34
5 2 34 12
5 2 34 12 1
und so weiter.

Sie brauchen die Melodie nirgends abzuspeichern, sondern können einfach bei jedem Durchlauf die gleiche Zahlenfolge immer wieder erneut berechnen.

Jetzt brauchen Sie nur noch bei jedem neuen Spiel einen neuen Startwert, den können Sie erzeugen, indem Sie messen, wie lange der Spieler die erste Taste (zum Starten) drückt.

Geben Sie dieses Programm in den Simulator ein starten Sie es durch Durck auf Strg-F7. Gehen Sie mit dem Cursor in die Zeile nochmal: rcall random und drücken Sie F9, um einen Haltepunkt zu setzen. Drücken Sei dann Alt-F5.

Während das Programm darauf wartet, daß Sie die (simulierte) Taste 1 loslassen, stellen Sie die Ansicht im linken Fenster so ein, daß Sie das Register 19 und den Port B sehen können:

Bildschirmfoto von der Assembler Applikation im Simulator in AVR Studio

Die Zahl im Register r19 ändert sich laufend, das wird unser Startwert für den Zufallsgenerator. Simulieren Sie nun das Loslassen der Taste 1, indem Sie das Bit 1 in Pinb anklicken (so daß es Schwarz wird). Der Simulator erreicht den Haltepunkt, während in Register r19 und r20 irgend ein Zufälliger Startwert steht.

Drücken Sie nun F5, um die nächste Zufallszahl zu berechnen. Drücken Sie nochmal ein paar mal F5 und beobachten Sie, wie bei jeder Wiederholung eine neue Zufallszahl in r20 erzeugt wird.

Den Algorithmus der Prozedur random: habe ich übrigens aus einem Schaltplan abgeleitet, den ich im Internet gefunden habe. Dort wurde der Zufallszahlen-Generator aus einem Schieberegister und drei Exklusiv-Oder Gattern gebildet.

Schaltplan eines Zufallszahlen-Generators aus Logikgattern

4.4) Das fertige Programm

In den vorherigen Kapiteln haben Sie gelernt, den AVR Mikrocontroller von Typ Tiny13 zu programmieren. Sie haben alle Komponenten kennen gelernt, die für das Senso Spiel benötigt werden.

Folgende Komponenten brauchen Sie für das Senso Spiel nicht:

Der vollständige Quelltext des Spiels wurde aus den bisher besprochenen Bausteinen zusammen gesetzt.

Nach dem Anlegen der Stromversorgung wird die Hardware initialisisert. Er ertönt ein tiefer Ton und dann schaltet sich das Gerät ab.

Wenn Sie nun irgend eine Taste drücken, schaltet sich das Spiel ein. Es gibt eine kurze Melodie aus 2 Tönen vor, die Sie nachspielen müssen.

Wenn Sie richtig gespielt haben, ertönt ein Bestätigungston. Danach wird die Melodie um einen Ton verlängert vorgespielt.

Wenn Sie gepatzt haben beginnt das Programm wieder ganz von oben, also beim Reset. Das Spiel ist damit beendet.

Wenn Sie 4 Sekunden lang keine Taste drücken, beißt der Wachhund zu (Watchdog) und setzt den Mikrocontroller ebenfalls zurück, wodurch das Spiel beendet wird.

Das wars's. Viel Spaß beim Spielen!

5) Material

Bauteile pro Schüler, je 10 Euro:

Anzahl4,5V3V
1Atmel Tiny13Atmel Tiny13V
1IC Sockel 8-Pin
1Piezo Schallwandler
4Eingabetaster in rot, gelb, grün und blau
4LED's in rot, gelb, grün und blaurote Low-Current LED's
1Widerstand 100 Ohm 1/4 WattWiderstand 330 Ohm 1/4 Watt
1Kondensator 100nF
1Batterien 3xAAALithium Knopfzelle CR2032
1Batteriehalter dazu
1Stück Punktrasterplatine

Sowie pro Arbeitsgruppe einen ISP Programmer mit selbstgelöteter Adapterplatine, je 30 Euro:

AnzahlBauteil
1ISP Programmer, z.B. Diamex USB ISP
1IC Sockel 8 Pins
1Stiftleiste 6 Pins
1Kondensator 100nF
1Stück Punktrasterplatine

Werkzeug pro Arbeitsgruppe: