Liste der Anhänge anzeigen (Anzahl: 2)
Ich verwende das RNMEga2560 Modul von Robotikhardware
Momentan hab ich den DCF Empfänger auf Portl.6
Die modofizierte lib.
copyright = W.Krueger
comment = DCF77-Decoder und Softclock
libversion = 2.52 (D. Ottensmeyer)
date = 07.10.2006
statement = ----------------------------------
statement = muss alle 25ms ausgeführt werden !
statement = Neu: komplette Paritätsprüfung
statement = Neu: Auswertung der Bits 15..20
statement = Neu: erweiterte Softclock
statement = ----------------------------------
[Dcf77_soft]
.equ DCF_Port = $109 ;$10 = Portd
.equ DCF_Pin = 6 ;3 = Pin 3
.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 Status = r18
;Bit0 = aktueller DCF Status
;Bit1 = vorheriger DCF Status
;Bit2 = 58 Impulse empfangen
;Bit3 = Parität OK
;Bit4 = Stundenparität OK
;Bit5 = Uhr nach DCF gestellt
;Bit6 = Datum nach DCF gestellt
;Bit7 = Uhr nach DCF stellen
.def Impulse = r19
.def Counter = r20
.def Buffer = r21
.def Parity = r22
Dcf77_soft:
*lds Status,{Dcfstatus} ;Status laden
rcall Softclock ;Softclock bearbeiten
bst Status,7 ;Status Uhr nach DCF stellen ?
brts Puls0 ;ja -> weiter
*sts {Dcfstatus},Status
ret
;-------------------------------------------------------------------------------
[Dcf77]
.equ DCF_Port = $109 ;$10 = Pind
.equ DCF_Pin = 6 ;3 = Pin 3
.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 Status = r18
;Bit0 = aktueller DCF Status
;Bit1 = vorheriger DCF Status
;Bit2 = 58 Impulse empfangen
;Bit3 = Parität OK
;Bit4 = Stundenparität OK
;Bit5 = Uhr nach DCF gestellt
;Bit6 = Datum nach DCF gestellt
;Bit7 = Uhr nach DCF stellen
.def Impulse = r19
.def Counter = r20
.def Buffer = r21
.def Parity = r22
Dcf77:
*lds Status,{Dcfstatus} ;Status laden
bst Status,7 ;Status Uhr nach DCF stellen ?
brts Puls0 ;ja -> weiter
ret
Puls0:
*lds Impulse,{Dcfimpulse} ;Variablen laden
*lds Counter,{Dcfcounter}
*lds Buffer,{Dcfbuffer}
*lds Parity,{Dcfparity}
in temp1,Dcf_Port ;DCF Port lesen
bst temp1,Dcf_Pin ;Status holen
bld Status,0 ;aktuellen Status speichern
inc Counter ;Impulslänge erhöhen
bst Status,0 ;aktuellen 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 Counter,temp1 ;Impulslänge Minimalwert überschritten
brcs Puls10 ;nein -> weiter
*sts {Dcfpau},Counter ;--------> Minutenimpulslänge speichern für Debug
clr Buffer ;Empfangspuffer löschen
clr Impulse ;Impulszähler löschen
bst Status,3 ;Parität OK ?
brtc Puls15 ;Nein -> weiter
bst Status,2 ;58 Impulse empfangen ?
brtc Puls15 ;Nein -> weiter
rcall Stellen ;empfangene Zeit übernehmen
Puls5:
clt
bld Status,2 ;Status 58 Impulse löschen
bld Status,3 ;Status Parität OK löschen
bld Status,4 ;Status Stundenparität OK löschen
Puls10:
clr Counter ;Impulslänge löschen
rjmp Puls40 ;Ende
Puls15:
bst Status,4 ;Stundenparität OK ?
brtc Puls5
rcall Zeitstellen ;nur Uhrzeit übernehmen
rjmp Puls5
Puls20:
bst Status,1 ;vorherigen Status prüfen
brts Puls40 ;vorheriger Status Low -> Ende
ldi temp1,Imp1min ;Minimalwert für "1" Impuls laden
cp Counter,temp1 ;Minimalwert unterschritten ?
brcs Puls30 ;ja -> weiter
*sts {Dcfimp},Counter ;--------> Impulslänge High speichern für Debug
cpi Impulse,28 ;beim Paritätsbit Min keine Negation
breq Puls25
cpi Impulse,35 ;beim Paritätsbit Std keine Negation
breq Puls25
cpi Impulse,58 ;beim Paritätsbit Datum keine Negation
breq Puls25
ldi Temp1,1
eor Parity,Temp1 ;Paritätsbit Negation
Puls25:
sec ;Carry setzen ( "1" empfangen )
ror Buffer ;Carry in Empfangspuffer
rcall Auswerten ;Impulse auswerten
inc Impulse ;Impulszähler erhöhen
rjmp Puls40 ;Ende
Puls30:
*sts {Dcfimp},Counter ;--------> Impulslänge Low speichern für Debug
clc ;Carry löschen ( "0" empfangen )
ror Buffer ;Carry in Empfangspuffer
rcall Auswerten ;Impulse auswerten
inc Impulse ;Impulszähler erhöhen
Puls40:
bst Status,0 ;aktuellen Status holen
bld Status,1 ;Status speichern
*sts {Dcfstatus},Status ;Variablen wieder speichern
*sts {Dcfimpulse},Impulse
*sts {Dcfcounter},Counter
*sts {Dcfbuffer},Buffer
*sts {Dcfparity},Parity
ret
;-------------------------------------------------------------------------------
Softclock: ;muss 40x pro Sekunde aufgerufen werden
*lds Temp1,{Dcfhsec}
inc Temp1 ;Hundertstel Sek erhöhen
cpi Temp1,40 ;1000ms erreicht ?
breq Soft10 ;ja -> weiter
*sts {Dcfhsec},Temp1
ret ;sonst Ende
Soft10:
clr Temp1 ;Hundertstel Sek löschen
*sts {Dcfhsec},Temp1
*lds Temp1,{_sec}
inc Temp1 ;Sekunde erhöhen
cpi Temp1,60 ;60 Sekunden erreicht ?
breq Soft20 ;ja -> weiter
*sts {_sec},Temp1
ret
Soft20:
clr Temp1 ;Sekunde löschen
*sts {_sec},Temp1
*lds Temp1,{_min}
inc Temp1 ;Minute erhöhen
cpi Temp1,60 ;60 Minuten erreicht ?
breq Soft30 ;ja -> weiter
*sts {_min},Temp1
ret
Soft30:
clr Temp1 ;Minute löschen
*sts {_min},Temp1
*lds Temp1,{_hour}
inc Temp1 ;Stunde erhöhen
cpi Temp1,24 ;24 Stunden erreicht ?
breq Soft40 ;ja -> weiter
*sts {_hour},Temp1
ret
Soft40:
clr Temp1 ;Stunde löschen
*sts {_hour},Temp1
*lds Temp1,{_dayofweek}
inc Temp1 ;Wochentag erhöhen
cpi Temp1,8 ;letzter Wochentag erreicht ?
brne Soft50 ;nein -> weiter
ldi Temp1,1 ;Wochentag auf "1" (Montag)
Soft50:
*sts {_dayofweek},Temp1
*lds Temp1,{_day} ;Tag holen
*lds Temp2,{_month} ;Monat holen
ldi zl,low(Tagdaten*2)
ldi zh,high(Tagdaten*2) ;Anzahl Tage pro Monat holen
add zl,Temp2 ;Zeiger auf aktuellen Monat
lpm ;Anzahl Tage holen
cp Temp1,r0 ;Monatsende erreicht ?
brne Soft90 ;nein -> weiter
cpi Temp2,2 ;Monatsende Februar ?
brne Soft60 ;nein -> weiter
clt ;Evtl. Schaltjahr mit 29.2.
bld Status,6 ;Status Datum nach DCF gestellt löschen
Soft60:
cpi Temp2,6 ;Monatsende Juni ?
brne Soft70 ;nein -> weiter
clt ;Zur Jahresmitte evtl. Schaltsekunde
bld Status,5 ;Status Uhr nach DCF gestellt löschen
Soft70:
ldi Temp1,1 ;Tag auf 1
cpi Temp2,12 ;Jahresende erreicht ?
brne Soft100 ;nein -> weiter
clt ;Zum Jahreswechsel evtl. Schaltsekunde
bld Status,5 ;Status Uhr nach DCF gestellt löschen
*lds Temp2,{_year} ;Jahr holen
inc Temp2 ;Jahr erhöhen
cpi Temp2,100 ;Jahr 100 erreicht ?
brne Soft80 ;nein -> Ende
clr Temp2 ;Jahr 00 setzen
Soft80:
*sts {_year},Temp2 ;speichern
ldi Temp2,1 ;Monat auf 1
rjmp Soft110
Soft90:
inc Temp1 ;Tag erhöhen
rjmp Soft110
Soft100:
inc Temp2 ;Monat erhöhen
Soft110:
*sts {_day},Temp1 ;Datum speichern
*sts {_month},Temp2
ret
Stellen:
*lds Temp1,{Dcftemp+2}
*sts {_day},Temp1 ;Tag auf empfangenen Tag
*lds Temp1,{Dcftemp+3}
*sts {_dayofweek},Temp1 ;Wochentag auf empfangenen Wochentag
*lds Temp1,{Dcftemp+4}
*sts {_month},Temp1 ;Monat auf empfangenen Monat
*lds Temp1,{Dcftemp+5}
*sts {_year},Temp1 ;Jahr auf empfangenes Jahr
set
bld Status,6 ;Status Datum nach DCF gestellt setzen
Zeitstellen:
ldi Temp1,1 ;Hundertstel zurücksetzen
*sts {Dcfhsec},Temp1 ;(1. Intervall 25ms kürzer !)
clr Temp1
*sts {_sec},Temp1 ;Sekunde auf 0 setzen
*lds Temp1,{Dcftemp}
*sts {_min},Temp1 ;Minute auf empfangene Minute
*lds Temp1,{Dcftemp+1}
*sts {_hour},Temp1 ;Stunde auf empfangene Stunde
*lds Temp1,{Dcftemp+6}
*sts {Dcfflags},Temp1 ;DCF77-Bits 15..20 aktualisieren
set
bld Status,5 ;Status Uhr nach DCF gestellt setzen
ret
Tagdaten:
.db 00, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
;-------------------------------------------------------------------------------
Auswerten:
cpi Impulse,14 ;14. Impuls
brne Aus5 ;nein -> weiter
clr Buffer
Aus5:
cpi Impulse,20 ;20. Impuls
brne Aus10 ;nein -> weiter
bst Buffer,7 ;Startbit 20 (S) selektieren
brtc Aus26 ;Fehler -> Ende
lsr Buffer ;Buffer 2x schieben, da 6 Bit
lsr Buffer
*sts {Dcftemp+6},Buffer ;Temp DCF77-Bits 15..20 schreiben
;Inhalt Buffer -> Bit0 (R) : Reserve-Antenne des DCF77-Senders
; Bit1 (A1): Ankündigung des Wechsels MEZ <-> MESZ
; Bit2 (Z1): \__ Z1/Z2: 10 = MESZ, 01 = MEZ
; Bit3 (Z2): /
; Bit4 (A2): Ankündigung einer Schaltsekunde
; Bit5 (S) : Startbit f. Zeitinformationen (immer 1)
clr Buffer
clr Parity
Aus10:
cpi Impulse,27 ;27. Impuls
brne Aus15 ;nein -> weiter
lsr Buffer ;Buffer 1x schieben, da Minute nur 7 Bit
rcall Bcd2dez ;in Dezimal wandeln
*sts {Dcftemp},Buffer ;Temp Minute schreiben
clr Buffer
Aus15:
cpi Impulse,28 ;Minuten Parität
brne Aus20
clr Temp1
bst Buffer,7 ;Paritätsbit selektieren
bld Temp1,0 ;Paritätsbit in Temp1 Bit0 kopieren
cp Temp1,Parity ;Minutenparität überprüfen
brne Aus26 ;Fehler -> Ende
clr Parity
clr Buffer
Aus20:
cpi Impulse,34 ;34. Impuls
brne Aus25 ;nein -> weiter
lsr Buffer ;Buffer 2x schieben, da Stunde nur 6 Bit
lsr Buffer
rcall Bcd2dez ;in Dezimal wandeln
*sts {Dcftemp+1},Buffer ;Temp Stunde schreiben
clr Buffer
Aus25:
cpi Impulse,35 ;Stunden Parität
brne Aus30
clr Temp1
bst Buffer,7 ;Paritätsbit selektieren
bld Temp1,0 ;Paritätsbit in Temp1 Bit0 kopieren
cp Temp1,Parity ;Stundenparität überprüfen
breq Aus27 ;Parität OK -> weiter
Aus26:
ret ;Fehler -> Ende
Aus27:
set
bld Status,4 ;Bit4 Status setzen (Stundenparität)
clr Parity
clr Buffer
Aus30:
cpi Impulse,41 ;41. Impuls
brne Aus40
lsr Buffer ;Buffer 2x schieben, da Tag nur 6 Bit
lsr Buffer
rcall Bcd2dez ;in Dezimal wandeln
*sts {Dcftemp+2},Buffer ;Temp Tag schreiben
clr Buffer
Aus40:
cpi Impulse,44 ;44. 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 {Dcftemp+3},Buffer ;Temp Wochentag schreiben
clr Buffer
Aus50:
cpi Impulse,49 ;49. Impuls
brne Aus60
lsr Buffer ;Buffer 3x schieben, da Monat nur 5 Bit
lsr Buffer
lsr Buffer
rcall Bcd2dez ;in Dezimal wandeln
*sts {Dcftemp+4},Buffer ;Temp Monat schreiben
clr Buffer
Aus60:
cpi Impulse,57 ;57. Impuls
brne Aus70
rcall Bcd2dez ;in Dezimal wandeln
*sts {Dcftemp+5},Buffer ;Temp Jahr schreiben
clr Buffer
Aus70:
cpi Impulse,58 ;Restparität
brne Aus80
set ;T-Bit setzen
bld Status,2 ;Bit2 Status setzen (58 Impulse)
clr Temp1
bst Buffer,7 ;Paritätsbit selektieren
bld Temp1,0 ;Paritätsbit in Temp1 Bit0 kopieren
cp Temp1,Parity ;Restparität überprüfen
brne Aus90 ;Fehler -> Ende
set ;T-Bit setzen
bld Status,3 ;Bit3 Status setzen (Parität)
Aus80:
cpi Impulse,59 ;mehr als 58 Impulse (d.h. Störimpulse)
brne Aus90
clt ;T-Bit löschen
bld Status,2 ;Bit2 Status löschen (58 Impulse)
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]
Liste der Anhänge anzeigen (Anzahl: 1)
Alle 24 Sekunden passiert das
DCF77 Library Impulslänge
Hallo,
ich habe mir die DCF77 Library von "W.Krueger" runtergeladen. Könnte mir jemand die Einstellung der Minutenimpulse erklären. Ich habe keinen Conrad
DCF Empfänger sondern einen Hyline Empfänger mit: 40-60 ms kurze Impulse und 85 - 115 lange Impulse, würde mir gerne die Zeiten ändern.
Über eine Antwort würde ich mich freuen.
Gruss Peter