Mikrocontroller-Einstieg mit myAVR Teil 3/7
Aus ELVjournal
04/2006
0 Kommentare
Keine
Angst vor dem Einstieg in die Welt der Mikrocontroller-Programmierung!
Die myAVR-Sets enthalten alles Nötige für den schnellen und fundierten
Beginn der Programmierer-Karriere – Experimentier-Board mit ATMELCont
roller, Lehrbuch, Softwarepaket, Kabel, sämtliches Zubehör. Im dritten
Teil unserer Serie zum Einstieg in die AVR-Programmierung fahren wir mit
der I/O-Programmierung anhand eines weiteren Beispiels fort und
befassen uns mit dem Thema Interrupt-Steuerung.Rein wie raus – die I/O-Ports
Nachdem
wir uns in der letzten Ausgabe sehr ausführlich der Funktion der
I/O-Ports des AVR-Controllers gewidmet hatten, ist uns die Aussage noch
gegenwärtig, dass es über das Steuerregister DDRx möglich ist,
festzulegen, welcher Pin als Eingang oder als Ausgang wirken soll. Über
das Register PORTx erfolgt entsprechend die Ausgabe, über PINx die
Eingabe von Signalen über die entsprechenden I/O-Lines. Was man zunächst
wissen muss, ist der Fakt, dass der Controller nach dem Einschalten
oder einem Reset immer den Inhalt der Register DDRB/C/D komplett auf
null setzt (0b00000000) – die „anhängenden“ I/OLines sind damit zunächst
stets als Eingang gesetzt. Erst das Laden des entsprechenden
Steuerregisters mit „1“, wie in unserem ersten Programmbeispiel, führt
zu einer Konfiguration als Ausgabe-Linie.![Bild 26: Die Pegelverhältnisse am Controller-Eingang mit aktiviertem Pull-up-Widerstand Bild 26: Die Pegelverhältnisse am Controller-Eingang mit aktiviertem Pull-up-Widerstand](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_006.jpg)
|
Bild 26: Die Pegelverhältnisse am Controller-Eingang mit aktiviertem Pull-up-Widerstand |
Wir
wollen aber nun den Fall der Konfi- guration als Eingabe-Linie
betrachten. Das fängt damit an, dass ein digitaler Signal- Eingang, noch
dazu so ein empfindlicher wie der CMOS-Eingang des AVR-Controllers,
stets definiert auf +UB (Pull-up) oder Masse (Pull-down) zu setzen ist.
Warum? Ein digitaler Eingang wirkt „frei in der Luft hängend“ wie eine
Empfangsantenne für alle möglichen elektromagnetischen Felder und
liefert dem nachfolgenden Steuerregister undefinierbare Signale statt
ordentlicher High- und Low-Signale, wie es in der Digitaltechnik üblich
ist. Schließt man hingegen den Eingang definiert mit einem
Pull-up-Widerstand ab, wie es in Abbildung 26 zu sehen ist, ist der
Eingang nie offen und kann so die erwähnten Felder nicht mehr ohne
weiteres „einfangen“. Ist der hier als „Signalquelle“ dienende Taster
offen, liegt der Eingang definiert auf +UB, liefert also die digitale
Information „1“. Ist der Taster hingegen geschlossen, liegt der Eingang
auf Masse und liefert die digitale Information „0“. Die Information, ob
der jeweilige interne Pull-up-Widerstand des Controllers aktiviert
werden soll oder nicht, muss also, zusammen mit der Pin- Auswahl des
IN-Pins, Bestandteil des Steuerprogramms werden, um eine I/OLine als
Eingang zu definieren. Dieser Programmschritt gehört also in das
Initialisierungsprogramm. Dazu ist (in unserem Beispielprogramm
beschäftigen wir uns wie im Ausgabeprogramm mit Port B) im
Port-B-Register eine logische „1“ an der entsprechenden Position zu
setzen.Das Ein-/Ausgabeprogramm
![Bild 27: Der Quellcode für unser I/O-Programm Bild 27: Der Quellcode für unser I/O-Programm](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_005.jpg)
|
Bild 27: Der Quellcode für unser I/O-Programm |
Setzen
wir die beiden eben besprochenen Schritte (wir wollen Port B 0 als
Eingang definieren und den Pull-up-Widerstand setzen) also in
Programmcode um. Da wir natürlich wissen wollen, ob das funktioniert,
verwenden wir einen der Taster auf dem myAVR-Board als Eingabeorgan und
verbinden das schon in Teil 2 erarbeitete Ausgabeprogramm mit dieser
Eingabeoperation, was nichts anderes heißt als: den an Port B 0
anzuschließenden Taster drücken, eine der LEDs mit Port B 1 verbinden
und diese mit dem Taster ein- und ausschalten. Damit werden gleich zwei
Pro - grammroutinen miteinander verbunden, einer Aktion folgt eine
Reaktion. Dazu gehen wir dieses Mal den umgekehrten Weg und sehen uns
zunächst das fertige Programm an, um den strukturierten Aufbau eines
Programms weiter zu vertiefen (Abbildung 27). Hier erscheint zunächst
die bereits bekannte und unverändert übernommene Reset- und
Interrupt-Tabelle, darauf der Initialisierungsteil. Hier sind gegenüber
der reinen Ausgabe-Initialisierung ein paar Zeilen hinzugekommen – die
Eingabe-Initialisierung. Zunächst ist hier ein neuer Befehl zu sehen:
„cbi“.Der
löscht an der definierten Stelle des Registers das nach dem Reset auf
„0“ gesetzte Bit und setzt das Steuerregister für Port B 0 auf
„Eingang“, also, wie erwähnt, auf „0“. Der folgende „sbi“-Befehl spricht
direkt das Bit 0 im I/O-Register an und aktiviert damit die
Pull-up-Funktion an diesem Pin. Nun ist nur noch festzulegen, dass Port B
1 als Ausgang arbeiten soll, ergo ist das Steuerregister für Port B 1
auf „1“ zu setzen. Damit ist die Initialisierung erledigt und wir können
uns dem Hauptprogramm zuwenden. Nach dem Zurücksetzen des Watchdogs
wird zuerst eines der allgemeinen Register, hier wieder das bereits
bekannte r16, mit einem Ausgabewert für den Fall geladen, dass die Taste
nicht gedrückt ist, denn auch dieser Fall muss definiert werden, um dem
Rechner eindeutige Anweisungen für jeden Betriebsfall zu geben. Das
Laden von 0b00000001 bedeutet hier: Pin B 0 = 1 aktiviert den Pull-up-
Widerstand, Pin B 1 = 0 heißt: LED ausgeschaltet. Der nächste
„in“-Befehl sorgt dafür, dass der Wert, der am Eingang B 0 über das
Eingaberegister Pin B (siehe auch Abbildung 13 im Teil 2) durch den
Taster definiert wird („0“ oder „1“), wiederum in einem allgemeinen
Register, hier r17, zur Auswertung zwischengespeichert wird. Dies ist
der an sich unauffällige Knackpunkt des Eingabeprogramms, der
Input-Befehl. Jetzt folgen die Festlegungen, was der Controller mit dem
eben in r17 abgelegten Wert anfangen soll. Hier kommt mit „sbrs“ ein so
genannter eleganter Sprungbefehl (engl. skip) zur Anwendung. „sbrs“
heißt „Skip if Bit in Register Set“, zu Deutsch, der Controller soll den
dem Skip-Befehl folgenden Programmschritt auslassen, falls im folgend
angegebenen Register (hier r17) das ebenfalls angegebene Bit (hier Bit
„0“ ) gesetzt ist. Vereinfacht gesagt: Steht hier der zunächst aus Port B
ausgelesene Wert von Bit 0 auf einer logischen „1“, heißt dies, der
Taster ist nicht gedrückt und die LED darf nicht angesteuert werden.
Damit springt das Programm sofort in die Out-Zeile. Hier verändert sich
nichts, da in Register r16 ja immer noch die Ausgabedaten für einen
offenen Taster definiert sind und die LED nicht angesteuert wird (Bit B 1
steht immer noch auf „0“). Über den „rjmp“-Befehl kehrt das Programm
wieder zurück zum Beginn des Hauptprogramms. ![Bild 28: Das Flussdiagramm für die Lösung unserer I/O-Aufgabe Bild 28: Das Flussdiagramm für die Lösung unserer I/O-Aufgabe](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_009.jpg)
|
Bild 28: Das Flussdiagramm für die Lösung unserer I/O-Aufgabe |
Dieser
beschriebene Ablauf setzt sich so lange fort, bis der Taster gedrückt
wird. Was passiert jetzt? Bei der Abarbeitung des Skip-Befehls erkennt
das Programm, dass nun im Register r17 für Port B für Bit 0 eine
logische „0“ abgelegt ist, der Programmsprung wird also nicht ausgeführt
und es geht weiter zum nächsten Register- Ladebefehl. Nun wird Register
r16 mit dem neuen Inhalt geladen: Pin B 0 = 1 behält seinen Status als
Eingang mit ak tiviertem Pull-up-Widerstand, während Pin B 1 = 1
bedeutet, dass beim Auslesen des Registers beim folgenden „out“-Befehl
die LED an Pin B 1 eingeschaltet wird. Auch diese Programmschleife wird
jetzt so lange durch - laufen, bis die Taste losgelassen wird, das
Programm dies feststellt und der Skip-Befehl wieder in Aktion tritt.
Abbildung 28 zeigt noch einmal das Flussdiagramm des Programms, das die
zu lösende Aufgabe übersichtlich dokumentiert.![Bild 29: Die Verdrahtung zur I/O-Aufgabe auf dem myAVR-Board Bild 29: Die Verdrahtung zur I/O-Aufgabe auf dem myAVR-Board](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_004.jpg)
|
Bild 29: Die Verdrahtung zur I/O-Aufgabe auf dem myAVR-Board |
Unsere
Beschreibung quasi „von hinten“ sollte zeigen, dass es relativ einfach
ist, einmal erarbeitete Algorithmen erneut anzuwenden und in neue
Programmlösungen einzubinden. Hat man erst einmal die wesentlichen
Befehle und ihre Auswirkungen im Hinterkopf, fällt es nicht mehr schwer,
zunächst das Flussdiagramm anhand der zu lösenden Aufgabe zu entwerfen.
Dass das seinen Sinn hat, merkt man spätestens dann, wenn man so weit
ist, mehrere Programmteile, so genannte Unterprogramme, miteinander zu
kombinieren, ohne sich im Quellcode zu „verlaufen“. Denn allein schon
unser kleines Beispiel zeigt, dass man keine Aktivität, die im Verlaufe
der Programmabarbeitung passieren kann, außer Acht lassen darf, um keine
ungewollten Reaktionen zu erhalten. Weiterführendes zur Systematik des
Programmentwurfs findet sich sehr ausführlich, nebst mehreren, auch
umfangreicheren Programmierbeispielen, im Lehrgangsmaterial und auf der
Programm-CD. Hier gibt es auch eine ausführliche und vor allem gut
verständliche Unterweisung zur Programmierung mit Unterprogrammen und
Sprunganweisungen, auf die wir im Rahmen unserer Serie ebenfalls nur
dann näher eingehen, wenn sich die Gelegenheit dazu in unseren
Beispielprogrammen ergibt. Unser Programm wird nun in die Praxis
umgesetzt – ein inzwischen bekannter Vorgang: Quellcode in den Editor
schreiben, kompilieren, linken, auf den AVR brennen. Verbindet man nun
nach Abbildung 29 einen Taster des myAVR-Boards mit dem Port-Pin B 0 und
eine LED mit dem Port- Pin B 1, so muss nach Anschluss der
Spannungsversorgung beim Drücken des Tasters die LED aufleuchten. Das
war zu einfach? Dann erweitern Sie doch zum Training das Programm um
einen zweiten Taster, der die nächste LED ansteuert. Da wird das
Programm schon etwas komplexer!Interrupt-Steuerung
Für
Programmier-Einsteiger hat das Wort „Interrupt-Steuerung“ einigen
Schrecken – die Profis sprechen da von Interrupt-Vektoren,
Interrupt-Service-Routinen, Interrupt- Quelle, -Maske usw. Der
myAVR-Lehrgang schafft es dennoch, dieses etwas sperrig erscheinende
Thema so zu vermitteln, dass man nach kurzer Zeit nicht nur mitreden,
sondern auch entsprechend programmieren kann. Das wollen wir hier
ausprobieren!Was ist Interrupt-Steuerung eigentlich?
![Bild 30: Der klassische Programmablauf beim Polling-Verfahren Bild 30: Der klassische Programmablauf beim Polling-Verfahren](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_007.jpg)
|
Bild 30: Der klassische Programmablauf beim Polling-Verfahren |
Bei
unserem letzten Programmierbeispiel haben wir ein typisches Beispiel
einer sequenziellen Abfrageroutine (Polling) kennen gelernt: Der Zustand
des Tasters wird ständig abgefragt, bis dieser den erwarteten Zustand
(gedrückt) einnimmt (Abbildung 30) und den Aktor (die LED) anspricht.
Gleichermaßen könnte so auch ein längeres Programm so lange unterbrochen
werden, bis das erwartete Ereignis eintritt. Solange kehrt das
Polling-Programm immer wieder zur Abfrage zurück. Im ungünstigen Fall
können aber dadurch weitere Verarbeitungsaufgaben des Controllers, etwa
eine Ausgabe auf einem Display, gestört werden bzw. ganz ausbleiben. Und
hat man das Abfrageprogramm als Unterprogramm eingebaut, kann es bei
zeitkritischen Abläufen durchaus geschehen, dass das Programm gerade
noch „woanders“ arbeitet, wenn z. B. ein kurzer Steuerimpuls eintrifft.
Der kann dann schlichtweg vom Programm „übersehen“ werden – mit
womöglich schlimmen Folgen. Also muss man hier einen anderen Weg gehen,
um effektiv zu programmieren – man lässt das Programm nicht dauernd ein
bestimmtes Ereignis abfragen, sondern steuert das Programm durch das
Eintreffen des Ereignisses selbst! Dabei kann das Programm an jeder
beliebigen Stelle (das muss man ausnahmsweise nicht vorher festlegen)
bei Eintreffen des Ereignisses unterbrochen und ein Unterprogramm für
die Verarbeitung des Ereignisses aufgerufen werden. Ist das erfolgt,
setzt das Hauptprogramm an der Stelle fort, an der es unterbrochen
wurde. Genau das bedeutet „Interrupt-Steuerung“! Die besteht aus immer
den gleichen Elementen:Interrupt-Quelle
Als
Interrupt-Quelle können äußere Sensoren (Ports), Schwellwerte des
A/DWandlers oder der integrierte Timer genauso auftreten wie spezielle
Software-Befehle. Der AVR-Controller auf unserem my- AVR-Board verfügt
über zahlreiche dieser Quellen. Tabelle 1 zeigt einen Auszug der
gängigsten Interrupt-Quellen dieses Controllers. Die Anzahl und Art der
Interrupt- Quellen ist bei jedem Controller eine andere und dessen
Aufgabenbereich angepasst.![Die Interrupt-Quellen des ATmega8 Die Interrupt-Quellen des ATmega8](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_002.jpg)
|
Die Interrupt-Quellen des ATmega8 |
Interrupt-Behandlungsroutine
![Bild 31: Der Grundaufbau der Interrupt-Service-Routine Bild 31: Der Grundaufbau der Interrupt-Service-Routine](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_008.jpg)
|
Bild 31: Der Grundaufbau der Interrupt-Service-Routine |
Das
ist eben jenes beschriebene Unterprogramm, das einer Interrupt-Quelle
zugeordnet ist und als Reaktion auf deren Unterbrechungsanforderung
gestartet wird, es wird auch Interrupt-Service-Routine (ISR) genannt.
Wie sie grundsätzlich aufgebaut ist, zeigt Abbildung 31. Die hier
aufgeführten Befehle werden wir später noch genauer erläutern. Man
erkennt auf jeden Fall bereits die Systematik: Tritt ein Interrupt auf,
wird die zugehörige Interrupt- Service-Routine (ISR) angesprungen.
Weitere Interrupts werden zunächst zum geregelten Abarbeiten dieser ISR
unterbunden, wenn nötig Speicherinhalte von Registern gerettet, die
eigentliche ISR ausgeführt, die Ordnung im Speicher wiederhergestellt,
das Steuerwerk für andere Interrupts wieder freigegeben, die ISR
insgesamt beendet, und das Programm kehrt zum Hauptprogramm zurück.Interrupt-Vektor
Den
kennen wir schon, er steht in der Reset- und Interrupt-Tabelle jedes
Quellprogramms. Hinter diesem Begriff verbirgt sich eine hier
festgeschriebene Adresse, auf der ein Befehl zum Aufruf oder die Adresse
der zugehörigen Interrupt-Behandlungsroutine gespeichert ist. Bei
Eintreffen eines bestimmten Ereignisses springt das Programm also immer
mit dem jeweils einzutragenden Befehl „rjmp“ (+ selbst festzulegendem
Unterprogramm-Namen) zu dem diesem Ereignis zugeordneten Unterprogramm.
Nicht zur Nutzung vorgesehene Interrupt- Behandlungsroutinen sind mit
dem Befehl „reti“ zu versehen. Der sorgt dafür, dass ein hier dennoch
aufgetretener Interrupt ordnungsgemäß beendet wird. Da die Länge der
Interrupt-Vektor-Tabelle von der Anzahl der jeweils verfügbaren
Interrupt-Quellen abhängt, hat sie bei jedem Controller der ATmega-Reihe
auch eine andere Länge. Die Vektoren sind in der Tabelle in einer
festen Reihenfolge platziert, die nicht verändert werden darf.
Gleichfalls darf man keine Vektoren aus der Tabelle löschen, die vor
einem benutzten Vektor liegen.Interrupt-Kontroll-Logik
Sie
ist fester Bestandteil des Prozessor- Steuerwerks und verantwortlich
für das Erlauben oder Verbieten sowie Konfigurieren von Unterbrechungen,
dem tatsächlichen Unterbrechen des laufenden Programms und für das
Auslösen der korrekten Interrupt-Behandlungsroutine.Wichtige Adressen
![Bild 32: In diesem Ausschnitt aus der Reset- und Interrupt-Vektor-Tabelle ist bereits der Sprungbefehl zur Interrupt-Service-Routine mit dem Namen „EXT_INT0“ eingetragen. Bild 32: In diesem Ausschnitt aus der Reset- und Interrupt-Vektor-Tabelle ist bereits der Sprungbefehl zur Interrupt-Service-Routine mit dem Namen „EXT_INT0“ eingetragen.](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic.jpg)
|
Bild
32: In diesem Ausschnitt aus der Reset- und Interrupt-Vektor-Tabelle
ist bereits der Sprungbefehl zur Interrupt-Service-Routine mit dem Namen
„EXT_INT0“ eingetragen. |
Dass
bei der Verwaltung der Interrupt- Quellen und -Vektoren Ordnung
herrschen muss, ist sicher jedem klar. Hier gibt es kein Variieren, ab
der Adresse 0x0001 erwartet der AVR-Controller im Programmspeicher immer
die Liste der Interrupt-Vektoren für die jeweiligen Interrupt-Quellen.
Die Adresse 0x0000 ist immer fest für die Reset-Interrupt-Routine
(ausgelöst durch ein Reset-Signal an Pin 1, Zuschalten der
Betriebsspannung oder Auslösen des Watchdogs) reserviert. Ein Beispiel
für eine aktivierte Interrupt- Behandlungsroutine für die
Interruptleitung INT0 (Pin 4, Port D 2) unseres AVRControllers zeigt
Abbildung 32. Hier ist auch noch einmal die eben beschriebene
Adressreservierung zu erkennen.Interrupt-Befehle und -Register
Für
das gesamte Handling der Interrupt- Quellen stehen Steuerregister und
einige spezielle Befehle zur Verfügung. Die beiden wichtigen Befehle
„sei“ und „cli“ dienen der Aktivierung und Deaktivierung der Interrupts:
sei – signalisiert dem Steuerwerk, dass Interrupts erlaubt sind. Er
setzt das Interrupt- Flag „I“ (Bit 7) im Status-Register SREG (siehe
Registerübersicht zu myAVR). cli – signalisiert dem Steuerwerk, dass
Interrupts verboten sind. Er löscht das Interrupt-Flag „I“ (Bit 7) im
Status-Register SREG (siehe Registerübersicht zu myAVR). Jetzt wird auch
ein Blick in die eben genannte Registerübersicht interessant. Hier
finden wir für jede Interrupt-Quelle mindestens ein spezifisches
Steuerregister (Interrupt-Register und z. B. Register MCUCR), das die
Konfiguration der Interrupt- Quelle (prinzipiell ähnlich wie bei den
I/O-Registern) erlaubt. Interrupts, die nicht abschaltbar sind, nennt
man „nicht maskierbar“. Solch ein Interrupt ist z. B. die
Interrupt-Quelle „RESET“ – logisch, würde man diese versehentlich
abschalten, gelänge kein definierter Reset des Controllers mehr!
Hingegen sind die (externen) Interrupts, die man per Programm ein- und
ausschalten kann, mit dem Begriff „maskierbar“ gekennzeichnet (bei
unserem ATmega8 sind dies z. B. die allgemeinen externen Interrupts INT0
und INT1). Dazu stehen entsprechende Steuerregister als „Maske“ zur
Verfügung, in denen man über die entsprechenden Bits die Interrupts ein-
(„1“) und ausschalten („0“) kann. Man teilt also dem Steuerwerk mit,
welches Ereignis als Interrupt akzeptiert werden soll. Für unsere eben
erwähnten INT0 und INT1 heißt das zuständige Register „GICR“. Je
nachdem, wie dessen Bits 6 bzw. 7 gesetzt werden, sind die Interrupts
erlaubt oder gesperrt.![Bild 33: Flussdiagramm zur Interrupt-Steuerung Bild 33: Flussdiagramm zur Interrupt-Steuerung](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_010.jpg)
|
Bild 33: Flussdiagramm zur Interrupt-Steuerung |
Schließlich
kann auch die Art der Interrupt-Auslösung festgelegt werden. Bei jedem
digitalen Signal gibt es die unterschiedlichen Zustände High-Pegel,
Low-Pegel, fallende und steigende Signalflanke, die die externen
Interrupts auslösen können. Diese Konfiguration erfolgt über die Bits 0
bis 3 des Registers MCUCR (siehe Registertabelle). Bei Setzen des Bits 0
erfolgt eine fortlaufende Interrupt- Auslösung, solange Low-Pegel
anliegt, bei Bit 1 löst jede Pegeländerung einen Interrupt aus, bei Bit 2
die fallende, bei Bit 3 die steigende Flanke. Nach so viel Theorie
wollen wir das Ganze zunächst wieder an einem ganz einfachen Beispiel
praktizieren – wir schließen einen Taster an den Interrupt-Port INT0
(Port D 2) an und nutzen diesen als Ereignis-Quelle. Wird der Taster
gedrückt, soll wieder die rote LED an Port B 0 aufleuchten. Die
Auswertung wollen wir über die fallende Signalflanke (der für eine
Auswertung interessante Moment also, wo der Taster tatsächlich gedrückt
wird und den Eingang auf „low“ schaltet) vornehmen. Dieses Mal machen
wir uns die zu planenden Programmschritte zuerst anhand des
Flussdiagramms klar (Abbildung 33):
- initialisieren
- Port D 2 als Eingang festlegen und Pullup aktivieren
- Port B 0 als Ausgang festlegen
- Maskierung für INT0 aktivieren, INT0 für fallende Flanke konfigurieren, Interrupt erlauben
- bei
Ereignis ISR starten, andere Interrupts sperren, Port B 0 auf 1 (LED
an) schalten, Interrupts freigeben, zurück zum Hauptprogramm
Im
Quellcode-Editor wird wieder das Grundgerüst geladen und vorbereitet,
dieses Mal aktivieren wir aber den Vektor für den INT0-Interrupt, hier
mit „EXT_0“.
![Bild 34: Die Verdrahtung zur Interrupt-Steuerung auf dem myAVR-Board Bild 34: Die Verdrahtung zur Interrupt-Steuerung auf dem myAVR-Board](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_003.jpg)
|
Bild 34: Die Verdrahtung zur Interrupt-Steuerung auf dem myAVR-Board |
Die
Initialisierung wird hier etwas länger: Nach der Konfiguration des
Eingangs und des Ausgangs mit „cbi“- und „sbi“- Befehlen wird zunächst
im Register r16 eingetragen, dass INT0 maskiert werden soll (Bit 6 auf
„1“, erlaubt den externen Interrupt über INT0). Die Ansprache dieses
Registers erfolgt wie bei einem I/O-Register per „out“-Befehl). Danach
erfolgt das Auslesen dieses Registerwertes in das Interrupt-Register
GICR). Die fallende Flanke als Auslöser wird jetzt ebenfalls ins
Register r16 eingetragen (Bit 1 = 1, Bit 0 = 0; dabei wird der vorherige
Wert gelöscht) und schließlich in das MCUCR-Kontroll-Register geladen.
Abschließend wird mit „sei“ die generelle Interrupt-Freigabe erteilt.
Die ISR finden wir ganz am Schluss unter „EXT_0“: Nach der Sperrung
anderer Interrupts wird über Port B 0 die LED eingeschaltet, danach
werden die Interrupts freigegeben, und der „reti“-Befehl führt wieder
zurück ins Hauptprogramm. Nun das Ganze übersetzen und auf den ATmega
auf dem myAVRBoard übertragen, die beiden beteiligten Ports entsprechend
verdrahten (Abbildung 34) und das Programm ausprobieren! Wenn die LED
nach dem Drücken des Tasters aufleuchtet, haben Sie soeben Ihr erstes
Programm mit Interrupt- Steuerung erfolgreich getestet! Vorteil: Sie
können das Ganze durch ein eigentliches Hauptprogramm ergänzen. Während
dieses läuft, löst die Betätigung des Tasters einen Interrupt aus, nach
dessen Abarbeitung (die LED leuchtet) das Hauptprogramm weiterläuft. In
unserem Beispiel wird ja nur die Interrupt-Routine abgearbeitet, und da
keine weitere Reaktion als die auf die fallende Flanke des
Eingangssignals definiert ist, bleibt die LED an, sooft man auch den
Taster drückt. Erst durch einen RESET (Buchse „RESET“ kurzschließen)
gelangt der Controller wieder in den Startzustand und die LED verlischt.
Dieser Interrupt-Service-Routine werden wir in der Folge noch öfter
begegnen, u. a. schon im nächsten Teil, wenn es um die Nutzung der
integrierten Timer geht – wir entlocken dabei dem AVR Töne!![Bild 35: Unser Beispielprogramm für die Nutzung von INT0 als Interrupt-Quelle Bild 35: Unser Beispielprogramm für die Nutzung von INT0 als Interrupt-Quelle](Mikrocontroller-Einstieg%20mit%20myAVR%20Teil%203_7%20_%20ELVjournal-Dateien/journal_pic_011.jpg)
|
Bild 35: Unser Beispielprogramm für die Nutzung von INT0 als Interrupt-Quelle |
Fachbeitrag online und als PDF-Download herunterladen
Inhalt
Sie erhalten den Artikel in 2 Versionen:
als Online-Version
als PDF (6 Seiten)
Sie erhalten folgende Artikel:
- Mikrocontroller-Einstieg mit myAVR Teil 3/7
weitere Fachbeiträge | Foren | |
Hinterlassen Sie einen Kommentar: