Das ASM-File zum Download gibts hier, fertig programmierte Controller auf Anfrage.
Das Programm selbst ist recht einfach, aber es verwendet eine Reihe von Techniken, welche auch in grösseren Projekten benötigt werden, z.B.
Lesen und Schreiben des EEPROMs
Timer-Interrupt
Software-Counter
In der Hauptroutine des Programms wird lediglich das PWM Signal erzeugt. Über den Timer Interrupt wird der Taster abgefragt und je nach Taster-Status die Helligkeit geändert bzw. der Dimmer ein / ausgeschaltet.
Dabei sind folgende Funktionen impementiert:
Taster kurz drücken (Als Eingang für einen Taster dient PB0,die LED's werden an PB1 und PB2 angeschlossen)
Die LED's werden EIN bzw. AUS geschaltet.
wurde vorher die Helligkeit geändert, wird der neue Wert dauerhaft abgespeichert.
Taster lange drücken:
Die Helligkeit ändert sich langsam von 0 auf 100% und zurück. ist die gewünschte Helligkeit erreicht, Taster wieder loslassen. Die Helligkeit ändert sich dabei nicht linear, sondern in mehreren Geschwindigkeiten, um der logarithmischen Empfindlichkeit des Auges gerecht zu werden.
Taster während dem RESET gedrückt halten:
Damit kann festgelegt werden, ob die LED's nach einem Reset an oder aus sind.
Das Programm wurde mit AVR Studio 4.10 erstellt.
Beim Programmieren bitte den OSCCAL-Wert in die EEPROM-Zelle $3f speichern!
;;Dimmer Soft ON/OFF
;(c) 2004 Markus Vohburger
;Gewerbliche Nutzung untersagt!
;Definitionen für Tiny12 Laden
.include "tn12def.inc"
.def temp1 = r16
.def temp2 = r17
.def output = r18
.def swcount0 = r19
.def output = r20
.def pwmcount = r21
.def swcount1 = r22
.def conbuf = r23
.def direction = r25
.def control=r26
.def pwmvalue = r27
.def dirty = r28
.def onoff = r29
.EQU EE_OSCCAL = $3f;
;reset handler
.org $0000
rjmp main
;timer overflow interrut handler
.org OVF0Addr
rjmp OVF0Handler
.org $0010
main:
;stack setup
;read osccal byte
ldi temp1,EE_OSCCAL
rcall readeeprom
out osccal,temp1
;port setup
;port b input with pullups
ldi temp1,$01e
out ddrb,temp1
;port b output off, pullups on
ldi temp1,$1f
out portb,temp1
ldi temp1,$1e
out ddrb,temp1
;Einstellungen aus EEProm laden
ldi temp1,$00
rcall readsettings
mov conbuf,temp1
ldi direction,$00
ldi dirty,$00
ldi temp1,$01
rcall readeeprom
mov onoff,temp1
andi onoff,$01
;Dimmer An/Aus nach Reset umschalten, wenn Taste gedrückt
sbic pinb,0
rjmp notoggle
ldi temp1,$01
eor onoff,temp1
;ins EEProm schreiben
waittoggle:
sbic eecr,eewe
rjmp waittoggle
out eedr,onoff
sbi eecr,eemwe
sbi eecr,eewe
notoggle:
;
;Timer zurücksetzen
ldi temp1,$00
out tcnt0,temp1
;Timer interrupts an
ldi temp1,(1
<<toie0) out timsk,temp1
;Timer starten
ldi temp1,$03
out tccr0,temp1
ldi swcount0, $00
ldi swcount1,$00
ldi pwmcount,$00
ldi pwmvalue,$00
sei
;Hauptprogrammschleife, macht nur PWM
loop:
;leds aus
ldi output,$1f
cp pwmcount,pwmvalue
brsh writeoutput
;leds an
ldi output,$01
writeoutput:
out portb,output
inc pwmcount
rjmp loop
;Timer Interrupt Handler
OVF0Handler:
;Status sichern
in r1,sreg
;SoftON bzw. Off abhandeln
mov control,conbuf
cpi onoff,$01
breq nooff
ldi control,$00
nooff:
cp pwmvalue,control
breq endcontrol
brlo doinc
dec pwmvalue
rjmp endcontrol
doinc:
inc pwmvalue
;wenn taster gedrückt, dann pressedhandler
endcontrol:
sbis pinb,0
rjmp pressedhandler
;war taster zu kurz gedrückt?
cpi swcount0,$02
brlo exitreleasehandler
;helligkeit wurde geändert
cpi swcount0,$1f
brsh exitreleasehandler
;turn on / Off
;und einstellungen abspeichern
ldi temp1,$01
eor onoff,temp1
rcall writesettings
rjmp exitreleasehandler
exitreleasehandler:
ldi swcount0,$00
exit_ovf0Handler:
out sreg,r1
reti
;zähler nur bis zum maximum erhöhen
pressedhandler:
cpi swcount0,$20
brsh noinc
inc swcount0
noinc:
cpi swcount0,$20
brlo exit_ovf0handler
inc swcount1
cpi swcount1,$08
brne exit_ovf0handler
clr swcount1
rcall updown
rjmp exit_ovf0handler
;Änderungsgeschwindigkeit je nach Helligkeit anpassen
updown:
mov pwmvalue,conbuf
;merken, dass sich was geändert hat
ldi dirty,$ff
;heller oder dunkler werden ?
sbrs direction,0
rjmp uphandler
ldi temp1,$01
cpi conbuf,$f0
brsh more1
ldi temp1,$02
cpi conbuf,$e8
brsh more1
ldi temp1,$08
more1:
clc
sub conbuf,temp1
brcc exitsub
ldi conbuf,$00
cbr direction,1
rjmp exitsub
uphandler:
ldi temp1,$01
cpi conbuf,$f0
brsh more2
ldi temp1,$02
cpi conbuf,$e8
brsh more2
ldi temp1,$08
more2:
clc
add conbuf,temp1
brcc exitsub
ldi conbuf,$ff
sbr direction,1
exitsub:
ret
;die aktuelle helligkeit aus EEprom lesen
readsettings:
ldi temp1,$00
rcall readeeprom
mov conbuf,temp1
ret
writesettings:
;eeprom-Schonen!
;nur schreiben, wenn sich was geändert hat
.. .. .. Den Vollständigen Quellcode gibts hier zum Download, |