Code:
$regfile = "m8def.dat" 'ATmega 32
$crystal = 3686400 'Quarz: 8 MHz
$baud = 9600
$hwstack = 32 'hardware stack
$swstack = 8 'software stack
$framesize = 24 'frame space
Config Date = Dmy , Separator = . 'deutsches Format für Datum
Config Clock = Soft
Disable Timer2 'ausgeschaltet lassen
$lib "K_DCF.lib" 'LIB für DCF77
$external Dcf77
Declare Sub Dcf77
'###########################################################################
'Hauptprogramm:
'LCD konfigurieren:
Wait 1
'Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 20 * 2 'LCD 164A
'Startmeldung:
Cls
Lcd "* RNBFRA V1.22 * "
Wait 5
Cls
Config Timer0 = Timer , Prescale = 1024 'Timer 40Hz
Const Startwert = 166'61 'Für 8MHz
Timer0 = Startwert
On Timer0 Tim0_isr 'Überlauf alle 25ms
Enable Interrupts
Enable Timer0
'---------------------- Pin für DCF Eingang definieren ---------------------
'Jeder Portpin kann benutzt werden.
'Auch in der "Dcf77_soft.lib" entsprechend anpassen !!!
Config Pinb.1 = Input 'DCF 77 Eingang ***Alt Pind.3 **
Set Portb.1 'Pullup ein Alt***Portd.3****
Declare Sub Showstatus()
Declare Sub Showtime()
'------------------- Variablen für DCF Routine -----------------------------
Dim Status As Byte , Zaehler As Byte , Buffer As Byte , Impuls As Byte
Dim H_sek As Byte , T_min As Byte , T_std As Byte , Wotag As Byte
Dim Pari As Byte , Pau As Byte , Imp As Byte
Dim I As Byte
'---------------------------------------------------------------------------
'Hauptprogramm:
Cls
Cursor Off
Date$ = "01.01.00"
Time$ = "00:00:00"
Status.7 = 0 'Uhr nach DCF stellen: AUS
Status.5 = 0 'Uhr wurde nicht gestellt
I = 0
'****************** HAUPTPROGRAMMSCHLEIFE **********************************
Cls
Do
'Cls
Call Showtime()
Call Showstatus()
If _min = 58 And Status.7 = 0 Then Status.5 = 0 '1x pro Stunde nach DCF stellen
If Status.5 = 0 Then Status.7 = 1 Else Status.7 = 0 'Zeit nicht aktuell: Stellen!
Wait 1
Loop
End
'************* ENDE HAUPTPROGRAMM ******************************************
Sub Showstatus() 'Status anzeigen
If I = 0 Then I = 1 Else I = 0
Locate 1 , 1
If Status.5 = 1 Then
Lcd " **DCF-Soft Clock** "
Else
Lcd " ***Soft Clock*** *"
End If
Locate 2 , 21
If Status.7 = 1 Then
Lcd "DCF:On "
Else
Lcd "DCF:Off"
End If
Locate 2 , 29
If Status.4 = 1 And I = 0 Then
Lcd " Signal"
Else
Lcd " "
End If
End Sub
'---------------------------------------------------------------------------
Sub Showtime()
Locate 2 , 5
Lcd Time$
If Status.5 = 1 Then
Locate 1 , 23
Wotag = Dayofweek()
Lcd Lookupstr(wotag , Wochentag) ; ". "
Lcd Date$
End If
End Sub
'---------------------- Interrupt Routine DCF77 ----------------------------
Tim0_isr:
Timer0 = Startwert
Call Dcf77
Return
'###########################################################################
'Programm Ende:
End
'---------------------- Daten für Wochentag --------------------------------
Wochentag:
Data "Mo" , "Di" , "Mi" , "Do" , "Fr" , "Sa" , "So"
'###########################################################################
Code:
copyright = W.Krueger
comment = DCF 77 Decoder
libversion = 2.00 (D. Ottensmeyer)
date = 09.04.2006
statement = ----------------------------------
statement = muss alle 25ms ausgeführt werden !
statement = ----------------------------------
[Dcf77]
Dcf77:
.equ DCF_Port = $16 ;$16 = Pinb
.equ DCF_Pin = 1 ;1 = Pin 1
.equ Imp0min = 70 ;minimale Länge des Minutenimpulses
.equ Imp1min = 6 ;minimale Länge des "1" Impulses
;alles darunter wird als "0" Impuls gewertet
.def Temp1 = r16
.def Temp2 = r17
.def Temp3 = r18
.def Minute = r19
.def Stunde = r20
.def Status = r21
;Bit0 = aktueller DCF Status
;Bit1 = vorheriger DCF Status
;Bit2 = Uhr synchronisieren
;Bit3 = 59 Impulse empfangen
;Bit4 = Parität OK
;Bit5 = Uhr wurde 1x gestellt
;Bit7 = Uhr nach DCF stellen
.def Impuls = r22
.def Zaehler = r23
.def Buffer = r24
.def Pari = r25
;------------------------------------
*lds Status,{Status} ;Status laden
rcall Softuhr ;Softuhr bearbeiten
bst Status,7 ;Status Uhr nach DCF stellen ?
brts Puls0 ;ja -> weiter
*sts {Status},Status
ret
Puls0:
*lds Impuls,{Impuls} ;Variablen laden
*lds Zaehler,{Zaehler}
*lds Buffer,{Buffer}
*lds Pari,{Pari}
in temp1,Dcf_Port ;DCF Port lesen
bst temp1,Dcf_Pin ;Status holen
bld Status,0 ;aktuellen Status speichern
inc Zaehler ;Impulslänge erhöhen
bst Status,0 ;akuellen Status prüfen
brts Puls20 ;Status Low -> weiter
bst Status,1 ;vorherigen Status prüfen
brtc Puls40 ;vorheriger Status Low -> Ende
ldi temp1,Imp0min ;Minutenimpuls Minimalwert laden
cp Zaehler,temp1 ;Impulslänge Minimalwert überschritten
brcs Puls10 ;nein -> weiter
*sts {Pau},Zaehler ;--------> Minutenimpulslänge speichern für Debug
clr Buffer ;Empfangspuffer löschen
clr Impuls ;Impulszähler löschen
bst Status,4 ;Parität OK ?
brtc Puls5 ;Nein -> weiter
bst Status,3 ;59 Impulse empfangen ?
brtc Puls5 ;Nein -> weiter
set
bld Status,2 ;Status Uhr synchronisieren setzen
Puls5:
clt
bld Status,3 ;Status 59 Impulse löschen
bld Status,4 ;Status Parität OK löschen
Puls10:
clr Zaehler ;Impulslänge löschen
rjmp Puls40 ;Ende
Puls20:
bst Status,1 ;vorherigen Status prüfen
brts Puls40 ;vorheriger Status Low -> Ende
ldi temp1,Imp1min ;Minimalwert für "1" Impuls laden
cp Zaehler,temp1 ;Minimalwert unterschritten ?
brcs Puls30 ;ja -> weiter
*sts {imp},Zaehler ;--------> Impulslänge Height speichern für Debug
cpi Impuls,28 ;beim Paritätsbit Min keine Negation
breq Puls25
cpi Impuls,35 ;beim Paritätsbit Std keine Negation
breq Puls25
ldi Temp1,1
eor Pari,Temp1 ;Paritätsbit Negation
Puls25:
sec ;Carry setzen ( "1" empfangen )
ror Buffer ;Carry in Empfangspuffer
inc Impuls ;Impulszähler erhöhen
rcall Auswerten ;Impulse auswerten
rjmp Puls40 ;Ende
Puls30:
*sts {imp},Zaehler ;--------> Impulslänge Low speichern für Debug
clc ;Carry löschen ( "0" empfangen )
ror Buffer ;Carry in Empfangspuffer
inc Impuls ;Impulszähler erhöhen
rcall Auswerten ;Impulse auswerten
Puls40:
bst Status,0 ;aktuellen Status holen
bld Status,1 ;Status speichern
*sts {Status},Status ;Variablen wieder speichern
*sts {Impuls},Impuls
*sts {Zaehler},Zaehler
*sts {Buffer},Buffer
*sts {Pari},Pari
ret
;-------------------------------------------------------------------------------
Softuhr:
*lds Temp1,{H_Sek}
*lds Temp2,{_sec}
*lds Minute,{_min}
*lds Stunde,{_hour}
bst Status,2 ;Status Uhr synchronisieren ?
brtc Soft10 ;nein -> weiter Softuhr
clt
bld Status,2 ;Status Synchron löschen
bst Status,7 ;Status Uhr nach DCF stellen ?
brtc Soft10 ;nein -> nicht neu stellen
set
bld Status,5 ;Status Uhr 1x gestellt setzen
clr Temp1 ;Hundertstel löschen
clr Temp2 ;Sekunde löschen
*lds Minute,{T_Min} ;Minute auf empfangene Minute
*lds Stunde,{T_Std} ;Stunde auf empfangene Stunde
rjmp Soft20 ;empfangene Zeit übernehmen
Soft10:
inc Temp1 ;Hundertstel Sek erhöhen
cpi Temp1,40 ;1000ms erreicht ?
brne Soft20 ;nein -> Ende
clr Temp1 ;Hundertstel Sek löschen
inc Temp2 ;Sekunde erhöhen
cpi Temp2,60 ;60 Sekunden erreicht ?
brne Soft20 ;nein -> Ende
clr Temp2 ;Sekunde löschen
inc Minute ;Minute erhöhen
cpi Minute,60 ;60 Minuten erreicht ?
brne Soft20 ;nein -> Ende
clr Minute ;Minute löschen
inc Stunde ;Stunde erhöhen
cpi Stunde,24 ;24 Stunden erreicht ?
brne Soft20 ;nein -> Ende
clr Stunde ;Stunde löschen
*lds Temp3,{_day}
inc Temp3 ;Tag erhöhen
cpi Temp3,29 ;Tag 29 erreicht ?
brlo Soft19 ;bis 28 -> Ende
clt ;ab 29 -> Hat Monat 29,30,31 Tage ?
bld Status,5 ;Status Uhr 1x gestellt löschen
; set ;Datum nach DCF stellen !
; bld Status,7 ;Status Uhr nach DCF stellen setzen
cpi Temp3,32 ;Tag 32 erreicht ?
brne Soft19 ;nein -> Ende
ldi Temp3,1 ;Tag 1 setzen
*sts {_day},Temp3
*lds Temp3,{_month}
inc Temp3 ;Monat erhöhen
cpi Temp3,13 ;Monat 13 erreicht ?
brne Soft18 ;nein -> Ende
ldi Temp3,1 ;Monat 1 setzen
*sts {_month},Temp3
*lds Temp3,{_year}
inc Temp3 ;Jahr erhöhen
cpi Temp3,100 ;Jahr 100 erreicht ?
brne Soft17 ;nein -> Ende
clr Temp3 ;Jahr 00 setzen
Soft17:
*sts {_year},Temp3
rjmp Soft20
Soft18:
*sts {_month},Temp3
rjmp Soft20
Soft19:
*sts {_day},Temp3
Soft20:
*sts {H_Sek},Temp1
*sts {_sec},Temp2
*sts {_min},Minute
*sts {_hour},Stunde
ret
;-------------------------------------------------------------------------------
Auswerten:
cpi Impuls, 21 ;21. Impuls
brne Aus10 ;nein -> weiter
clr Buffer
clr Pari
Aus10:
cpi Impuls, 28 ;28. Impuls
brne Aus15 ;nein -> weiter
lsr Buffer ;Buffer 1x schieben, da Minute nur 7 Bit
rcall Bcd2dez ;in Dezimal wandeln
*sts {T_Min},Buffer ;Temp Minute schreiben
clr Buffer
Aus15:
cpi Impuls, 29 ;Minuten Parität
brne Aus20
clr Temp3
bst Buffer,7 ;Paritätsbit selektieren
bld Temp3,0 ;Paritätsbit in Temp3 Bit0 kopieren
cp Temp3,Pari ;Parität überprüfen
brne Aus26 ;Fehler -> Ende
clr Pari
clr Buffer
Aus20:
cpi Impuls, 35 ;35. Impuls
brne Aus25 ;nein -> weiter
lsr Buffer ;Buffer 2x schieben, da Stunde nur 6 Bit
lsr Buffer
rcall Bcd2dez ;in Dezimal wandeln
*sts {T_Std},Buffer ;Temp Stunde schreiben
clr Buffer
Aus25:
cpi Impuls, 36 ;Stunden Parität
brne Aus30
clr Temp3
bst Buffer,7 ;Paritätsbit selektieren
bld Temp3,0 ;Paritätsbit in Temp3 Bit0 kopieren
cp Temp3,Pari ;Parität überprüfen
breq Aus27 ;Pari OK -> weiter
Aus26:
ret ;Fehler -> Ende
Aus27:
set ;T-Bit setzen
bld Status,4 ;Bit4 Status setzen (Parität)
clr Buffer
Aus30:
cpi Impuls,42 ;42. Impuls
brne Aus40
lsr Buffer ;Buffer 2x schieben, da Tag nur 6 Bit
lsr Buffer
rcall Bcd2dez ;in Dezimal wandeln
*sts {_day},Buffer ;Tag schreiben
clr Buffer
Aus40:
cpi Impuls,45 ;45. Impuls
brne Aus50
lsr Buffer ;Buffer 5x schieben, da Wochentag nur 3 Bit
lsr Buffer
lsr Buffer
lsr Buffer
lsr Buffer
rcall Bcd2dez ;in Dezimal wandeln
*sts {WoTag},Buffer ;Wochentag schreiben
clr Buffer
Aus50:
cpi Impuls,50 ;50. Impuls
brne Aus60
lsr Buffer ;Buffer 3x schieben, da Monat nur 5 Bit
lsr Buffer
lsr Buffer
rcall Bcd2dez ;in Dezimal wandeln
*sts {_month},Buffer ;Monat schreiben
clr Buffer
Aus60:
cpi Impuls,58 ;58. Impuls
brne Aus70
rcall Bcd2dez ;in Dezimal wandeln
*sts {_year},Buffer ;Jahr schreiben
clr Buffer
Aus70:
cpi Impuls,59 ;59. Impuls
brne Aus80
set ;T-Bit setzen
bld Status,3 ;Bit3 Status setzen (59 Impulse)
Aus80:
cpi Impuls,60 ;bei mehr als 59 Impulsen (Störimpulse)
brne Aus90
clt ;T-Bit löschen
bld Status,3 ;Bit3 Status löschen (59 Impulse)
bld Status,4 ;Bit4 Status löschen (Parität)
Aus90:
ret
;-------------------------------------------------------------------------------
Bcd2dez:
mov Temp1,Buffer
andi Temp1,$0F
Bcd10:
subi Buffer,$10
brcs Bcd20
subi Temp1,$F6
rjmp Bcd10
Bcd20:
mov Buffer,Temp1
ret
[end]
Das DCF-Modul Klemme 1=Gnd, 2=5V, 3=Frei, 4= pinb.1
Lesezeichen