Code:
;******************************************************************************
; Netzteil für Kameras mit Entprellroutine von P.Dannegger
; MCU: ATtiny13
; Takt: 4.8 MHz
; Version: 1.0
;
; Default-LED (3V): PB0
; Taster-4,3V: PB2 Schaltausgang: PB3
; Taster-6V: PB1 Schaltausgang: PB4
;******************************************************************************
.nolist
.include "tn13def.inc"
.list
;
;***** Konstanten *****
.equ vorteiler = 0b10001000 ;Wert für Systemtakt 256 (MCU-Takt=37kHz)
.equ keyport = PINB ;Eingänge
.equ t_43v = 2 ;Bitpositionen für Tasten 4,3V
.equ t_6v = 1 ;und 6V
.equ schaltport = PORTB ;Ausgänge
.equ a_3v = 0 ;Bitpositionen für Schalten 3V
.equ a_43v = 3 ;4,3V
.equ a_6v = 4 ;und 6V
.equ t_maske = 0b00000110 ;Maske für Tasten
.equ portmaske = 0b00011001 ;Maske für Ein- und Ausgänge
.equ startwert = 256-6 ;Startwert für Zeit, etwa 300ms
.equ count = 30 ;10 Sekunden bis Zeitablauf
;
;***** Register *****
.def key_ct0 = R2
.def key_ct1 = R3
.def key_state = R4
.def key_press = R5
.def Counter = R6 ;Zeitzähler
.def mp = R16
.def leds = R17
;
;******** Interruptvektoren **********
.org 0
rjmp init ;Sprung zum Hauptprogramm
reti ;externer Interrupt für Flankensteuerung
rjmp tasten ;Interrupt für Taster
rjmp zeit ;TIM0_OVF, Timer/Counter0 Overflow
reti ;EE_RDY, EEProm ready
reti ;ANA_COMP, Analog Comparator
reti ;TIM0_COMPA, Timer/Counter0 Compare Match A
reti ;TIM0_COMPB, Timer/Counter0 Compare Match B
reti ;WDT Time-out
reti ;ADC Konvertierung komplett
;
;******** Interrupt-Routinen **********
;*** Tastenerkennung ***
tasten:
in mp,SREG
push mp
ldi mp,0 ;Timer-Interrupt abschalten
out TIMSK0,mp
pop mp
out SREG, mp
set ;setze T-Flag
reti
;
;*** Zeit für Spannungswahl ***
zeit:
in mp,SREG
push mp
dec Counter ;Zeit runterzählen
brne nochmal ;wenn runtergezählt...,
pop mp
out SREG, mp
set ;...dann T-Flag setzen
rjmp timer_finit ;und fertig
nochmal:
ldi mp,startwert ;Timer mit Startwert laden
out TCNT0,mp
sbic schaltport,a_3v ;LED blinken lassen
rjmp aus
sbi schaltport,a_3v
rjmp timer_raus
aus:
cbi schaltport,a_3v
timer_raus:
pop mp
out SREG, mp
timer_finit:
reti
;
;******** Unterprogramme **********
auswerten:
cli ;alle Interrupts
clt ;und T-Flag löschen
ldi mp,0 ;PinChange-Interrupt abschalten
out GIMSK,mp
ldi mp,0 ;Timer-Interrupt abschalten
out TIMSK0,mp
entprelle:
rcall entprellen ;Taste entprellen
rcall pause ;kurze Pause
tst key_press ;Taste schon entprellt?
breq entprelle ;nein,nochmal
mov mp,key_press ;wegen dummen Register
andi mp,t_maske ;nur Tasten maskieren
clc ;C-Flag aus
ror mp ;für erste Taste 2x rotieren
ror mp
brcc taste2 ;C gesetzt? nein,es war die andere Taste
cbi schaltport,a_6v ;6V einschalten
sbi schaltport,a_3v ;blinkende LED abschalten
rjmp ende
ret
taste2:
ror mp ;noch einmal rotieren
brcc weiter ;C gesetzt? wenn nein,Zeitablauf
cbi schaltport,a_43v ;4,3V einschalten
sbi schaltport,a_3v ;blinkende LED abschalten
rjmp ende
weiter: ;Zeit war abgelaufen, es bleibt bei 3V
cbi schaltport,a_3v ;blinkende LED ständig einschalten
ende:
ret
;
entprellen: ;Entprellroutine
in mp, keyport
com mp ;low active
eor mp, key_state
and key_ct0, mp ;reset counter
and key_ct1, mp
com key_ct0 ;count
eor key_ct1, key_ct0
and mp, key_ct0 ;input AND last counterstate
and mp, key_ct1
eor key_state, mp ;toggle state
and mp, key_state ;0-1-transition
or key_press, mp ;store key press detect
ret
;
pause: ;kurze Pause von 10ms
ldi mp, 188
loop:
dec mp
brne loop
ret
;
;******** Hauptprogramm **********
init:
ldi mp,low(RAMEND) ;der übliche Stack
out SPL,mp
ldi mp,(1<<clkpce)
out CLKPR,mp ;Vorteilerbit setzen
ldi mp,(1<<clkps3) ;Vorteiler auf 256 (Takt durch 256)
out CLKPR,mp
ldi mp,(1<<CS02)|!(1<<CS01)|(1<<CS00)
out TCCR0B,mp ;Teiler 1024 (Timertakt=36Hz=27ms)
ldi mp,startwert ;Timer mit Startwert laden
out TCNT0,mp
ldi mp,1<<TOIE0 ;Timer-Interrupt einschalten
out TIMSK0,mp
ldi mp,1<<PCIE ;PinChange-Interrupt einschalten
out GIMSK,mp
ldi mp,t_maske ;Tasten in PinChange-Maske eintragen
out PCMSK,mp
ldi mp,1<<SE ;Schlafmodus einschalten
out MCUCR,mp
ldi mp,portmaske ;Tastereingänge und Schaltausgänge
out DDRB,mp
sbi schaltport,a_3v ;Ausgänge ausschalten (PNP-Transistoren)
sbi schaltport,a_43v
sbi schaltport,a_6v
clr key_state ;Merker der Entprellroutine löschen
clr key_press
clr key_ct0
dec key_ct0
mov key_ct1, key_ct0
clt ;T-Flag löschen
ldi mp,count ;Zeitzähler laden
mov Counter,mp
sei ;Interrups freigeben
;
main:
brtc nix ;T-Flag gesetzt?
rcall auswerten ;wenn ja, auswerten
nix:
sleep ;abnicken
rjmp main
.exit ;Programmende
;
Nun mache ich die Luke endgültig zu, schaue aber gelegentlich mal rein, falls jemand was zu mäkeln hat
Lesezeichen