Pfad: Home =>
AVR-Übersicht =>
Anwendungen =>
Eieruhr => Assembler-Quellcode Version 3
; ***************************************************
; * Eieruhr mit ATtiny2313, Version 3 mit Tonleiter *
; * und Haenschen-Klein-Eroeffnung *
; * (C)2009 by info@avr-asm-tutorial.net *
; ***************************************************
;
.NOLIST
.INCLUDE "tn2313def.inc"
.LIST
;
;
; ***************************************
; Fuses-Voreinstellungen im ATtiny2313V
; ***************************************
;
; - Internen RC-Oszillator auf 4 MHz, CLKSEL3:0 = 0010, SUT1:0 = 10
; - Interner Clockteiler auf 8, CKDIV8 = Enabled
; - Der interne Clockteiler von 8 wird durch Setzen von CLKPR
; bei der Initiierung mit 2 ueberschrieben
;
; ***************************************
; Hardware - Schaltung
; ***************************************
;
; __________
; / |_| |
; +3V O--|Res VCC|--O +3V
; | |
; L1K O--|PD0 PB7|--O L10A + USCK
; | |
;L1A/L2K O--|PD1 PB6|--O L9A/L10K + MISO
; | AT |
; O--|PA1 PB5|--O L8A/L9K + MOSI
; | tiny |
; O--|PA0 PB4|--O L7A/L8K
; | 2313 |
;L2A/L3K O--|PD2 PB3|--O
; | V |
;L4K/L3A O--|PD3 PB2|--||--O Lsp
; | (OC0A)|
;L5K/L4A O--|PD4 PB1|--O
; | |
;L6K/L5A O--|PD5 PB0|--O L0K
; | |
; GND O--|GND PD6|--O L6A/L7K
; |___________|
;
;
; ***************************************
; Definiere Ports und Portbits
; ***************************************
;
.EQU iOcO = PINB
.EQU pOcO = PORTB
.EQU dOcO = DDRB
.EQU bOcO = 2
;
.EQU pL0K = PORTB
.EQU dL0K = DDRB
.EQU bL0K = 0
;
.EQU pL1K = PORTD
.EQU dL1K = DDRD
.EQU bL1K = 0
;
.EQU pL1A = PORTD
.EQU dL1A = DDRD
.EQU bL1A = 1
;
.EQU pL2K = PORTD
.EQU dL2K = DDRD
.EQU bL2K = 1
;
.EQU pL2A = PORTD
.EQU dL2A = DDRD
.EQU bL2A = 2
;
.EQU pL3K = PORTD
.EQU dL3K = DDRD
.EQU bL3K = 2
;
.EQU pL3A = PORTD
.EQU dL3A = DDRD
.EQU bL3A = 3
;
.EQU pL4K = PORTD
.EQU dL4K = DDRD
.EQU bL4K = 3
;
.EQU pL4A = PORTD
.EQU dL4A = DDRD
.EQU bL4A = 4
;
.EQU pL5K = PORTD
.EQU dL5K = DDRD
.EQU bL5K = 4
;
.EQU pL5A = PORTD
.EQU dL5A = DDRD
.EQU bL5A = 5
;
.EQU pL6K = PORTD
.EQU dL6K = DDRD
.EQU bL6K = 5
;
.EQU pL6A = PORTD
.EQU dL6A = DDRD
.EQU bL6A = 6
;
.EQU pL7K = PORTD
.EQU dL7K = DDRD
.EQU bL7K = 6
;
.EQU pL7A = PORTB
.EQU dL7A = DDRB
.EQU bL7A = 4
;
.EQU pL8K = PORTB
.EQU dL8K = DDRB
.EQU bL8K = 4
;
.EQU pL8A = PORTB
.EQU dL8A = DDRB
.EQU bL8A = 5
;
.EQU pL9K = PORTB
.EQU dL9K = DDRB
.EQU bL9K = 5
;
.EQU pL9A = PORTB
.EQU dL9A = DDRB
.EQU bL9A = 6
;
.EQU pL10K = PORTB
.EQU dL10K = DDRB
.EQU bL10K = 6
;
.EQU pL10A = PORTB
.EQU dL10A = DDRB
.EQU bL10A = 7
;
.EQU pLRot = PORTB
.EQU dLRot = DDRB
.EQU bLRot = 0
;
; ***************************************
; Funktionsweise Timing
; ***************************************
;
; Timer1 = Zeitmessung
; _______ ______ ______ ______ _____ ______
; |RC-Osc.| | CDiv | 2 |Presc.|250 |TC1CNT|5Hz| LED |0,5|MinCnt|
; | 4 MHz |===>| / 2 |==>| / 1 |===>|/50000|==>|Count|==>| / 30 |==>1 Min.
; |_______| |______|MHz|______|kHz |______| |_____|Hz |______|
; |
; Timer0 = NF-Erzeugung|
; | ______ ______
; | |Presc.| | CTC0 |1046-2794 Hz
; |=>| / 1 |==>|/Tontl|===> OC0A = Beep-Lautsprecher
; |______| |______|
;
;
; ***************************************
; Register
; ***************************************
;
.DEF rmp = R16 ; Multipurpose-Register
.DEF rLmp = R17 ; Lampenzaehler
.DEF rSec = R18 ; Sekundenzaehler
.DEF rMin = R19 ; Minuten-Zaehler
.DEF rFlg = R20 ; Flag-Register
.EQU fs = 0 ; Beginn-Melodie-Flagge
; benutzt XH:XL fuer Melodie zu Beginn
; benutzt ZH:ZL fuer Tonleiter
;
; ***************************************
; Reset und Interrupt-Vektoren
; ***************************************
;
.CSEG
.ORG $0000
rjmp Main ; Reset
reti ; INT0 Interrupt
reti ; INT1 Interrupt
reti ; TC1Capt Interrupt
rjmp TC1CmpA ; Timer 1 Compare A match
reti ; TC1 Overflow Int
reti ; TC0 Overflow Int
reti ; UART0 RX Int
reti ; UART0 TX Int
reti ; Ana Comp Int
reti ; PCINT
reti ; TC1 CompB Int
reti ; TC0 Compare Match A Int
reti ; TC0 Compare Match B Int
reti ; USISTART Int
reti ; USIOverflow Int
reti ; EERDY Int
reti ; WDT Overflow Int
;
; ***************************************
; TC1 Compare Match A Interrupt Routine
; ***************************************
;
TC1CmpA:
set
reti
;
; ***************************************
; Subroutinen
; ***************************************
;
; Setze den Ton auf die Tonleiter-Tabelle
;
Ton:
mov rmp,rMin ; kopiere Minutenzaehler
cpi rmp,12 ; Innerhalb der Tabelle
brcs Ton1 ; ja, keine Korrektur
ldi rmp,11 ; korrigiere
Ton1:
ldi ZH,HIGH(2*Tonleiter) ; Z zeigt auf Tabelle im Flash
ldi ZL,LOW(2*Tonleiter)
add ZL,rmp ; zeige auf Ton
brcc Ton2 ; kein Ueberlauf
inc ZH ; Ueberlauf in das MSB des Zeiges
Ton2:
lpm ; Lese Teiler fuer Ton aus dem Flash
out OCR0A,R0 ; schreibe Tabellenwert in Compare Register A
lsr R0 ; halbiere den Tabellenwert
out OCR0B,R0 ; halben Tabellenwert in Compare Register B
ret ; fertig
;
Tonleiter:
.DB 237,210,189,178,157,142,126,118,105,95,89,79
; Haenschen klein
mtab:
.db 6,0,4,0,4,0,0,5,0,3,0,3,0,0,2,0,3,0,4,0,5,0
.db 6,0,6,0,6,0,0,6,0,4,0,4,0,0,5,0,3,0,3,0
.db 2,0,4,0,6,0,6,0,2,0,0,0,0,3,0,3,0,3,0,3,0,3
.db 0,4,0,5,0,4,0,4,0,4,0,4,0,4,0,5,0,6,0,6
.db 0,4,0,4,0,0,5,0,3,0,3,0,2,0,4,0,6,0,6,0,1,0
.db 0,0xFF
;
; ***************************************
; Hauptprogramm
; ***************************************
;
Main:
; Stack init
ldi rmp,LOW(RAMEND) ; Setze Stackpointer
out SPL,rmp
; setze CLKPR auf 2 MHz
ldi rmp,1<<CLKPCE ; Clock prescaler change enable Bit setzen
out CLKPR,rmp
ldi rmp,4 ;1<<CLKPS1 ; Prescaler auf 2
out CLKPR,rmp
; Initiierung der Register
clr rLmp ; Loesche Lampenzaehler
clr rSec ; Loesche Sekundenzaehler
clr rMin ; Loesche Minutenzaehler
; Init LED-Ausgabe
cbi dLRot,bLRot ; Rote Lampe aus
; Init 8-Bit-Timer 0 fuer Ton-Ausgabe
sbr rFlg,1<<fs ; Setze Flag Beginn-Melodie
ldi XH,HIGH(2*mtab); Setze Anfang Beginn-Melodie
ldi XL,LOW(2*mtab)
ldi rmp,(1<<COM0A0)|(1<<WGM01) ; CTC, Compare A
out TCCR0A,rmp
ldi rmp,1<<CS00 ; Timer Prescaler = 1, Timer an
out TCCR0B,rmp
; Init OC0A-Portausgang fuer Lautsprecher
sbi dOcO,bOcO
; Init Timer 1 fuer Zeit- und Lampensteuerung
ldi rmp,HIGH(50000) ; CTC-Wert
out OCR1AH,rmp
ldi rmp,LOW(50000)
out OCR1AL,rmp
clr rmp ; Kontrollwort A
out TCCR1A,rmp
ldi rmp,(1<<WGM12)|(1<<CS10) ; auf CTC, Teiler = 1
out TCCR1B,rmp
ldi rmp,1<<OCIE1A ; Timer1-Interrupt
out TIMSK,rmp
; set sleep mode enable
ldi rmp,1<<SE ; sleep idle
out MCUCR,rmp
sei ; Enable Ints
; Hauptprogramm-Loop
loop:
sleep ; schlafen legen
nop ; dummy
brtc loop ; kein Timer1-Interrupt
clt ; loesche Flag
sbrc rFlg,fs ; Beginn-Melodie?
rcall Beginn
sbrc rFlg,fs
rjmp Loop1
ldi rmp,0
out TCCR0B,rmp
Loop1:
rcall LampOff
inc rLmp ; Erhoehe Lampenzaehler
rcall LampOn
cpi rLmp,10 ; Lampenzaehler bei Zehn?
brcs loop
clr rLmp
rcall LampOn
inc rSec
cpi rSec,30
brcs loop
clr rSec
sbrc rFlg,fs
rjmp Loop2
rcall Ton
ldi rmp,1<<CS00 ; Timer Prescaler = 1, Timer an
out TCCR0B,rmp
Loop2:
inc rMin
cpi rMin,10
brcs loop
sbi dLRot,bLRot ; rote Overflow-Lampe an
cbi pLRot,bLRot
sbrc rFlg,fs
rjmp Loop
sbr rFlg,fs ; Beginn-Melodie an
ldi XH,HIGH(2*mtab)
ldi XL,LOW(2*mTab)
rjmp loop
;
; *******************************
; Melodie zu Beginn ausgeben
; *******************************
;
Beginn:
mov ZH,XH ; lade naechsten Ton
mov ZL,XL
adiw XL,1 ; naechster Ton
lpm
mov rmp,R0 ; kopiere nach rmp
cpi rmp,0xFF ; Letzte Note?
brne Beginn2
cbr rFlg,1<<fs ; Beginn-Melodie aus
Beginn1:
clr rmp ; Ton aus
out TCCR0B,rmp
ret
Beginn2:
subi rmp,1 ; Null-Ton?
brcs Beginn1 ; ja, Ton aus
ldi ZH,HIGH(2*Tonleiter) ; Ton aus Tonleiter
ldi ZL,LOW(2*Tonleiter)
add ZL,rmp ; addiere Ton
ldi rmp,0
adc ZH,rmp
lpm
out OCR0A,R0 ; an OCR0A
lsr R0 ; halbieren
out OCR0B,R0 ; an OCR0B
ldi rmp,1<<CS00 ; Ton an
out TCCR0B,rmp
ret
;
; ***************************************
; LED - Schalten
; ***************************************
;
; Schalte aktuelle Lampe aus
;
LampOff:
ldi ZH,HIGH(TabAus) ; LED ausschalten
ldi ZL,LOW(TabAus)
add ZL,rLmp ; aktuelle LED addieren
brcc LampOff1
inc ZH
LampOff1:
ijmp ; aktuelle LED deaktivieren
;
; Schalte aktuelle Lampe an
;
LampOn:
cp rLmp,rMin ; aktuelle Lampe < Minuten?
brcc LampGn ; >= Minute, Lampe gruen
ldi ZH,HIGH(TabRot) ; Lampe rot
ldi ZL,LOW(TabRot)
add ZL,rLmp ; aktuelle LED addieren
brcc LampOn1
inc ZH
LampOn1:
ijmp ; aktuelle LED aktivieren
LampGn:
ldi ZH,HIGH(TabGruen) ; Lampe gruen
ldi ZL,LOW(TabGruen)
add ZL,rLmp ; aktuelle LED addieren
brcc LampGn1
inc ZH
LampGn1:
ijmp ; aktuelle LED aktivieren
;
; ***************************************
; Sprungtabellen
; ***************************************
;
; Sprungtabelle der Lampen-Routinen fuer Ausschalten
TabAus:
rjmp L1A
rjmp L2A
rjmp L3A
rjmp L4A
rjmp L5A
rjmp L6A
rjmp L7A
rjmp L8A
rjmp L9A
rjmp L10A
ret ; dummies
ret
ret
; Sprungtabelle der Lampen-Routinen fuer Rot
TabRot:
rjmp L1R
rjmp L2R
rjmp L3R
rjmp L4R
rjmp L5R
rjmp L6R
rjmp L7R
rjmp L8R
rjmp L9R
rjmp L10R
ret ; dummies
ret
ret
; Sprungtabelle der Lampen-Routinen fuer Gruen
TabGruen:
rjmp L1G
rjmp L2G
rjmp L3G
rjmp L4G
rjmp L5G
rjmp L6G
rjmp L7G
rjmp L8G
rjmp L9G
rjmp L10G
ret ; dummies
ret
ret
;
; ***************************************
; Lampen - Schaltroutinen
; ***************************************
;
; Lampen ausschalten
L1A:
cbi pL1A,bL1A
cbi pL1K,bL1K
cbi dL1A,bL1A
cbi dL1K,bL1K
ret
L2A:
cbi pL2A,bL2A
cbi pL2K,bL2K
cbi dL2A,bL2A
cbi dL2K,bL2K
ret
L3A:
cbi pL3A,bL3A
cbi pL3K,bL3K
cbi dL3A,bL3A
cbi dL3K,bL3K
ret
L4A:
cbi pL4A,bL4A
cbi pL4K,bL4K
cbi dL4A,bL4A
cbi dL4K,bL4K
ret
L5A:
cbi pL5A,bL5A
cbi pL5K,bL5K
cbi dL5A,bL5A
cbi dL5K,bL5K
ret
L6A:
cbi pL6A,bL6A
cbi pL6K,bL6K
cbi dL6A,bL6A
cbi dL6K,bL6K
ret
L7A:
cbi pL7A,bL7A
cbi pL7K,bL7K
cbi dL7A,bL7A
cbi dL7K,bL7K
ret
L8A:
cbi pL8A,bL8A
cbi pL8K,bL8K
cbi dL8A,bL8A
cbi dL8K,bL8K
ret
L9A:
cbi pL9A,bL9A
cbi pL9K,bL9K
cbi dL9A,bL9A
cbi dL9K,bL9K
ret
L10A:
cbi pL10A,bL10A
cbi pL10K,bL10K
cbi dL10A,bL10A
cbi dL10K,bL10K
ret
; Lampe auf Gruen
L1G:
sbi pL1A,bL1A
cbi pL1K,bL1K
sbi dL1A,bL1A
sbi dL1K,bL1K
ret
L2G:
sbi pL2A,bL2A
cbi pL2K,bL2K
sbi dL2A,bL2A
sbi dL2K,bL2K
ret
L3G:
sbi pL3A,bL3A
cbi pL3K,bL3K
sbi dL3A,bL3A
sbi dL3K,bL3K
ret
L4G:
sbi pL4A,bL4A
cbi pL4K,bL4K
sbi dL4A,bL4A
sbi dL4K,bL4K
ret
L5G:
sbi pL5A,bL5A
cbi pL5K,bL5K
sbi dL5A,bL5A
sbi dL5K,bL5K
ret
L6G:
sbi pL6A,bL6A
cbi pL6K,bL6K
sbi dL6A,bL6A
sbi dL6K,bL6K
ret
L7G:
sbi pL7A,bL7A
cbi pL7K,bL7K
sbi dL7A,bL7A
sbi dL7K,bL7K
ret
L8G:
sbi pL8A,bL8A
cbi pL8K,bL8K
sbi dL8A,bL8A
sbi dL8K,bL8K
ret
L9G:
sbi pL9A,bL9A
cbi pL9K,bL9K
sbi dL9A,bL9A
sbi dL9K,bL9K
ret
L10G:
sbi pL10A,bL10A
cbi pL10K,bL10K
sbi dL10A,bL10A
sbi dL10K,bL10K
ret
; Lampe auf Rot
L1R:
cbi pL1A,bL1A
sbi pL1K,bL1K
sbi dL1A,bL1A
sbi dL1K,bL1K
ret
L2R:
cbi pL2A,bL2A
sbi pL2K,bL2K
sbi dL2A,bL2A
sbi dL2K,bL2K
ret
L3R:
cbi pL3A,bL3A
sbi pL3K,bL3K
sbi dL3A,bL3A
sbi dL3K,bL3K
ret
L4R:
cbi pL4A,bL4A
sbi pL4K,bL4K
sbi dL4A,bL4A
sbi dL4K,bL4K
ret
L5R:
cbi pL5A,bL5A
sbi pL5K,bL5K
sbi dL5A,bL5A
sbi dL5K,bL5K
ret
L6R:
cbi pL6A,bL6A
sbi pL6K,bL6K
sbi dL6A,bL6A
sbi dL6K,bL6K
ret
L7R:
cbi pL7A,bL7A
sbi pL7K,bL7K
sbi dL7A,bL7A
sbi dL7K,bL7K
ret
L8R:
cbi pL8A,bL8A
sbi pL8K,bL8K
sbi dL8A,bL8A
sbi dL8K,bL8K
ret
L9R:
cbi pL9A,bL9A
sbi pL9K,bL9K
sbi dL9A,bL9A
sbi dL9K,bL9K
ret
L10R:
cbi pL10A,bL10A
sbi pL10K,bL10K
sbi dL10A,bL10A
sbi dL10K,bL10K
ret
;
; Ende des Quellcodes
;
An den Seitenanfang
©2009 by http://www.avr-asm-tutorial.net