Elektronischer Spielwürfel mit ATtiny13V

von Michael Schramm


ELO 2009
Elektronik-Labor  Labortagebuch  ELO  


1


Ach, noch ein elektronischer Würfel... Ja, stimmt - aber dies ist ein ganz besonderer, der die Möglichkeiten des verwendeten kleinen Microcontrollers AVR ATTiny13V wirklich ausreizt. Er kann nämlich nicht nur auf Tastendruck würfeln, sondern lässt sich in einen Dauerwürfelmodus versetzen, in dem in zufälliger Reihenfolge eine Zahl nach der anderen gewürfelt wird - hübsch zur Dekoration, etwa auf Partys. Hierzu muss man nur die Würfeltaste mindestens vier Sekunden lang drücken (die LEDs verlöschen dann zunächst) oder nach Einschalten der Stromversorgung einfach gar nichts tun.

Noch zwei optische Extras: Der Würfel 'rollt aus', und die gewürfelte Zahl glimmt dreimal als LED-Leuchtmuster auf. Die Helligkeitssteuerung löst der Microcontroller mithilfe der PWM (Pulsweitenmodulation).

Bei der Programmierung des µC ist zu beachten, dass dieses Programm für eine interne Taktung mit 128 kHz ausgelegt ist - das ist der Takt des Watch-Dog-Oszillators. Diese Einstellung über die Fuses sollte als Letztes, nach der Flash-Programmierung, vorgenommen werden, denn anschließend kann der Controller nur noch sehr langsam mit dem Programmer kommunizieren.

Die Würfelschaltung entspricht dem üblichen Muster. Die immer paarweise gemeinsam leuchtenden LEDs werden entweder in Reihen- oder Parallelschaltung von einem µC-Ausgang gesteuert. Die fünf vollwertigen Ein- und Ausgänge eines Tiny13 genügen somit gerade für den Taster, die einzelne zentrale LED sowie die drei LED-Paare. PB5 (= Reset) bleibt ungenutzt.

Nach jedem Würfeldurchgang wird der Controller in den power-down-Schlafzustand versetzt. Es fließt dann ein Ruhestrom von deutlich unter einem µA. Ein Ausschalter ist daher nicht erforderlich. Ein Druck auf die Würfeltaste weckt das IC wieder auf (per pin change interrupt).
Ob man die LEDs in Reihe betreiben kann oder eine Parallelschaltung erforderlich ist, hängt von der Höhe der Versorgungsspannung und der Art der Leuchtdioden ab. Der ATTiny13V arbeitet zuverlässig im Betriebsspannungsbereich von 1,8 bis 5,5 Volt, während der ATTiny13 (also ohne das V in der Bezeichnung) relativ genau auf 5 Volt besteht. In der V-Version lässt sich der Würfel daher bereits mit zwei Batterien oder Akkus betreiben, am besten mit roten oder gelben LEDs.

 


Die Schaltung des Würfels (mit LEDs in Parallelschaltung)

 

Die Widerstände sind so zu wählen, dass der gewünschte Strom fließt, bspw. 5 mA pro LED. Bei 2,4 Volt Betriebsspannung (2 NiMH-Akkus in Reihe) und roten LEDs: R1 bis R6 = 82 Ω, R7 = 120 Ω

;----------------------------------------------------------------------
; Würfelsimulator mit ATTiny13 / ATTiny13V
; Weitere Infos: www.schramm-software.de/bausatz/
;----------------------------------------------------------------------
; Prozessor: ATtiny13 (V)
; Takt : 128 kHz
; Sprache : Assembler
; Version : 1.0
; Autor : Dr. Michael Schramm
; Datum : 5.2009
;----------------------------------------------------------------------
; Portbelegung:
; PB0: Taster gegen Masse
; PB1 bis PB4: Leuchtdioden gegen Masse:
; 2 1
; 3 4 3
; 1 2
; PB5 wie PB1
;----------------------------------------------------------------------
.include "tn13def.inc"
; Als globale Variablen genutzte Register:
.DEF lfsr0 = r6 ;3 Register bilden ein 23bit-LFSR
.DEF lfsr1 = r7 ; (linear rückgekoppeltes Schieberegister)
.DEF lfsr2 = r8 ; für den Pseudo-Zufallszahlengenerator
.DEF ledmust = r9 ;PB-LED-Muster gemäß wuewert
.DEF int_lwr = r10 ;nur als Zwischenspeicher in Interrupt-Routinen
.DEF int_hir = r11 ;nur als Zwischenspeicher in Interrupt-Routinen
.DEF ausr_ct = r12 ;Ausroll-Counter (Zähler je Interrupt)
.DEF einsreg = r13 ;konstant 1
.DEF intreg = r14 ;nur als Zwischenspeicher in Interrupt-Routinen
.DEF nullreg = r15 ;konstant 0
.DEF tim24bt = r21 ;für 24bit-Timer-Zähler
.DEF ausr_ln = r22 ;Anz. Interrupts pro Ausrollschritt
.DEF wuewert = r23 ;gewürfelte bzw. anzuzeigende Zahl, als Index 0..5
.DEF phase = r24 ;Spielphase, steuert Vorgänge bei Timer-Interrupt:
; 0: nichts zu tun
; 1: gewürfelter Wert glimmt mehrfach auf (zeitlich zuletzt)
; 2: warten auf Tastendruck nach Einschalten, PB4-LED blinken lassen
; 3: Taste gedrückt beim Würfeln, "Würfel rollen lassen"
; 4: Taste losgelassen, "Würfel rollt aus"
.DEF flags = r25 ;diverse Flags. Bedeutung der Bits:
; 6: Interrupt durch gedrückte Taste
; 7: Tastendruck-Interrupt ausgelöst
;----------------------------------------------------------------------
.macro ldi_hl ;(reg, 16bit-Zahl)
ldi @0h,high(@1)
ldi @0l,low(@1)
.endmacro
.macro out_i ;(I/O-reg, 8bit-Zahl) - zerstört Inhalt von R16
ldi r16,@1
out @0,r16
.endmacro
.macro for ;(reg, anzahl bzw. startwert, label); für reg ab R16
ldi @0,@1
.set @2 = pc
.endmacro
.macro next_down ;(reg, label)
dec @0
.if pc-@1 < 64
brne @1
.else
breq pc+2
rjmp @1
.endif
.endmacro
.macro next_up ;(reg, endwert, label)
inc @0
cpi @0,@1+1
.if pc-@1 < 64
brcs @2
.else
brcc pc+2
rjmp @2
.endif
.endmacro
.macro loop ;(label, reg) - Register muss vorbelegt sein
.set @0 = pc
.endmacro
;----------------------------------------------------------------------
.CSEG
;Reset- und Interruptvektoren
rjmp start ;0 RESET, Brown-out Reset, Watchdog Reset
reti ;1 INT0 External Interrupt Request 0
rjmp i_pcint0;2 PCINT0 Pin Change Interrupt Request 0
rjmp i_t0ov ;3 TIM0_OVF Timer/Counter Overflow
reti ;4 EE_RDY EEPROM Ready
reti ;5 ANA_COMP Analog Comparator
reti ;6 TIM0_COMPA Timer/Counter Compare Match A
rjmp i_t0cmb ;7 TIM0_COMPB Timer/Counter Compare Match B
; reti ;8 WDT Watchdog Time-out
; reti ;9 ADC ADC Conversion Complete
;----------------------------------------------------------------------
led_kombi: ;LED-Kombinat. der Würfelzahlen für PORTB, mit PB0-Pull-Up
; Reihenfolge der Würfelzahlen: 1 6 2 5 3 4
.db 0b010001,0b101111,0b100101,0b110111,0b110101,0b100111

start:
; zunächst Stromsparmaßnahmen und Initialisierung
ldi r16,0b111110
out DIDR0,r16 ;Port-B-Input-Buffer ausschalten
out DDRB, r16 ;Datenrichtung von Port B
sbi ACSR,ACD ;Analog-Comparator ausschalten
clr einsreg
inc einsreg ;einsreg (R13) bleibt dauerhaft 1
out PORTB,einsreg ;Pull-Up-Widerstand an PB0 aktivieren
clr nullreg ;nullreg (R15) bleibt dauerhaft null
clr phase ;Timer-Overflow-Interrupt soll zunächst nichts tun
mov lfsr2,r16
out_i SPL,low(RAMEND) ;Stackpointer setzen, 8bit-Pointer bei Tiny13
mov lfsr0,r16
clr lfsr1 ;die LFSR-Register initialisieren
clr flags
clr wuewert
sei ;Interrupts erlauben
out_i PCMSK,(1<<PCINT0) ;Pin-Change an Pin PB0 beobachten
; nach dem Einschalten kurz alle LEDs leuchten lassen
rcall wait500ms ; eine halbe Sekunde warten
out_i PORTB,0b111111 ; alle LEDs an und Pull-Up-Widerstand
rcall wait500ms ; ... für eine Sekunde, Zeit zum Messen
rcall wait500ms
;----------------------------------------------------------------------
spiel:
; Nun warten, bis die Taste gedrückt wird. Falls das nicht innerhalb
; von etwa 4 Sekunden geschieht (xh = 8), in den Demo-Modus wechseln.
; sbi PCMSK,(1<<PCINT0) ;Signale an PB0 sollen Interr. auslösen können
out PORTB,einsreg ; alle LEDs wieder aus
sbis PINB,0 ;Taste bereits gedrückt?
rjmp taste_gedr ;dann keine Wartephase
ldi phase,2 ;zentrale LED soll blinken
rcall wait_taste
sbrs flags,7 ;Tasten-Interrupt?
rjmp demomodus ;nein => in den Demo-Modus wechseln

taste_gedr:
; Messen, wie lange die Taste gedr. wird.
; Unter 4 Sekunden => normales Spiel, Drückzeit bestimmt Würfelzahl
; 4 bis 8 Sekunden => Demo-Modus mit zufälligem Einstieg
; Über 8 Sekunden => 1-kHz-Signalerzeugung
ldi phase,3 ;schnell wechselnde Würfelzahlen zeigen
rcall wait_taste ;max. 4 Sek. auf Taste-Loslassen warten
sbrc flags,7 ;Tasten-Interrupt?
rjmp zeitmod6 ;ja => aus der Drückzeit den Würfelwert ermitteln
; 4 Sekunden sind verstrichen, Taste ist noch gedrückt. Weiter messen.
out PORTB,einsreg ;alle LEDs aus
clr phase ;im Timer-Overflow-Interrupt nichts mehr tun
rcall wait_taste ;weitere max. 4 Sek. auf Taste-Loslassen warten
sbrs flags,7 ;Tasten-Interrupt?
rjmp khz_signal ;nein, volle 8 Sek. verstrichen => Signalerzeugung
; Es soll der Demo-Modus mit zufälligem Würfelsequenz-Startpunkt
; beginnen. Gemessene Tastendruckzeit als Zufallswert nutzen.
movw lfsr0,x ;Tastendruckzeit als Zufallsgenerator-Startwert
mov lfsr2,einsreg ; lfsr insgesamt darf niemals 0 sein
;----------------------------------------------------------------------
demomodus: ;Dauer-Würfeln ...
; Falls Taste gedrückt, wieder normales Spiel
rcall init_pcif ;Tastendruck soll erkannt werden
demo_lp:
rcall wait500ms ; 1/2 Sekunde warten
ldi phase,3 ;schnell wechselnde Würfelzahlen zeigen
rcall set_tim_2khz ;Timer starten
ldi r16,(1<<SE)
demo_schnell: ;schneller Zahlenwechsel, "Würfel rollt"
out MCUCR,r16 ;Idle-Modus
sleep ;CPU schläft, wartet auf Interrupt (Timer/Taste)
sbrc flags,7 ;Tasten-Interrupt?
rjmp spiel ;ja => hier abbrechen, normales Spiel beginnen
cpi xh,16 ;etwa 2 Sekunden schnelles Würfelrollen
brcs demo_schnell
demolp2:
ldi xl,5
rcall zufallszahl ;Pseudo-Zufallszahl generieren
andi xl,7 ;die letzten drei Bits isolieren, also Werte 0 ... 7
cpi xl,6 ;nur Werte 0 .. 5 akzeptieren
brcc demolp2 ;ggf. neue Zuf.zahl erzeugen, so Gleichverteilung 0..5
cp xl,wuewert ;gleiche Werte direkt nacheinander ...
ldi wuewert,-1 ;sollen nur selten auftreten
breq demolp2
mov wuewert,xl
rcall wuerfeln ;Würfel ausrollen und Ergebnis zeigen
sbrs flags,7 ;Tasten-Interrupt?
rjmp demo_lp ;nein => weitermachen im Demo-Modus
rjmp spiel ;ja => normales Spiel beginnen
;----------------------------------------------------------------------
zeitmod6: ;Drückzeit (in XH:XL) modulo 6 berechnen ("Zufallszahl")
tst xh ;sehr kurze Drückzeit (< 128 ms)
breq spiel ;nicht akzeptieren
; add xl,yl ;letzten Messwert dazuzählen, um Manipulation
; adc xh,yh ;zu erschweren
; movw y,z ;merken für die nächste Runde
rcall xmod6 ;Ergebnis in wuewert
rcall wuerfeln ;Würfel ausrollen und Ergebnis zeigen
sbrc flags,7 ;Tasten-Interrupt?
rjmp spiel ;ja => sofort nächstes Spiel starten
schlafen:
; Ende der Würfelrunde, schlafen gehen
rcall init_pcif ;Pin-Change-Interrupt einschalten
out_i MCUCR,(1<<SE)+(1<<SM1) ;Power-down-Modus
sleep ;Tiefschlaf, warten auf Interrupt (Tastendruck)
rjmp spiel ;nächstes Würfeln starten
;----------------------------------------------------------------------
khz_signal: ; 1-kHz-Signal an PB2 und PB1 (gegenläufig) erzeugen
; Abbruch, sobald Taste gedrückt wird; dann normales Spiel starten
out_i PORTB,0b101 ; alle LEDs bis auf die an PB2 aus
ldi r18,0b110 ; 1-Bits schalten um bei OUT
khz_weiter:
rcall init_pcif ;Pin-Change-Interrupt einschalten
khz_loop:
for r19,20,khz_wt ;Warteschleife für knapp 1/2 ms
next_down r19,khz_wt
out PINB,r18 ; PB2 und PB1 umschalten
sbrs flags,7 ;wurde Tastenflag gesetzt (durch Interrupt)?
rjmp khz_loop ; nein: weiterhin Signal erzeugen
sbrs flags,6 ;Taste erst einmal losgelassen oder neu gedrückt?
rjmp khz_weiter ;losgelassen: weiterhin Signal erzeugen
rjmp spiel ; neu gedrückt: wieder normales Spiel
;----------------------------------------------------------------------
; ******************* Unterprogramme / Funktionen *******************

wuerfeln: ; *** Würfel ausrollen und Zahl gemäß Register wuewert zeigen
push wuewert
ldi phase,4 ;steht für Ausrollen
ldi ausr_ln,2 ;zunächst eine Zahl pro 2 Interrupts anzeigen
mov ausr_ct,ausr_ln
rcall set_tim_2khz ;Timer mit 2 kHz-Takt starten
ldi r16,(1<<SE)
wuerf_ausr: ;Ausroll-Anzeige regelt der Timer-Overflow-Interrupt
out MCUCR,r16 ;Idle-Modus
sleep ;CPU schläft, wartet auf Interrupt (Timer-Overflow)
cpi xh,13 ;Ausrollen abgeschlossen?
brcs wuerf_ausr ;nein, noch nicht
out TCCR0B,nullreg ;Timer aus
; ldi phase,1 ;Glühen/Dimmen des Würfelwertes
rcall init_pcif
ldi r16,2
ldi ausr_ln,1
mov ausr_ct,einsreg
for r19,5,wdimlp_
wdimlp:
mov r0,ausr_ln
wdimlp1:
sub r0,r16
brcc wdimlp1
out PORTB,ledmust
mov r0,ausr_ln
wdimlp2:
add r0,r16
brcc wdimlp2
out PORTB,einsreg
sbrc flags,7 ;Tasten-Interrupt?
rjmp wuerf_end ;ja => vorzeitig abbrechen
add ausr_ln,ausr_ct
cpi ausr_ln,255
breq wdim_cge
cpi ausr_ln,1
brne wdimlp
wdim_cge:
neg ausr_ct
next_down r19,wdimlp_
wuerf_end:
pop wuewert
ret
;----------------------------------------------------------------------
init_pcif: ; *** Pin-Change-Interrupt einschalten
cbr flags,(1<<7) ;Tastenflag löschen
ldi r16,(1<<PCIF)
; Das Pin-Change-Flag in GIFR muss zurückgesetzt werden, damit ein
; schon erfolgter Pin-Cge nicht im Nachhinein einen Interr. auslöst.
out GIFR,r16 ;Pin-Change-Flag löschen
out_i GIMSK,(1<<PCIE) ;Pin-Change-Interrupt aktivieren
ret
;----------------------------------------------------------------------
wait500ms: ; *** in etwa eine halbe Sekunde warten
; Stromsparende Realisierung über Timer im Sleep-Modus
out TCNT0,nullreg ;Counter-Wert nullsetzen
out_i TIMSK0,(1<<TOIE0) ;Timer-Overflow-Interrupt aktivieren
out_i TCCR0B,(1<<CS02) ;Timertakt = Systemtakt / 256 = 500 Hz
out_i MCUCR,(1<<SE) ;Idle-Modus
sleep ;CPU schläft, wartet auf Interrupt (Timer-Überlauf)
out TCCR0B,nullreg ;Timer stoppen
ret
;----------------------------------------------------------------------
wait_taste: ; *** auf Tastenereignis warten, jedoch max. ca. 4 Sekunden
; Output: XH:XL = verstrichene Zeit in 2000stel Sekunden
; flags-b7 gesetzt, falls Tastenereignis eingetreten
rcall init_pcif ;Pin-Change-Interrupt einschalten
rcall set_tim_2khz
ldi r16,(1<<SE)
wt_tas_4sek:
out MCUCR,r16 ;Idle-Modus
sleep ;CPU schläft, wartet auf Interr. (Taste oder Timer-Overflow)
sbrc flags,7 ;Tasten-Interrupt?
rjmp wt_tas_end ;dann die Warteschleife verlassen
cpi xh,31 ;maximal ca. 4 Sekunden auf Tastenereignis warten
brcs wt_tas_4sek
wt_tas_end:
out TCCR0B,nullreg ;Timertakt stoppen
out GIMSK,nullreg ;Pin-Change-Interrupt deaktivieren
in xl,TCNT0
ret
;----------------------------------------------------------------------
set_tim_2khz: ; *** Timer mit 2-kHz-Takt starten
ldi r16,(1<<CS01)+(1<<CS00) ;Timertakt = Systemtakt / 64 = 2 kHz
ldi r17,(1<<TOIE0) ;Timer-Overflow-Interrupt aktivieren
cpi phase,3 ;in Phase 3 sind zusätzliche Einstellungen erforderlich
brne set_tim_var
ldi r17,220 ;TCNT0-Vergleichswert für das LED-Ausschalten
out OCR0B,r17
ldi r17,(1<<TOIE0)+(1<<OCIE0B) ;zusätzlich Compare-Match-B-Interrupt
set_tim_var: ; *** Timer mit Parametern gemäß R16/R17 starten
; Aufgrund früherer Compare-Matches sind die entsprechenden Interrupt-
; Flags bereits gesetzt und müssen vor dem Int.-Aktiv. gelöscht werden
ldi xh,(1<<OCF0B)+(1<<OCF0A)+(1<<TOV0)
out TIFR0,xh
clr xh ;Überlauf-Reg. für den Timer, wird in Int.-Rout. inkrementiert
clr tim24bt ;dito, bei hoher Taktrate auch weiterer Überlauf
out TCNT0,nullreg ;Counter-Wert nullsetzen
out TIMSK0,r17 ;Timer-Interrupts aktivieren
out TCCR0B,r16 ;Timer mit gewünschtem Takt starten
ret
;----------------------------------------------------------------------
nxt_wuewert: ; *** Nächster Würfelwertindex (-1, mod 6)
dec wuewert ;nächster Würfelwertindex für die nächste Runde
brpl get_muster
ldi wuewert,5 ;nur Werte 0 bis 5, bei -1 Rücksetzen auf 5
get_muster: ; *** LED-Muster für den Würfelwertindex => ledmust
ldi_hl z,led_kombi*2 ;Basisadresse der Würfelwerte im Flash-Speicher
add zl,wuewert ;8bit-Addition genügt, da kleine Adresse
lpm ledmust,z ;LED-Kombination für den Würfelwert
ret
;----------------------------------------------------------------------
zufallszahl: ; *** Pseudo-Zufallszahl erzeugen (per LFSR mit 23 Bits)
; Input: XL = Anzahl n der zu erzeugenden Bits (1 ... 16)
; Output: XH:XL = Zufallszahl (in den unteren n Bits)
loop zuf_lp ;n Shift-Operationen mit Rückkopplung
mov xh,lfsr1
lsl xh ;bit 13 des LFSR steht nun in bit 6 von xh
eor xh,lfsr2 ;bit 22 und 13 des LFSR sollen verknüpft werden
lsl xh ;jetzt in bit 7
lsl xh ;jetzt im Carry-Flag
rol lfsr0 ;gesamtes LFSR links-shiften und neues Bit einschieben
rol lfsr1
rol lfsr2
next_down xl,zuf_lp ;n "neue bits" stehen bereit in LFSR
movw x,lfsr0
ret
;----------------------------------------------------------------------
xmod6: ; *** x := x mod 6; wuewert := xl
; nicht die schnellste, aber eine kurz zu formulierende Methode
xm6_xh: ;Berechnung xh := xh mod 6 - 6
subi xh,6
brcc xm6_xh
xm6_ueb_korr: ;Modulo-6-konforme Überlaufkorrektur
subi xl,4 ;256 - 4 = 252 ist durch 6 teilbar
brcc xm6_uebk_2
subi xl,-12 ;Ergebnis darf nicht negativ sein
xm6_uebk_2:
inc xh ;xh wird auf null gebracht
brne xm6_ueb_korr
xm6_xl: ;nun noch xl := xl mod 6
subi xl,6
brcc xm6_xl
subi xl,-6 ;Ergebnis liegt in [0;5]
mov wuewert,xl
ret
;----------------------------------------------------------------------
; ************************ Interrupt-Routinen ************************

; Um Zeit und Programmspeicherplatz zu sparen, wird das Statusregister
; nicht auf dem Stack zwischengespeichert, sondern in intreg (= R14).
; Dieses Register darf daher nur innerhalb der Interrupt-Routinen
; verwendet werden.

i_t0ov: ; *** Timer/Counter Overflow
; Bei Timertakt = 2 kHz (während des Würfelns) tritt dieser Interrupt
; etwa 8mal pro Sekunde auf und wird zu Darstellungszwecken gemäß
; Spielphase genutzt. Beim Aufglimmen des gewürfelten Wertes in Phase 1
; beträgt der Timertakt 128 kHz, und der Überlauf tritt 500mal / Sek.
; auf. Dann sind jeweils die LEDs auszuschalten. Register XH nimmt den
; Timer-Überlauf auf, so dass XH:TCNT0 einen 16bit-Zähler ergibt.
in intreg,sreg ;Statusregister merken
cpi phase,2
brcs iov_ende ;in Phase 0 oder 1 nichts weiter tun
push r16 ;diverse Register werden temporär benötigt
movw int_lwr,z
rcall get_muster ;LED-Kombination für den Würfelwert => ledmust
cpi phase,3
brcc iov_phm3 ;Phasen ab 3
iov_ph2: ;Phase 2, Blinken der zentralen LED
mov ledmust,einsreg ;alle LEDs aus
ldi r16,0b10001
sbrc xh,2
mov ledmust,r16 ;zentrale LED soll eingeschaltet werden
rjmp iov_outled
iov_phm3: ;Phasen ab 3
brne iov_phm4 ;Phasen ab 4
iov_ph3: ;Phase 3, Würfelwerte schnell durchlaufen lassen
rcall nxt_wuewert ;nächster Würfelwertindex
rjmp iov_outled
iov_phm4: ;Phasen ab 4
;iov_ph4: ;Phase 4; Würfel ausrollen lassen
; out PORTB,r16 ;momentanen Würfelwert anzeigen
dec ausr_ct ;zwei Zähler regeln das richtige Timing (ausrollen)
brne iov_outled; iov_pop ;diesmal keine Änderung
inc ausr_ln ;langsamer werden
mov ausr_ct,ausr_ln
rcall nxt_wuewert ;nächster Würfelwertindex
iov_outled:
out PORTB,ledmust ;Würfelwert/Effekt anzeigen
iov_pop:
movw z,int_lwr ;vorige Registerwerte wiederherstellen
pop r16
iov_ende:
add xh,einsreg ;so wird insgesamt ein 16bit-Zähler realisiert
adc tim24bt,nullreg ;bzw. 24bit (nur bei max. Timer-Taktrate)
iov_ret:
out sreg,intreg ;Statusregister wiederherstellen
reti
;----------------------------------------------------------------------
i_t0cmb: ; *** TIM0_COMPB Timer/Counter Compare Match B
; kurzzeitiges Ausschalten aller LESs in Phase 3, zwischen der
; Anzeige verschiedener Würfelwerte
out PORTB,einsreg ;alle LEDs aus
reti
;----------------------------------------------------------------------

i_pcint0: ; *** Tastenereignis
in intreg,sreg
sbr flags,(1<<7)+(1<<6) ;merken, dass Tastenereignis stattfand
sbic PINB,0
cbr flags,(1<<6) ;bedeutet, dass Taste losgelassen wurde
out GIMSK,nullreg ;keine externen Interrupts mehr annehmen
out sreg,intreg
reti
; ******************************* ENDE *******************************



Elektronik-Labor  Labortagebuch  ELO