Pfad: Home ==> Mikrobeginner ==> 7. LED mit Taster-Interrupt     This page in English (external): Flag EN
ATtiny13

Lektion 7: Eine LED blinkt mit dem Tasten-Interrupt


Mit dieser Lektion schließen wir eine Taste an den Prozessor an und verwenden den INT0-Interrupt, um nicht per Schleifen auf Drücke auf die Taste warten zu müssen.

7.0 Übersicht

  1. Einführung in Tasten und die INT0-Programmierung
  2. Aufgabenstellung
  3. Hardware, Bauteile, Aufbau
  4. Programm

7.1 Einführung in Tasten und die INT0-Programmierung

7.1.1 Tasten an Inputports

Schaltet man bei einem Portpin den Ausgangstreiber mit DDRp/portbit=0 aus, dann kann man den Zustand des Pins im PORT PINp einlesen und abhängig von diesem Zustand Programmteile ausführen.

Schalter Um eine LED am Portpin PB0 einzuschalten, solange ein Schalter am Portpin PB1 einschaltet (mit der Betriebsspannung verbunden ist), wäre für die nebenstehende Schaltung das folgende Programm nötig:

	sbi DDRB,PB0 ; LED-Ausgangstreiber an PB0 einschalten
Schleife:
	sbis PINB,PINB1 ; ueberspringe Instruktion, wenn Inputpin Eins ist
	sbi PORTB,PORTB0 ; LED ausschalten
	sbic PINB,PINB1 ; ueberspringe Instruktion, wenn Inputpin Null ist
	cbi PORTB,PORTB0 ; LED einschalten
	rjmp Schleife



Was geschieht, wenn der Schalter gar nicht angeschlossen oder kaputt ist? Der Eingang PB1 ist dann offen. Er reagiert wegen seines extrem hohen Eingangswiderstandes auf alles, was sich in seiner Umgebung signalmäßig so abspielt, z. B. elektrische Felder des 230 V-Netzes, die statische Ladung von Fingern in der Nähe oder Pegelwechsel am Nachbarpin. Ergebnis ist Zappeln am Eingangspin und hektisches Flackern der LED. Pull-Up Dagegen ist ein elektronisches Kraut gewachsen: der Pull-Up-Widerstand. Er wird gegen die positive Betriebsspannung geschaltet, setzt den Eingangswiderstand auf 47 kOhm herab und sorgt dafür, dass der Pin auf einem definierten Potential liegt. Der Strombedarf bei geschlossenem Schalter ist nicht allzu hoch (0,1 mA), auch wenn mit einem Mäuseklavier acht Eingänge gleichzeitig auf Null gezogen werden.

Da die Aufgabe von Pull-Up-Widerständen sehr oft vorkommt, gibt es die Möglichkeit, diese prozessorintern zuzuschalten. Sie werden eingeschaltet, indem das Datenrichtungsregister-Bit auf Null und das Ausgabeport-Bit auf Eins gesetzt wird. Z. B.

	cbi DDRB,DDB1 ; Richtung = Input
	sbi PORTB,PORTB1 ; Pull-Up einschalten

Warum Pull-Up und nicht Pull-Down dürfte historische Gründe haben.

Dasselbe gilt, wenn statt eines Schalters ein Taster an den Eingang angeschlossen ist. Dann ist der Pull-Up umso wichtiger, weil der im losgelassenen Zustand ja tatsächlich elektrisch in der Luft hängt.

7.1.2 Tasten und Schalter prellen

Prellen Eine unangenehme Eigenschaft ist, dass mechanische Tasten und Schalter immer prellen. Das heißt, sie schließen und öffnen nicht mit einem Mal sondern mehrmals. Das sorgt im Zeitbereich bis 10 oder 20 ms für einen echten Signalschwarm. Programmtechnisch bedeutet das, dass die Software auf solche Schwärme vorbereitet werden muss, damit sie von nachfolgenden Signalen nicht irritiert ist.

Das Prellen spielt erst bei der nächsten Lektion eine Rolle.

7.1.3 Der INT0-Interrupt

ISC-Bits Der INT0-Interrupt überwacht den entsprechenden INT0-Eingang (beim ATtiny13 Pin6) auf auftretende Pegel und Pegelflanken und verzweigt zum INT0-Interrupt-Vektor, wenn der entsprechende Interrupttyp einschaltet ist. Die mit ISC01 und ISC00 auswählbaren Pegel und Flanken sind folgende:
ISC01ISC00Interruptauslösung
00Niedriger Pegel löst Interrupt aus
01Jeder Wechsel des Pegels löst Interrupt aus
10Fallender Pegel löst Interrupt aus
11Steigender Pegel löst Interrupt aus
Das ist ziemlich fatal, weil der Defaultwert ist, dass Nullpegel Interrupts auslösen. Das bedeutet, dass versehentliches Aktivieren des Interrupts in diesem Modus zu einer Dauerblockade des Prozessors führen: der Interrupt schlägt sofort wieder zu, wenn der letzte fertig bearbeitet ist, solange der Eingang Null ist. Da dieser INT0-Interrupt auch noch die höchste Priorität hat, kommt kein anderer mehr durch. Damit kriegt man einen AVR zur Totalblockade mit nachhaltiger Arbeitsverweigerung.

Die ISC-Bits liegen im gleichen Port wie das SE-Bit zum Schlafen. Die Pegelauswahl erfolgt daher immer zusammen mit dem SE-Bit.

INT0 im GIMSK Und so kriegt man den INT0 dazu, Interrupts anzufordern: Eins-setzen des INT0-Bits im Port GIMSK. Die Instruktion dafür ist:

	ldi R16,1<<INT0 ; INT0-Bit setzen
	out GIMSK,R16 ; und in General Interrupt Mask schreiben

Im Bereich der Interrupt-Vektoren steht der INT0-Interrupt an oberster Stelle hinter dem Reset-Vektor, mit höchster Priorität. Im ATtiny13:

.CSEG ; Assemblieren in den Flashspeicher (Code Segment)
.ORG 0 ; Adresse auf Null (Reset- und Interruptvektoren beginnen bei Null)
	rjmp Start ; Reset Vektor, Sprung zur Initiierung
	rjmp Int0_Isr ; INT0-Int, aktiv
	reti ; PCINT-Int, nicht aktiv
	reti ; TIM0_OVF, nicht aktiv
	reti ; EE_RDY-Int, nicht aktiv
	reti ; ANA_COMP-Int, nicht aktiv
	reti ; TIM0_COMPA-Int, nicht aktiv
	reti ; TIM0_COMPB-Int, nicht aktiv
	reti ; WDT-Int, nicht aktiv
	reti ; ADC-Int, nicht aktiv
;
; Interrupt-Service-Routinen
;
Int0_Isr: ; INT0-ISR
	in R15,Sreg ; SREG retten
	[...] ; weitere Aktionen
	out SREG,R15 ; SREG wieder herstellen
	reti ; zurueckkehren
;
; Programmstart beim Reset
;
Start:
	; [Hier beginnt das Programm]

Das war es schon und es kann an die Aufgabe gehen.

Home Top Einführung Aufgabe Hardware Programm


7.2 Aufgabenstellung

Das hier ist die komplexe Aufgabe:

Signalfolge

Ein Tastersignal startet eine Signalfolge der LED, die zwei kurze und ein drittes längeres Signal mit dem dargestellten Timing umfasst. Die Lösung soll prell-unempfindlich sein.

Home Top Einführung Aufgabe Hardware Programm


7.3 Hardware, Bauteile und Aufbau

7.3.1 Hardware

Schaltbild Die Duo-LED ist an den Portbits PB2 (Anode rot) und PB0 (Anode grün) angeschlossen. Die Ausgangssignale an beiden Portpins zeigt die Tabelle.

Die Taste ist mit einem Anschluss an den INT0-Eingang (PB1) angeschlossen, der zweite Anschluss liegt auf Masse (Minus).

7.3.2 Bauteile

Duo-LED
Duo-LED Die Duo-LED enthält zwei LED, eine rote und eine grüne. Der längere Anschlussdraht ist die Anode der roten LED und die Kathode der grünen.
Taster
Taster von unten Taster von oben Das ist ein Taster. Jeweils zwei seiner vier Anschlussstifte sind verbunden, Drücken der Taste schließt die Anschlüsse.


Home Top Einführung Aufgabe Hardware Programm


7.4 Programm

7.4.1 Ablauf

Um die Aufgabe zu lösen ist ein klarer Ablauf aufzuzeichnen. In diesem Fall ist er offenkundig so:

Zähler Noch ein Wort darüber, warum Assemblerprogrammierer Zähler immer rückwärts laufen lassen: erreicht er beim Dekrementieren die Null, wird die Z-Flagge gesetzt. Und die lässt sich mit "BREQ" und "BRNE" bequem zum Verzweigen benutzen. Liefe der Zähler aufwärts, müsste mit "cpi rCntDwn,7" und dann erst könnte mit "breq Label" verzweigt werden. Abwärts spart eine Instruktion.

Um die Farben der LED zu den richtigen Zeiten zu wechseln, verwenden wir einen Abwärtszähler, rCntDwn. Der Zähler beginnt bei sechs und muss alle 0,25 Sekunden abwärts zählen. Bei den Zählerständen 5 und 3 muss auf Grün umgeschaltet werden. Ist der Zähler Null, dann endet der Zyklus, die LED werden abgeschaltet und die T-Flagge auf Null gesetzt.

7.4.2 Ablaufdiagramme

INT0 Die T-Flagge ist ein frei verfügbares Bit 6 im Statusregister (siehe Lektion 6). Es lässt sich mit "SET" auf Eins setzen und mit "CLT" löschen. Mit den bedingten Sprungbefehlen "BRTS" und "BRTC" lassen sich Verzweigungen realisieren, wenn das T-Bit geSetzt oder geCleared ist. Eine Besonderheit tritt auf, wenn die T-Flagge in einer Interrupt-Service-Routine geändert werden soll: mit dem Sichern und Wiederherstellen des Statusregisters würde das zwischendurch gesetzte T-Flag wieder überschrieben. In unserem Fall macht das nix, weil der INT0-Interrupt nichts weiter tun muss als nur die T-Flagge setzen. Da die anderen Bits im SREG in der Routine nicht verändert werden, gibt es diesmal keinen Konflikt.

CTC-Int Um das Timing exakt hinzukriegen, wählen wir einen Vorteiler von 8, einen CTC-Teiler von 150 und einen Software-Zähler bis 250. Das ergibt genau 0,25 Sekunden. Da wir noch ein paar Takte Verwaltung zu tun haben, ist die Genauigkeit nur scheinbar, aber die Abweichungen sind hinnehmbar. Und besser und eleganter als elendig lange Verzögerungsschleifen allemal.

Ablauf Das ist der gesamte Ablauf ohne die beiden Interrupt-Service-Routinen. Diese beiden laufen separat ab und kommunizieren ihre erreichten Zustände (die Taste wurde gedückt, der Timer hat 0,25 s erreicht) über zwei Flaggen (T, bTo) an das Hauptprogramm, das schlafend auf diese beiden Ereignisse wartet.

Das Programm startet mit den Reset- und Interruptvektoren. Im Hauptprogramm folgt das Initiieren der Portpins und das Ermöglichen des INT0-Interrupts. Danach tritt der schlafende Wartezustand ein. Tritt ein Tasteninterrupt ein, dann wird das nach dem Aufwachen dadurch bemerkt, indem das T-Flag gesetzt ist. Damit das Setzen der T-Flagge nicht erneut zu einem Neustart einer schon ablaufenden Blinksequenz führt, muss zuerst geprüft werden, ob eine solche Sequenz bereits gestartet ist und gerade abläuft. Das wird am Registerinhalt des Countdown-Zählers "rCntDwn" erkannt. Ist er nicht Null, wird die folgende Prüfung auf eine gesetzte T-Flagge übersprungen. Wenn nicht, wird T geprüft. Ist T gesetzt, wird nun eine Blinksequenz gestartet. Dazu wird beim Timer Die LED wird auf rot geschaltet und der Countdown-Zähler mit 6 gestartet.

Sind die vorgewählte Anzahl Timer-Interrupts eingetreten, setzt der Timer die bTo-Flagge. Ist bTo gesetzt, wird in der Hauptprogrammschleife die nächste Phase des Ablaufs bearbeitet. Hat der Ablauf rCntDwn Null erreicht, wird der Timer und die LED abgeschaltet. In diesem Zustand verharrt das Programm schlafend bis zum nächsten Tastendruck.

7.4.3 Das Programm

Das hier ist das Programm (den Quellcode gibt es hier):

;
; *************************************
; * Taster mit INT0-Interrupt         *
; * (C)2016 by www.gsc-elektronic.net *
; *************************************
;
.NOLIST
.INCLUDE "tn13def.inc"
.LIST
;
; ------ Programmablauf ---------------
; 
; Das Programm wartet auf negative Flanken
; am INT0-Eingang. Tritt eine solche ein,
; wird mittels der T-Flagge der folgende
; Ablauf gestartet:
; - Ein Abwaertzaehler wird auf 6 gesetzt.
; - Die LED wird auf Rot geschaltet.
; - Der Timer wird im CTC-Modus mit einem
;   Teiler von 150 im Compare-A-Register
;   gestartet.
; Beim Compare-A-Interrupt wird ein
; Softwarezaehler von 250 auf Null ab-
; waerts gezaehlt. Wird Null erreicht,
; wird der Zaehler mit 250 neu gestartet
; und die bTO-Flagge gesetzt.
; Ist die bTO-Flagge gesetzt, wird sie
; wieder rueckgesetzt und der Abwaerts-
; zaehler um Eins vermindert. Bei den
; folgenden Zaehlerstaenden werden diese
; Operationen vorgenommen:
; 5, 3: LED auf gruen
; 4, 2: LED auf rot
; 0: Ablauf beenden, Zaehler abschalten,
;    T-Flagge ruecksetzen
;
; --------- Register ------------------
; frei R0 .. R14
.def rSreg = R15 ; Sichern Statusregister
.def rmp = R16 ; Vielzweckregister
.def rimp = R17 ; Vielzweckregister Interrupts
.def rFlag = R18 ; Flaggenregister
	.equ bTo = 0 ; Timeout-Flagge Timer
.def rCntDwn = R19 ; Count Down
.def rCtcCnt = R20 ; CTC-Count-Down
; frei R21 .. R31
;
; --------- Ports ---------------------
.equ pOut = PORTB ; Output-Port
.equ pDir = DDRB  ; Direction-Port
.equ pIn  = PINB  ; Input-Port
.equ bARO = PORTB2 ; Anode LED rot Ausgabe
.equ bKRO = PORTB0 ; Kathode LED rot Ausgabe
.equ bPuO = PORTB1 ; Pull-Up Taster Ausgabe
.equ bARD = DDB2 ; Anode LED rot Richtung
.equ bKRD = DDB0 ; Kathode LED rot Richtung
;
; --------- Timing --------------------
; Clock       = 1200000 Hz
; Prescaler   = 8
; CTC-Teiler  = 150
; Counter     = 250
; ----------------------------
; Signaldauer = 0,250 Sekunden
;
; --------- Konstanten ----------------
.equ cCtcCmp = 149 ; CTC-Teiler - 1
.equ cCtcInt = 250 ; Int-Zaehler
;
; --------- Reset- und Int-Vektoren ---
.CSEG ; Assemblieren in den Flashspeicher (Code Segment)
.ORG 0 ; Adresse auf Null (Reset- und Interruptvektoren beginnen bei Null)
	rjmp Start ; Reset Vektor, Sprung zur Initiierung
	rjmp Int0_Isr ; INT0-Int, aktiv
	reti ; PCINT-Int, nicht aktiv
	reti ; TIM0_OVF, nicht aktiv
	reti ; EE_RDY-Int, nicht aktiv
	reti ; ANA_COMP-Int, nicht aktiv
	rjmp Tc0CmpA ; TIM0_COMPA-Int, aktiv
	reti ; TIM0_COMPB-Int, nicht aktiv
	reti ; WDT-Int, nicht aktiv
	reti ; ADC-Int, nicht aktiv
;
; Interrupt-Service-Routinen
;
; INT0 wird von fallenden Flanken am Tasten-
; eingang ausgeloest. Das T-Flag wird gesetzt.
;
Int0_Isr: ; INT0-ISR
	set ; setze T-Flagge
	reti ; zurueckkehren
;
; TC0-Compare-A wird bei Ueberschreitung des Compare-A-
; Wertes ausgeloest. Der Zaehler rCtcCnt wird abwaerts
; gezaehlt. Erreicht er Null, wird er neu gestartet
; und die bTO-Flagge gesetzt.
;
Tc0CmpA: ; TC0 Compare A ISR
	in rSreg,SREG ; sichere SREG
	dec rCtcCnt ; CTC-Zaehler abwaerts
	brne Tc0CmpA1 ; noch nicht Null
	sbr rFlag,1<<bTo ; Timeout-Flagge setzen
	ldi rCtcCnt,cCtcInt ; Neustart Zaehler
Tc0CmpA1:
	out SREG,rSreg ; SREG wieder herstellen
	reti
;
; Programmstart beim Reset
;
Start:
	; Stapel-Init
	ldi rmp,LOW(RAMEND)
	out SPL,rmp;
	; LED-Ausgaenge initiieren
	ldi rmp,(1<<bARD)|(1<<bKRD) ; Ausgaenge
	out pDir,rmp ; an Richtungsport
	; Pull-Up-Widerstand einschalten
	sbi pOut,bPuO ; Pull-up an
	; Anfangszustand setzen
	clr rCntDwn ; Countdown-Zaehler aus
	clt ; Busy-Flagge aus
	; Schlafen ermoeglichen, Ext. Int
	ldi rmp,(1<<SE)|(1<<ISC01) ; Schlafen, fallende Flanke
	out MCUCR,rmp
	; INT0 ermoeglichen
	ldi rmp,1<<INT0 ; INT0-Interrupts an
	out GIMSK,rmp ; in General Interrupt Maske
	; Interrupts einschalten
	sei ; Interrupt-Flagge setzen
Schleife:
	sleep
	nop
	tst rCntDwn ; Countdown-Zaehler = Null?
	brne Schleife1 ; nein, nicht starten 
	brtc Schleife1 ; springe bei T = 0
	rcall Starten ; Sequenz starten
Schleife1:
	sbrc rFlag,bTo ; Springe, wenn CTC-Flagge aus
	rcall Countdown ; abwaerts bearbeiten
	rjmp Schleife
;
; Sequenz starten
; - Startwert Abwaertszaehler setzen
; - LED auf rot
; - bTO-Flagge loeschen
; - Timer 0 im CTC-Modus starten
;
Starten:
	ldi rCntDwn,6 ; Startwert erster Zyklus
	ldi rmp,(1<<bPuO)|(1<<bARO) ; rote LED und Pullup
	out pOut,rmp ; an Ausgangsport
	ldi rCtcCnt,cCtcInt ; Neustart CTC-Int-Zaehler
	cbr rFlag,1<<bTo ; Timeout-Flagge Null
	ldi rmp,cCtcCmp ; CTC-Teilerwert
	out OCR0A,rmp ; in Vergleichsregister A
	ldi rmp,1<<WGM01 ; TC0 als CTC mit Compare A
	out TCCR0A,rmp ; in Kontrollregister A
	ldi rmp,1<<CS01 ; Prescaler = 8
	out TCCR0B,rmp ; in Kontrollregister B
	ldi rmp,1<<OCIE0A ; Compare-A-Interrupt
	out TIMSK0,rmp ; in TC0-Int-Maske
	ret ; Fertig
;
; 250 ms vorbei, naechste Stufe
; - bTO-Flagge loeschen
; - rCntDwn vermindern
; - bei 0: LED ausschalten, Timer aus
; - bei 5 und 3: LED gruen schalten
; - bei 4 und 2: LED rot schalten
;
Countdown:
	cbr rFlag,1<<bTo ; Flagge ruecksetzen
	dec rCntDwn ; naechste Stufe abwaerts
	breq CountdownAus ; beendet, ausschalten
	cpi rCntDwn,5 ; Zyklus = 5?
	breq CountDownGreen ; Lampe auf Gruen
	cpi rCntDwn,3 ; Zyklus = 3?
	breq CountDownGreen
	; LED auf rot schalten
	ldi rmp,(1<<bPuO)|(1<<bARO) ; Rot und Pullup
	out pOut,rmp ; an Ausgabeport
	ret
CountDownGreen: ; LED  auf Gruen
	ldi rmp,(1<<bPuO)|(1<<bKRO) ; Gruen und Pullup
	out pOut,rmp ; an Ausgabeport
	ret
CountdownAus: ; Beendet, alles ausschalten
	clr rmp ; Zaehler ausschalten
	out TCCR0B,rmp ; in Kontrollregister B
	out TIMSK0,rmp ; Timer-Int aus
	ldi rmp,1<<bPuO ; alles aus ausser Pullup
	out pOut,rmp ; LED aus
	clt ; T-Flagge aus
	ret
;
; Ende Quellcode
;

Zwei Instruktionen sind neu:

Home Top Einführung Aufgabe Hardware Programm


7.4.4 Simulation der Vorgänge

Um diese Abläufe zu simulieren füttern wir den Quellcode in avr_sim und steppen uns durch die einzelnen Sequenzen des Quellcodes.

Port B nach dem Init Das ist der Zustand des Port B nach dem Init: Nun geht der Herr Professor in den Idle-Schlafmodus und Port B wartet auf Signale an PB1.

INT0 initiated Durch Klicken auf das Portbit INT0 lösen wir eine INT0-Interruptanforderung aus. Sofern kein anderer Interrupt gerade bearbeitet wird, wird die Anforderung mit der nächsten Instruktion ausgeführt. Selbst wenn nun noch andere Interruptanforderungen vorlägen, käme INT0 trotzdem dran, denn er hat die höchste Priorität (er steht in der Vektorliste ganz oben).

INT0 Sprung zum Vektor Der Controller wacht damit auf, legt die derzeitige Ausführungsadresse auf dem Stapel ab und verzweigt zur INT0-Vektoradresse.

INT0-ISR setzt T-Flagge Die einzige Tätigkeit in der INT0-Serviceroutine ist das Setzen der T-Flagge im Statusregister SREG und startet damit den Ablauf.

Starten einer Sequenz Nach dem Aufwachen bemerkt der Herr Professor, dass die T-Flagge gesetzt ist und er ruft mit RCALL StartSeq die Unterroutine auf, die den Ablauf startet. Durch den RCALL wird der gerade durch die Rückkehr vom INT0-Interrupt wieder erhöhte Stapelzeiger wieder um zwei Positionen niedriger, weil die Rückkehradresse auf dem Stapel abgelegt wird.

Die Unterroutine StartSeq hat zuerst geprüft, ob der Abwärtszähler auf Null steht. Wenn nicht, wird wieder schlafen gelegt. Ist er auf Null, wird der Abwärtszähler in R19 auf 6 gesetzt, um eine Sequenz zu beginnen. Der CTC-Zähler in R20 wurde auf 250 gesetzt, damit 250 CTC-Sequenzen ausgeführt werden. Man beachte, dass die T-Flagge gesetzt bleibt. Sie wird erst gelöscht, wenn die Zählsequenz auf Null läuft. Weitere INT0-Interrupts tun daher nichts, weil der Abwärtszähler ab jetzt nicht mehr Null ist.

Timer TC0 nach der Startsequenz Die Routine StartSeq hat den Timer TC0 in den CTC-Modus gebracht. Sein TOP-Wert ist 149, daher startet der Timer nach 150 Zählimpulsen neu. Der Prozessortakt wird mit dem Prescaler durch 8 geteilt, daher dauert der CTC-Zyklus 8 * 150 / 1.200.000 = 1,00 ms.

Erster Compare Match Interrupt Nachdem TC0 150 erreicht hat (und neu gestartet wurde) löst er einen Compare Match A aus und verzweigt zum CMP0A-Interrupt-Vektor.

Zeit bis zum ersten Compare Match Interrupt Wie vorherberechnet erfolgt der erste Compare Match Interrupt nach 1.0025 ms. Die "Überzeit" von 2,5 µs ist dadurch verursacht, dass die Rücksprungadresse auf dem Stapel abgelegt und das I-Flag im SREG gelöscht werden muss, bevor die Vektoradresse angesprungen werden konnte. Misst man von Sprung bis Sprung immer bei der gleichen Instruktion, verschwindet diese Extrazeit und die Millisekunde stimmt genau. Für das menschliche Auge ist aber der kleine Unterschied beim allerersten Zyklus ohnehin nicht sichtbar.

250 CTC-Zyklen Hier sind 250 CTC-Zyklen abgelaufen. Die bTO-Timeout-Flagge wird nun gesetzt um das Time-Out zu signalisieren. Die abgelaufene Zeit seit dem Timer-Start is ziemlich genau.

Port vor dem Polaritätswechsel Port nach dem Polaritätswechsel Nun, da die bTO-Flagge gesetzt ist, ist es Zeit die Farbe der Duo-LED von rot nach grün umzukehren. Hier wechseln die Bits PB0 und PB2 und die machen das schon.

Das wiederholt sich fünf mal, davon einmal ohne Farbwechsel.

Ein Zyklus ist abgelaufen Nach 1,5 Sekunden ist der ganze Zyklus vorbei, die T-Flagge wird gelöscht und es kann mit Tastendruck von vorne beginnen.



Home Top Einführung Aufgabe Hardware Programm


©2016 by http://www.gsc-elektronic.net