Pfad: Home => AVR-Übersicht => Anwendungen => UV-Belichter mit Timer
UV-Belichter

Sourcecode des UV-Belichters mit Timer ATtiny2313

;
; **********************************************
; * Timer mit ATtiny2313, quarzgetaktet        *
; * (C)2009 by http://www.avr-asm-tutorial.net *
; **********************************************
;
.nolist
.include "tn2313def.inc"
.list
;
; **********************************************
;              H a r d w a r e
; **********************************************
;              _______
;           1 /       |20
;  Reset o---|        |---o VCC
; LCD-RS o---|        |---o USCK/LCD-D7
;  LCD-E o---|   AT   |---o MISO/LCD-D6
;  XTAL1 o---|  tiny  |---o MOSI/LCD-D5
;  XTAL2 o---|  2313  |---o LCD-D4
; KEY UP o---|        |---o LCD-D3
;KEY DWN o---|        |---o LCD-D2
;KEY STA o---|        |---o LCD-D1
;    OUT o---|        |---o LCD-D0
;    GND o---|________|---o LED-OUT
;
; Keys (active on key up):
;   Up-key: 10 seconds longer
;  Dwn-key: 10 seconds shorter
;  Up-key while STA pressed: start/stop counting
;  Dwn-key while STA pressed: write cycle length
;       to EEPROM (value is read on start-up)
;
; **********************************************
;            C o n s t a n t s
; **********************************************
;
.equ fclock = 2457600 ; Xtal frequency
; Hardware depending constants
.equ pbLcdRs = 0 ; Rs-Bit LCD
.equ pbLcdE = 1 ; E-Bit LCD
.equ pbOut = 5 ; Output bit
.equ pbLed = 6 ; LED port bit
.equ pbKeyUp = 2 ; Up-key
.equ pbKeyDwn = 3 ; Down-key
.equ pbKeySta = 4 ; Start/Stop-key
;
; **********************************************
;             R e g i s t e r
; **********************************************
;
; Registers R0 ... R3 used in calculations
.def rCycL = R12 ; Cycle length, LSB
.def rCycH = R13 ; dto. MSB
.def rPwm = R14 ; Pwm-Value
.def rSreg = R15 ; save/restore SREG
.def rmp = R16 ; multi purpose register
.def rFlg = R17 ; Flag register
	.equ bSec = 0 ; second over flag
	.equ bOff = 1 ; end of time reached
	.equ bOn = 2 ; start cycle
	.equ bAct = 3 ; count cycle active
	.equ bUpd = 4 ; update cycle display
	.equ bSave = 5 ; save parameter for next start
.def rimp = R18 ; multi purpose inside ints
.def rCtrL = R24 ; LSB second counter
.def rCtrH = R25 ; MSB second counter
; X = R27:R26 = duration length
;
; ***********************************************
;  R e s e t / I n t e r r u p t - V e c t o r s
; ***********************************************
;
.cseg
.org $0000
	rjmp Main
	rjmp Int0Isr
	rjmp Int1Isr
	rjmp Tc1CptIsr ; TC1Capt
	rjmp Tc1CmpAIsr ; TC1CmpA
	reti ; TC1Ovf
	reti ; TC0Ovf
	reti ; USART-RX
	reti ; USART-UDRE
	reti ; USART-TX
	reti ; AnaComp
	reti ; PCINT
	rjmp Tc1CmpBIsr ; TC1CmpB
	reti ; TC0CmpA
	reti ; TC0CmpB
	reti ; USI-Start
	reti ; USI-Ovf
	reti ; EEP-Rdy
	reti ; WDT-Ovf
;
; **********************************************
;      I n t e r r u p t   S e r v i c e
; **********************************************
;
; Up key
Int0Isr:
	in rSreg,SREG ; save status
	sbis PIND,pbKeySta
	rjmp StartStop
	ldi rimp,10 ; add 10 seconds
	add rCycL,rimp
	ldi rimp,0
	adc rCycH,rimp
	sbr rFlg,1<<bUpd ; set update flag
	out SREG,rSreg ; restore status
	reti
; Dwn key
Int1Isr:
	in rSreg,SREG ; save status
	sbis PIND,pbKeySta
	rjmp Save
	ldi rimp,10 ; subtract 10 seconds
	sub rCycL,rimp
	ldi rimp,0
	sbc rCycH,rimp
	brcc Int1Isr1
	clr rCycH
	clr rCycL
Int1Isr1:
	sbr rFlg,1<<bUpd ; set update flag
	out SREG,rSreg ; restore status
	reti
; Start/Stop pressed
StartStop:
	sbrc rFlg,bAct
	rjmp StartStop1
	sbr rFlg,1<<bOn
	out SREG,rSreg
	reti
StartStop1:
	sbr rFlg,1<<bOff
	out SREG,rSreg
	reti
; Save par pressed
	sbr rFlg,bSave
	out SREG,rSreg
	reti
; TC1 overflow int
Tc1CptIsr:
	in rSreg,SREG ; save status
	sbr rFlg,1<<bSec ; set second flag
	sbiw rCtrL,1 ; count down
	brne Tc1CptIsr1
	sbr rFlg,1<<bOff ; End of count reached
Tc1CptIsr1:
	out SREG,rSreg ; restore status
	reti
; TC1 Compare A Int
Tc1CmpAIsr:
	cbi PORTD,pbLed ; Led green
	reti
; TC1 Compare B Int
Tc1CmpBIsr:
	sbi PORTD,pbLed ; Led red
	reti
;
; **********************************************
;      M a i n   P r o g r a m   I n i t
; **********************************************
;
Main:
	ldi rmp,1<<CLKPCE ; set CLKPR to 1
	out CLKPR,rmp
	clr rmp
	out CLKPR,rmp
	ldi rmp,LOW(RAMEND) ; Init stack
	out SPL,rmp
	; Init Output
	sbi DDRD,pbOut
	cbi PORTD,pbOut
	; Init Led output
	sbi DDRD,pbLed
	cbi PORTD,pbLed
	; Init keys
	cbi DDRD,pbKeyUp
	sbi PORTD,pbKeyUp ; pull-up up-key
	cbi DDRD,pbKeyDwn ; pull-up down-key
	sbi PORTD,pbKeyDwn
	cbi DDRD,pbKeySta ; pull-up start/stop-key
	sbi PORTD,pbKeySta
	; Clear flags
	clr rFlg
	; Init Lcd portbits
	cbi PORTD,pbLcdE ; Enable
	sbi DDRD,pbLcdE
	cbi PORTD,pbLcdRs ; RS
	sbi DDRD,pbLcdRs
	ldi rmp,0xFF ; Data
	out DDRB,rmp
	rcall LcdInit
	; Init Timer 1 second counter
	ldi rmp,HIGH(38400) ; CTC after 1 sec
	out ICR1H,rmp
	ldi rmp,LOW(38400)
	out ICR1L,rmp
	ldi rmp,HIGH(38400/2) ; Turns LED green
	out OCR1AH,rmp
	ldi rmp,LOW(38400/2)
	out OCR1AL,rmp
	ldi rmp,HIGH(3*38400/4) ; Turns LED red
	out OCR1BH,rmp
	ldi rmp,LOW(3*38400/4)
	out OCR1BL,rmp
	ldi rCtrH,HIGH(10) ; set first counter
    ldi rCtrL,LOW(10)
	rcall Read
	rcall DisplCycl
	rcall SetOff ; init counter
	; set external ints and sleep mode
	ldi rmp,(1<<SE)|(1<<ISC01)|(1<<ISC00)|(1<<ISC11)|(1<<ISC10)
	out MCUCR,rmp
	ldi rmp,(1<<INT0)|(1<<INT1) ; mask ints
	out GIMSK,rmp
	sei
Loop:
	sleep
	nop ; dummy
	sbrc rFlg,bOff ; switch off?
	rcall SetOff
	sbrc rFlg,bOn ; switch on?
	rcall SetOn
	sbrc rFlg,bSec
	rcall SetSec
	sbrc rFlg,bUpd ; update cycle length?
	rcall Update
	sbrc rFlg,bSave ; save parameter?
	rcall Save
	rjmp Loop
; End of cycle reached
SetOff:
	cbr rFlg,1<<bOff ; clear flag
	cbi PORTD,pbOut ; set Out Off
	clr rmp
	out OCR0B,rmp ; clear timer compare
	cbi PORTD,pbLed ; set Led Off
	ldi rmp,0 ; set mode CTC
	out TCCR1A,rmp
	ldi rmp,(1<<WGM13)|(1<<WGM12) ; set timer off
	out TCCR1B,rmp
	ldi rmp,0 ; disable timer ints
	out TIMSK,rmp
	cbr rFlg,1<<bAct ; clear active flag
	ret
; Set cycle on
SetOn:
	cbr rFlg,1<<bOn ; clear flag
	sbi PORTD,pbOut
	mov rCtrH,rCycH ; set timer duration
	mov rCtrL,rCycL
	ldi rmp,0 ; clear timer 1
	out TCNT1H,rmp
	out TCNT1L,rmp
	ldi rmp,0 ; set mode CTC
	out TCCR1A,rmp
	ldi rmp,(1<<WGM13)|(1<<WGM12)|(1<<CS11)|(1<<CS10) ; set pre 64
	out TCCR1B,rmp
	ldi rmp,(1<<ICIE1)|(1<<OCIE1A)|(1<<OCIE1B) ; enable capture int
	out TIMSK,rmp
	sbi PORTD,pbLed ; LED red
	sbr rFlg,1<<bAct ; set active flag
	rjmp DisplTime ; display time
; Update cycle length display
Update:
	cbr rFlg,1<<bUpd ; clear flag
	rjmp DisplCycl
; End of second reached
SetSec:
	cbr rFlg,1<<bSec ; clear flag
	rjmp DisplTime
; Save parameter
Save:
	cbr rFlg,1<<bSave
	ldi rmp,0x40 ; write to 0040
	out EEAR,rmp
	cli
	out EEDR,rCycL ; write low byte
	sbi EECR,EEMPE
	sbi EECR,EEPE
	sei
Save1:
	sbic EECR,EEPE
	rjmp Save1
	ldi rmp,0x41 ; write to 0041
	out EEAR,rmp
	cli
	out EEDR,rCycH ; write high byte
	sbi EECR,EEMPE
	sbi EECR,EEPE
	sei
Save2:
	sbic EECR,EEPE
	rjmp Save2
	ret
; Read parameter
Read:
	ldi rmp,0x40 ; read from Adress 0040
	out EEAR,rmp
	ldi rmp,1<<EERE ; read strobe
	out EECR,rmp
	in rCycL,EEDR ; read low byte
	ldi rmp,0x41
	out EEAR,rmp
	ldi rmp,1<<EERE
	out EECR,rmp
	in rCycH,EEDR
	ldi rmp,0x00
	out EEAR,rmp
	ret
;
; **********************************************
;    C a l c u l a t i o n   r o u t i n e s
; **********************************************
;
DisplTime:
	ldi rmp,0xCA ; Display on line 2, col. 11
	mov R0,rCtrL ; Time to R1:R0
	mov R1,rCtrH
	rjmp Displ
;
DisplCycl:
	ldi rmp,0x8A ; Display on line 1, col. 11
	mov R0,rCycL ; Cycle length to R1:R0
	mov R1,rCycH
Displ:
	cbi PORTD,pbLcdRs ; control
	out PORTB,rmp ; set display position
	rcall LcdE
	rcall LcdDel40
	sbi PORTD,pbLcdRs ; set display chars
	clr ZH ; set 60 seconds
	ldi ZL,60
	clr R2
Displ1:
	cp R0,ZL ; compare
	cpc R1,ZH
	brcs Displ2
	sub R0,ZL
	sbc R1,ZH
	inc R2
	rjmp Displ1
Displ2:
	rcall Displ3
	ldi rmp,':'
	out PORTB,rmp
	rcall LcdE
	rcall LcdDel40
	mov R2,R0
Displ3:
	clr R1
	ldi rmp,10
Displ4:
	cp R2,rmp
	brcs Displ5
	sub R2,rmp
	inc R1
	rjmp Displ4
Displ5:
	ldi rmp,'0'
	add rmp,R1
	out PORTB,rmp
	rcall LcdE
	rcall LcdDel40
	ldi rmp,'0'
	add rmp,R2
	out PORTB,rmp
	rcall LcdE
	rjmp LcdDel40
;
; **********************************************
;          L C D - R o u t i n e s
; **********************************************
;
LcdInit:
	rcall LcdDel4500 ; delay 4,5 ms
	cbi PORTD,pbLcdRs ; clear RS
	ldi rmp,0x38 ; Setze 8 bit interface, 2 Zeilen
	out PORTB,rmp ; to data output
	rcall LcdE
	rcall LcdDel4100 ; wait 4100 µs
	rcall LcdE
	rcall LcdDel100 ; wait 100 µs
	rcall LcdE
	rcall LcdDel100 ; wait 100 µs
	ldi rmp,0x08 ; Display off
	out PORTB,rmp
	rcall LcdE
	rcall LcdDel40 ; wait 40 µs
	ldi rmp,0x01 ; clear Display
	out PORTB,rmp
	rcall LcdE
	rcall LcdDel4500 ; wait 4,5 ms
	ldi rmp,0x06 ; input mode insert, no Shift
	out PORTB,rmp
	rcall LcdE
	rcall LcdDel40
	ldi rmp,0x10 ; Display Cursor Shift
	out PORTB,rmp
	rcall LcdE
	rcall LcdDel40 ; wait 40 µs
	ldi rmp,0x02 ; Display/Cursor Home
	out PORTB,rmp
	rcall LcdE
	rcall LcdDel1640 ; wait 1,64 ms
	ldi rmp,0x0F ; Display active, Cursor on, blink
	out PORTB,rmp
	rcall LcdE
	rcall LcdDel40 ; wait 40 µs
	sbi PORTD,pbLcdRs
	ldi ZH,HIGH(2*LcdText1)
	ldi ZL,LOW(2*LcdText1)
	rcall LcdWriteZ
	ldi rmp,250
LcdInit1:
	rcall LcdDel10000
	dec rmp
	brne LcdInit1
	ldi ZH,HIGH(2*LcdText2)
	ldi ZL,LOW(2*LcdText2)
LcdWriteZ:
	cbi PORTD,pbLcdRs
	ldi rmp,0x80
	out PORTB,rmp
	rcall LcdE
	sbi PORTD,pbLcdRs
LcdWriteZ1:
	push ZH
	push ZL
	rcall LcdDel40
	pop ZL
	pop ZH
	lpm
	adiw ZL,1
	tst R0
	breq LcdWriteZ3
	ldi rmp,0x0A
	cp R0,rmp
	brne LcdWriteZ2
	cbi PORTD,pbLcdRs
	ldi rmp,0xC0
	out PORTB,rmp
	rcall LcdE
	sbi PORTD,pbLcdRs
	rjmp LcdWriteZ1
LcdWriteZ2:
	out PORTB,R0
	rcall LcdE
	rjmp LcdWriteZ1
LcdWriteZ3:
	rjmp LcdDel100
;
LcdText1:
.db "Timer ATtiny2313 DG4FAC",0x00
LcdText2:
.db "Max.time= 00:00 seconds",0x0A,"Resttime= 00:00 seconds",0x00
;
LcdE:
	sbi PORTD,pbLcdE ; set enable LCD
	nop ; delay four clock cycles
	nop
	nop
	nop
	cbi PORTD,pbLcdE ; clear enable LCD
	ret
;
; Delay Routines for 2457600 MHz
;
LcdDel10000:
.equ nt10000 = (5 * 10000 - 16) / 8
	ldi ZH,HIGH(nt10000)
	ldi ZL,LOW(nt10000)
	rjmp LcdDelZ
LcdDel4500:
.equ nt4500 = (5 * 4500 - 16) / 8
	ldi ZH,HIGH(nt4500)
	ldi ZL,LOW(nt4500)
	rjmp LcdDelZ
LcdDel4100:
.equ nt4100 = (5 * 4100 - 16) / 8
	ldi ZH,HIGH(nt4100)
	ldi ZL,LOW(nt4100)
	rjmp LcdDelZ
LcdDel1640:
.equ nt1640 = (5 * 1640 - 16) / 8
	ldi ZH,HIGH(nt1640)
	ldi ZL,LOW(nt1640)
	rjmp LcdDelZ
LcdDel100:
.equ nt100 = (5 * 100 - 16) / 8
	ldi ZH,HIGH(nt100)
	ldi ZL,LOW(nt100)
	rjmp LcdDelZ
LcdDel40:
.equ nt40 = (5 * 40 - 16) / 8
	ldi ZH,HIGH(nt40)
	ldi ZL,LOW(nt40)
	nop
	nop
LcdDelZ:
	sbiw ZL,1
	brne LcdDelZ
	ret
;
; EEPROM segment
;
.ESEG
.ORG 0x0040
.DW 180
;
; End of source code
;


©2009 by http://www.avr-asm-tutorial.net