Hallo bertl100,

probier 'mal diese vorherige Version:
Code:
copyright    = W.Krueger
comment      = DCF77-Decoder und Softclock
libversion   = 2.51 (D. Ottensmeyer)
date         = 29.09.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 = $10   ;$10 = Portd
.equ DCF_Pin  = 3     ;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 = $10   ;$10 = Pind
.equ DCF_Pin  = 3     ;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 Puls5                  ;Nein -> weiter
  bst Status,2                ;58 Impulse empfangen ?
  brtc Puls5                  ;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
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
  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]
Gruß Dirk