| Weitere Artikel aus dem Elo-Magazin |
Ein Würfelprogramm für den Tiny13
von Felix Irmscher
Ein Bausatz-Klassiker, hier für den ATtin13/ ATtiny13V. Es werden nur sehr wenig externe Bauteile benötigt, wie im Programmcode dargestellt.
Damit die wenigen Ausgänge des tiny13 ausreichen, sind einige LEDs zusammengeschaltet. Der Würfel verfügt über eine AUTO POWER OFF-Funktion (Power Down - Mode). Da ich den Würfel für meinen kleinen Sohn Moritz gebaut habe, befindet er sich in einem selbstgebauten LEGO-Gehäuse.
Download Assembler-Quelltext (cube_240108_1.zip, 3 KB)
;###
CUBE_240108_1
###
;Würfelprogramm
mit
div.
Features:
;
-
Durch
POWER
DOWN
MODE
nur
einen
Taster
zum
Anschalten
;
und
neu
Würfeln
;
-
Ruhestrom
mit
tn13(kein
V-Typ)
im
PowerDownMode
ca.
0,3uA
;
-
Würfelt
nach
dem
Einschalten,
sobald
Taster
wieder
losge-
;
lassen
wird.
Wird
dann
innerhalb
der
nächsten
15Sekunden
;
(Variable:
sek)
erneut
die
Taste
gedrückt
und
wieder
;
losgelassen,
so
wird
wieder
gewürfelt.
;
-
Nach
dem
Loslassen
wird
immer
ein
Ausrollen
des
Würfels
;
simuliert
;
-
erfolgt
innerhalb
von
15sec
nach
der
Würfel-Ausgabe
kein
;
Tastendruck,
so
wird
in
den
SLEEP-Mode:
POWER
DOWN
;
geschaltet
;
-
INT0-ITR
an
Taster
angeschlossen
(alternate
function
PB1)
;
-
ITR-Subroutine
ist
leer,
da
keine
Voreinstellungen
vor
;
dem
Neustart
notwendig
sind
;
Zeitgeber
über
TIM0_OVF
.include
"tn13def.inc"
;ZUSAMMENGESCHALTETE
PUNKTE
DES
WÜRFELS
.equ
mitte
=
0
;Mitte
.equ
lu_ro
=
2
;links
unten
&
rechts
oben
.equ
lo_ru
=
3
;links
oben
&
rechts
unten
.equ
lm_rm
=
4
;links
Mitte
und
rechts
Mitte
.equ
Taster
=
1
.def
I
=
r16
.def
j
=
r17
.def
k
=
r18
.def
Sicher
=
r19
;Sicherung
von
U-Prg.s
.def
Zahl
=
r20
;Übergabevariable
für
AUSGABE
.def
Augen
=
r21
;tatsächlich
gewürfelte
Zahl
.def
Sicher_ITR
=
r22
.def
sek
=
r23
.def
timer
=
r24
.def
timer2
=
r25
rjmp
ANFANG
.org
0x0001
rjmp
EXT_INT0
;Ext.
ITR
mit
INT0
(für
SLEEP)
.org
0x0003
rjmp
TIM0_OVF
;Timer0
-
Overflow
ANFANG:
cli
sbi
ddrb,mitte
;Ausgänge
für
Punkte
sbi
ddrb,lu_ro
sbi
ddrb,lo_ru
sbi
ddrb,lm_rm
sbi
portb,Taster
;INT0
mit
pullup
für
Taster
clr
Augen
WAIT_TASTER:
Sbic
pinb,Taster
;Taster
noch
gedrückt?
Rjmp
AUSROLLEN
Cpi
Augen,6
;Augen=tatsächlich
gewürfelte
Zahl
Brlo
Augen_INC
Ldi
Augen,0
AUGEN_INC:
Inc
Augen
Rjmp
WAIT_TASTER
;----------
AUSROLLEN:
Ldi
Zahl,0
Ldi
i,0
LOOP_i:
Cpi
ZAHL,6
Brlo
ZAHL_INC
Ldi
ZAHL,0
ZAHL_INC:
Inc
ZAHL
Rcall
AUSGABE

;Pseudo-Wert
fürs
Ausrollen
Rcall
WARTESCHLEIFE
;kurze
Pause
Ldi
k,10
Add
i,k
Cpi
i,230
Brlo
LOOP_i
;----------
mov
Zahl,Augen
;echten
Wert
ausgeben
rcall
AUSGABE
clr
Augen
CUBE_240108_1
###;Würfelprogramm
mit
div.
Features:;
-
Durch
POWER
DOWN
MODE
nur
einen
Taster
zum
Anschalten;

und
neu
Würfeln;
-
Ruhestrom
mit
tn13(kein
V-Typ)
im
PowerDownMode
ca.
0,3uA;
-
Würfelt
nach
dem
Einschalten,
sobald
Taster
wieder
losge-;

lassen
wird.
Wird
dann
innerhalb
der
nächsten
15Sekunden;

(Variable:
sek)
erneut
die
Taste
gedrückt
und
wieder;

losgelassen,
so
wird
wieder
gewürfelt.;
-
Nach
dem
Loslassen
wird
immer
ein
Ausrollen
des
Würfels;

simuliert;
-
erfolgt
innerhalb
von
15sec
nach
der
Würfel-Ausgabe
kein;

Tastendruck,
so
wird
in
den
SLEEP-Mode:
POWER
DOWN;
geschaltet;
-
INT0-ITR
an
Taster
angeschlossen
(alternate
function
PB1);
-
ITR-Subroutine
ist
leer,
da
keine
Voreinstellungen
vor;

dem
Neustart
notwendig
sind;

Zeitgeber
über
TIM0_OVF.include
"tn13def.inc";ZUSAMMENGESCHALTETE
PUNKTE
DES
WÜRFELS.equ

mitte
=
0
;Mitte.equ

lu_ro
=
2
;links
unten
&
rechts
oben.equ

lo_ru
=
3
;links
oben
&
rechts
unten.equ

lm_rm
=
4
;links
Mitte
und
rechts
Mitte.equ

Taster
=
1.def

I
=
r16.def

j
=
r17.def

k
=
r18.def

Sicher
=
r19
;Sicherung
von
U-Prg.s.def
Zahl
=
r20
;Übergabevariable
für
AUSGABE.def
Augen
=
r21
;tatsächlich
gewürfelte
Zahl.def
Sicher_ITR
=
r22.def
sek
=
r23.def
timer
=
r24.def
timer2
=
r25rjmp
ANFANG.org
0x0001rjmp
EXT_INT0
;Ext.
ITR
mit
INT0
(für
SLEEP).org
0x0003rjmp
TIM0_OVF
;Timer0
-
OverflowANFANG:
cli
sbi
ddrb,mitte
;Ausgänge
für
Punktesbi
ddrb,lu_rosbi
ddrb,lo_rusbi
ddrb,lm_rmsbi
portb,Taster
;INT0
mit
pullup
für
Tasterclr
AugenWAIT_TASTER:
Sbic
pinb,Taster
;Taster
noch
gedrückt?
Rjmp
AUSROLLEN
Cpi
Augen,6
;Augen=tatsächlich
gewürfelte
Zahl
Brlo
Augen_INC
Ldi
Augen,0AUGEN_INC:
Inc
Augen
Rjmp
WAIT_TASTER;----------
AUSROLLEN:
Ldi
Zahl,0
Ldi
i,0
LOOP_i:
Cpi
ZAHL,6
Brlo
ZAHL_INC
Ldi
ZAHL,0
ZAHL_INC:
Inc
ZAHL
Rcall
AUSGABE

;Pseudo-Wert
fürs
Ausrollen
Rcall
WARTESCHLEIFE
;kurze
Pause
Ldi
k,10
Add
i,k
Cpi
i,230
Brlo
LOOP_i;----------

mov
Zahl,Augen
;echten
Wert
ausgebenrcall
AUSGABEclr
Augen
;###
Timer
starten
###
ldi
timer,6

;250
bis
OVF,
/1024
->
30Hz
OUT
TCNT0,timer
ldi
i,3


;Prescaler:
1200kHz
/64
out
TCCR0B,i
ldi
i,2


;Timer-ITR
freigeben
out
TIMSK0,i
clr
sek
clr
timer2
sei
;Global
ITR
frei!
WAIT_PUSH:
Sbis
pinb,Taster
;warten,bis
Ta
wieder
gedrückt
Rjmp
WAIT_TASTER
;beginnt
von
vorne
;------------------
SLEEP_TEST:

;länger
als
Xsec
gewartet?
Cpi
sek,15

;Sekunden
bis
zum
AUTO
POWER
OFF
Brlo
WAIT_PUSH
Ldi
i,0
Out
TCCR0B,i
;Zähler
aus!
Ldi
i,0
Out
TIMSK0,I
;Timer
ITR
aus!
cli

;76543210
Ldi
i,0b00110000
;b0:
ISC00
b1:b0=0:0,
dh.
ITR
by
Out
MCUCR,I
;b1:
ISC01
low
level
of
INT0
S.55

;b3:
SM0
b4:b3=1:0,
dh.

;b4:
SM1
power
down
mode
S.27

;b5:
SE
b5=1
Sleep
enable
S.27

;b6:
PUD
b6=0
pullup
disab
S.51

;76543210
Ldi
i,0b01000000
;b5:
PCIF
b5=0
PinChangeITR
S.56
Out
GIMSK,I
;b6:
INTF0
B6=1
.56

;
=
External
ITR
Request0
enable
Cbi
portb,mitte
Cbi
portb,lu_ro
Cbi
portb,lo_ru
Cbi
portb,lm_rm

sei
sleep
;###
POWER
DOWN
starten!!!
###
cli

;76543210
;SE
aus
!
Ldi
i,0b00000000
Out
MCUCR,i


;76543210
Ldi
i,0b00000000
;Ext
ITR
Request
aus!
Out
GIMSK,I
rjmp
WAIT_TASTER
Timer
starten
###
ldi
timer,6

;250
bis
OVF,
/1024
->
30Hz
OUT
TCNT0,timer
ldi
i,3


;Prescaler:
1200kHz
/64
out
TCCR0B,i
ldi
i,2


;Timer-ITR
freigeben
out
TIMSK0,i
clr
sek
clr
timer2
sei
;Global
ITR
frei!
WAIT_PUSH:
Sbis
pinb,Taster
;warten,bis
Ta
wieder
gedrückt
Rjmp
WAIT_TASTER
;beginnt
von
vorne;------------------
SLEEP_TEST:


;länger
als
Xsec
gewartet?
Cpi
sek,15

;Sekunden
bis
zum
AUTO
POWER
OFF
Brlo
WAIT_PUSH
Ldi
i,0
Out
TCCR0B,i
;Zähler
aus!
Ldi
i,0
Out
TIMSK0,I
;Timer
ITR
aus!
cli
;76543210
Ldi
i,0b00110000
;b0:
ISC00
b1:b0=0:0,
dh.
ITR
by
Out
MCUCR,I
;b1:
ISC01
low
level
of
INT0
S.55
;b3:
SM0
b4:b3=1:0,
dh.
;b4:
SM1
power
down
mode
S.27
;b5:
SE
b5=1
Sleep
enable
S.27
;b6:
PUD
b6=0
pullup
disab
S.51
;76543210
Ldi
i,0b01000000
;b5:
PCIF
b5=0
PinChangeITR
S.56
Out
GIMSK,I
;b6:
INTF0
B6=1
.56
;
=
External
ITR
Request0
enable
Cbi
portb,mitte
Cbi
portb,lu_ro
Cbi
portb,lo_ru
Cbi
portb,lm_rm
sei
sleep
;###
POWER
DOWN
starten!!!
###
cli
;76543210
;SE
aus
!
Ldi
i,0b00000000
Out
MCUCR,i

;76543210
Ldi
i,0b00000000
;Ext
ITR
Request
aus!
Out
GIMSK,I
rjmp
WAIT_TASTER
;============================================================
AUSGABE:
;Übergabevariable:
ZAHL

In
Sicher,SREG
Cbi
portb,mitte
;alle
LEDs
löschen
Cbi
portb,lu_ro
Cbi
portb,lo_ru
Cbi
portb,lm_rm

ZAHL_0:
Cpi
Zahl,0
Brne
ZAHL_1
;kein
Auge
setzen
Rjmp
AUSGABE_ENDE
ZAHL_1:
Cpi
Zahl,1
Brne
ZAHL_2
Sbi
portb,mitte
Rjmp
AUSGABE_ENDE
ZAHL_2:
Cpi
Zahl,2
Brne
ZAHL_3
Sbi
portb,lu_ro
Rjmp
AUSGABE_ENDE
ZAHL_3:
Cpi
Zahl,3
Brne
ZAHL_4
Sbi
portb,mitte
Sbi
portb,lo_ru
Rjmp
AUSGABE_ENDE
ZAHL_4:
Cpi
Zahl,4
Brne
ZAHL_5
Sbi
portb,lu_ro
Sbi
portb,lo_ru
Rjmp
AUSGABE_ENDE
ZAHL_5:
Cpi
Zahl,5
Brne
ZAHL_6
Sbi
portb,mitte
Sbi
portb,lu_ro
Sbi
portb,lo_ru
Rjmp
AUSGABE_ENDE
ZAHL_6:
Cpi
Zahl,6
Brne
ZAHL_1
Sbi
portb,lu_ro
Sbi
portb,lo_ru
Sbi
portb,lm_rm
Rjmp
AUSGABE_ENDE
AUSGABE_ENDE:
Out
SREG,Sicher
ret
;------------------------------------------------------------
WARTESCHLEIFE:

;Übergabevariable:
i
in
Sicher,SREG

ldi
j,0
LOOP_j:
Ldi
k,255
LOOP_k:
;innere
NICHT
variable
Schleife
nop
nop
dec
k
brne
LOOP_k

inc
j
;j
<-
j+1
cp
j,i
;wartet
umso
länger,
je
größer
brlo
LOOP_j

;i
ist
out
SREG,Sicher
ret
;------------------------------------------------------------
TIM0_OVF:
;ITR
für
Timer0
;Ausgabevariable:
sek

in

Sicher_ITR,SREG
ldi
timer,
6
out
TCNT0,timer
;250
bis
Overflow
inc
timer2
cpi
timer2,75
brlo
TIM0_ende
clr
timer2
inc
sek


TIM0_ende:


out
SREG,Sicher_ITR
;SREG
zurück
reti
;------------------------------------------------------------
EXT_INT0:
reti
AUSGABE:
;Übergabevariable:
ZAHL
In
Sicher,SREG
Cbi
portb,mitte
;alle
LEDs
löschen
Cbi
portb,lu_ro
Cbi
portb,lo_ru
Cbi
portb,lm_rm
ZAHL_0:

Cpi
Zahl,0
Brne
ZAHL_1
;kein
Auge
setzen
Rjmp
AUSGABE_ENDEZAHL_1:

Cpi
Zahl,1
Brne
ZAHL_2
Sbi
portb,mitte
Rjmp
AUSGABE_ENDEZAHL_2:

Cpi
Zahl,2
Brne
ZAHL_3
Sbi
portb,lu_ro
Rjmp
AUSGABE_ENDEZAHL_3:

Cpi
Zahl,3
Brne
ZAHL_4
Sbi
portb,mitte
Sbi
portb,lo_ru
Rjmp
AUSGABE_ENDEZAHL_4:

Cpi
Zahl,4
Brne
ZAHL_5
Sbi
portb,lu_ro
Sbi
portb,lo_ru
Rjmp
AUSGABE_ENDEZAHL_5:

Cpi
Zahl,5
Brne
ZAHL_6
Sbi
portb,mitte
Sbi
portb,lu_ro
Sbi
portb,lo_ru
Rjmp
AUSGABE_ENDEZAHL_6:

Cpi
Zahl,6
Brne
ZAHL_1
Sbi
portb,lu_ro
Sbi
portb,lo_ru
Sbi
portb,lm_rm
Rjmp
AUSGABE_ENDEAUSGABE_ENDE:
Out
SREG,Sicherret
;------------------------------------------------------------
WARTESCHLEIFE:


;Übergabevariable:
i
in
Sicher,SREG
ldi
j,0
LOOP_j:
Ldi
k,255
LOOP_k:
;innere
NICHT
variable
Schleife
nop
nop
dec
k
brne
LOOP_k
inc
j
;j
<-
j+1
cp
j,i
;wartet
umso
länger,
je
größer
brlo
LOOP_j

;i
ist
out
SREG,Sicherret
;------------------------------------------------------------
TIM0_OVF:
;ITR
für
Timer0
;Ausgabevariable:
sek
in

Sicher_ITR,SREG
ldi
timer,
6
out
TCNT0,timer
;250
bis
Overflow
inc
timer2
cpi
timer2,75
brlo
TIM0_ende
clr
timer2
inc
sek

TIM0_ende:


out
SREG,Sicher_ITR
;SREG
zurückreti
;------------------------------------------------------------
EXT_INT0:
reti
Literatur: AVR-RISC Embedded Software selbst entwickeln

Lernen Sie die ganze Vielfalt vom Franzis Buch- und Softwareverlag kennen













