;********************************************************************************************** ; Autor: Sven Stoecker ; V 0.1 2004-03-20 : Nixie Clock; Treiber fuer 74141 ;********************************************************************************************** .include "4433def.inc" ;********************************************************************************************** ; Belegung der Ports ;********************************************************************************************** ; PORTB0 Nixie1 D0 Stunden HI ; PORTB1 Nixie1 D1 ; PORTB2 Nixie1 D2 ; PORTB3 Nixie1 D3 / Prog ; PORTB4 DCF / Prog ; PORTB5 Taster / Prog ; PORTC0 Nixie2 D0 Minuten HI ; PORTC1 Nixie2 D1 ; PORTC2 Nixie2 D2 ; PORTC3 Nixie2 D3 ; PORTC4 Doppelpunkt ; PORTC5 LED ; PORTD0 Nixie3 D0 Stunden LO ; PORTD1 Nixie3 D1 ; PORTD2 Nixie3 D2 ; PORTD3 Nixie3 D3 ; PORTD4 Nixie4 D0 Minuten LO ; PORTD5 Nixie4 D1 ; PORTD6 Nixie4 D2 ; PORTD7 Nixie4 D3 ;******************************************************************************* ; Variablen und Zuweisungen ;******************************************************************************* .def temp = r16 ; temporary variable .def temp2 = r17 ; temporary variable .def temp3 = r18 ; temporary variable .equ Korrekt = 4500 ; sec bis zum auslassen einer sec ;********************************************************************************************** ; Belegung des SRAMS ;********************************************************************************************** .equ secLO =0x65 .equ secHI =0x64 .equ minLO =0x63 .equ minHI =0x62 .equ hLO =0x61 .equ hHI =0x60 ;********************************************************************************************** ; Beginn des Codesbereiches ;********************************************************************************************** .cseg .org $0000 ;********************************************************************************************** ; Interupt-Sprungtabelle ;********************************************************************************************** rjmp Start ; RESET reti ; IRQ0 reti ; IRQ1 reti ; TIMER1 CAPT reti ; TIMER1 COMP rjmp sekunde ; TIMER1 OVF reti ; TIMER0 OVF reti ; SPI, STC reti ; UART, RX reti ; UART, UDRE reti ; UART, TX reti ; ADC reti ; EE_RDY reti ; ANA_COMP ;********************************************************************************************** ; Korrekturtabelle fuer Nixieansteuerung ;********************************************************************************************** Korrektur: .db 0x03,0x04,0x07,0x08,0x06,0x00,0x02,0x09 .db 0x05,0x01,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a ;********************************************************************************************** ; jetzt kommen die Interuptroutinen ;********************************************************************************************** sekunde: push temp ; temp sichern in temp,SREG ; SREG holen und push temp ; sichern ldi temp,6 ; Zaehlerstart out TCNT1H,temp ; H setzen clr temp ; L setzen out TCNT1L,temp ; und jetzt uebernehmen ldi temp,0x0f out DDRB,temp ; Taster auf Eingang in temp,PINB ; Taster Stunde? sbrs temp,5 rjmp plusstunde ; ja --> in temp,PINB ; Taster min? sbrs temp,4 rjmp plusminute ; ja --> clr temp subi YL,1 ; Ganggenauigkeit Korrektur sbc YH,temp brbc 0,plussekunde ; schon faellig? nein ---> ldi YH,high(Korrekt) ; neu starten ldi YL,low(Korrekt) rjmp A9 ; keine sec erhoehen ;********************************************************************************************** ; Erhoehen der Zeit ;********************************************************************************************** plussekunde: lds temp,secLO ; hole sekunden einer inc temp ; +1 cpi temp,10 ; schon 10 brbs 1,A1 ; ja sts secLO,temp ; nein ret A1: clr temp sts secLO,temp lds temp,secHI ; hole sekunden zehner inc temp ; +1 cpi temp,6 ; schon 6 brbs 1,A2 ; nein sts secHI,temp ; nein ret A2: clr temp sts secHI,temp plusminute: lds temp,minLO ; hole min einer inc temp ; +1 cpi temp,10 ; schon 10 brbs 1,A3 ; ja sts minLO,temp ; nein rjmp A8 A3: clr temp sts minLO,temp lds temp,minHI ; hole min zehner inc temp ; +1 cpi temp,6 ; schon 6 brbs 1,A4 ; nein sts minHI,temp ; nein rjmp A8 A4: clr temp sts minHI,temp plusstunde: lds temp,hHI ; hole h zehner cpi temp,2 ; schon 2 brbs 1,A6 ; ja lds temp,hLO ; hole h einer inc temp ; +1 cpi temp,10 ; schon 10 brbs 1,A5 ; ja sts hLO,temp ; nein rjmp A8 A5: clr temp ; loesche h einer sts hLO,temp ; speichern h einer lds temp,hHI ; hole h zehner inc temp ; +1 sts hHI,temp ; speichern h zehner rjmp A8 A6: lds temp,hLO ; holen h einer inc temp ; +1 cpi temp,4 brbs 1,A7 sts hLO,temp rjmp A8 A7: clr temp sts hLO,temp sts hHI,temp A8: clr temp sts secLO,temp sts secHI,temp A9: rcall Zeitausgabe ; Zeit auf Ports ausgeben pop temp ; SREG vom Stack holen out SREG,temp ; und wiederherstellen pop temp ; temp wiederherstellen reti ;********************************************************************************************** ; jetzt kommen Unterprogramme ;********************************************************************************************** ;********************************************************************************************** ;Warteschleifen ; 1 cycle = 125ns; ; 100µsec = 800 c ; 4100µsec = 32800 c ; 15000µsec = 120000 c ;********************************************************************************************** Delay100: nop ; 1 cycle ; total 800 = (157*5)+(1*2)+10+3 nop ; 1 cycle nop ; 1 cycle ldi temp2,157 ; 1 cycle ldi temp3,1 ; 1 cycle rjmp Delay ; 2 cycles Delay4100: nop ; 1 cycle ; total 32800 = (6547*5)+(26*2)+10+3 nop ; 1 cycle nop ; 1 cycle ldi temp2,147 ; 1 cycle ldi temp3,26 ; 1 cycle rjmp Delay ; 2 cycles Delay15000: nop ; 1 cycle ; total 120000 = (23808*5)+(94*2)+10+2 nop ; 1 cycle ldi temp2,152 ; 1 cycle ldi temp3,94 ; 1 cycle rjmp Delay ; 2 cycles ;********************************************************************************************** ; RCALL needs 3 cycles ; each inner loop = 5 ; each outer loop = +2 (3-1) ; last loop = +3 (4-1) ; formula == ((temp2+(temp3-1)*256)*5)+(temp3*2)+10+(num of nops) ;********************************************************************************************** Delay: nop ; 1 cycle nop ; 1 cycle dec temp2 ; 1 cycle brne Delay ; 2/1 cycles ; Check if inner loop is finished dec temp3 ; 1 cycle brne Delay ; 2/1 cycles ; Check if outer loop is finished ret ; 4 cycles ;********************************************************************************************** ; Ausgabe der Zeit auf Ports ;********************************************************************************************** Zeitausgabe: ldi temp,0b11111111 out DDRD,temp ; set port D output ldi temp,0b00001111 out DDRB,temp ; set port C output ldi temp,0b00001111 out DDRC,temp ; set port C (0-3) output lds temp,hHI ; hole Zehner Stunden ;andi temp,0x0f ;brbc 1,Zeitausgabe1 ; nicht Null ;ldi temp,11 ; Null ausblenden Zeitausgabe1: rcall Korrport ; 74141 Belegung korrigieren out PORTB,temp ; ausgeben lds temp,minLO ; hole einer Stunde rcall Korrport ; 74141 Belegung korrigieren out PORTC,temp ; ausgeben lds temp,minHI ; hole Einer Minuten rcall Korrport ; 74141 Belegung korrigieren mov temp2,temp lds temp,hLO ; hole Zehner Minuten rcall Korrport ; 74141 Belegung korrigieren swap temp ; in oberes Nibble or temp,temp2 ; zusammenwuerfeln out PORTD,temp ; ausgeben ret ;********************************************************************************************** ; Anpassung der Ausgabe an Falsche Belegung des 74141 ;********************************************************************************************** Korrport: andi temp,0x0f ldi ZL, low(Korrektur*2) ;Zeiger auf Tabelle laden ldi ZH,high(Korrektur*2) add ZL,temp ;Zeiger auf Element clr temp adc ZH,temp lpm ;Zeichen nach R0 mov temp,R0 ;Zeichen holen ret ;********************************************************************************************** ; Ab hier gehts richtig los:-) ; das ist der Programmstart nach Reset und Power on ;********************************************************************************************** ;********************************************************************************************** ; Initialisieren der Ports ;********************************************************************************************** Start: ldi temp,RAMEND out SPL,temp ; set stack pointer ldi temp,0xff out PORTD,temp out PORTC,temp out PORTB,temp ldi temp,0b11111111 out DDRD,temp ; set port D output ldi temp,0b00001111 out DDRB,temp ; set port C output ldi temp,0b00001111 out DDRC,temp ; set port C (0-3) output ;********************************************************************************************** ; Initialisieren der Variablen ;********************************************************************************************** ldi YH,high(Korrekt) ; Korrekturwert ganggenauigkeit laden ldi YL,low(Korrekt) clr temp sts secLO,temp sts secHI,temp sts minLO,temp sts minHI,temp sts hLO,temp sts hHI,temp ;********************************************************************************************** ; Timer 1 starten mit 1/64 Quarztakt ;********************************************************************************************** ldi temp,250 out TCNT1H,temp clr temp out TCNT1L,temp ldi temp,0x03 ; 1/64 Takt ( 0x01 = 1/1 Takt) out TCCR1B,temp ldi temp, 0x80 out TIMSK,temp ; Timerinterupt freigeben sei ; Interupt freigeben ;********************************************************************************************** ; Alles erledigt? ; Dann geht jetzt die richtige Arbeit los ;********************************************************************************************** Hauptschleife: rjmp Hauptschleife ; das hier ist die Hauptsache:-)