Moin,

Vorweg: ich erwarte nicht, dass sich jemand meinen Code im Detail reinfuchst, ich hoffe, dass es villeicht etwas ist, wo ich einfach nur nicht drauf komme.

Ich hab mir nen schönen Code zum Auswerten von nem DCF Signal gebaut. Das seltsame ist, die Zeitauswertung ist erst im zweiten oder dritten Anlauf korrekt.

Das läuft so, dass erst alles etwa 3 min lang ignoriert wird, dann auf die lange Pause nach Sekunde 59 gewatet wird und erst dann das Signal berücksichtigt wird.

Eine Funktion wird nach jedem Ouls aufgerufen und entscheidet ob es 1 oder 0 war. Ist das 59 mal passiert, wir das Bitmuster ausgewertet.

Klappt aber eben erst beim zweiten,dritten mal wirklich.

Hat da jemand einen Vorschlag?

Danke


Code:
.include "m8def.inc"

.def tmp = r16
.def tmp2 = r17
.def status_reg = r18
;BIT 0 zeigt an, ob PINB,1 während der ISR LOW war, dann = 1
;BIT 1 warten auf dcf Anfang =1 => freigabe
;Bit 2 Fehlerbit
.def pw = r19
.def pw2 = r20
.def pw_alt = r21

.def dcf_shift_reg = r24
.def sreg_save = r25

.equ dcf_BIT_counter = 104
.equ eins = 1
.equ zwei = 2
.equ vier = 4
.equ acht = 8
.equ zehn = 10
.equ zwanzig = 20
.equ vierzig = 40

.org 0x000
  rjmp reset
.org OC1Aaddr
     rjmp timer1_int

;*****************************************	
;*****************************************	
;         Pointer Z
; 
;              ms = RAM 100
;              sc = RAM 101
;             min = RAM 102
;          stunde = RAM 103
; dcf_BIT_counter = RAM 104
;     
;******************************************

;******************************************
;        Pointer Y

;     dcf BIT 0-7 = RAM 105
;    dcf BIT 8-15 = RAM 106
;   dcf BIT 16-23 = RAM 107
;   dcf BIT 24-31 = RAM 107
;   dcf BIT 32-39 = RAM 108
;   dcf BIT 40-47 = RAM 109     
;   dcf BIT 48-55 = RAM 110
;   dcf BIT 56-59 = RAM 111

reset:
   ;Stack wird bei Interrupts benötigt! 
   ldi tmp,HIGH(RAMEND) 
   out SPH,tmp 
   ldi tmp,LOW(RAMEND) 
   out SPL,tmp
   ldi tmp,0xFF
   out DDRD,tmp
   ldi tmp,0

   ldi r28,105
   ldi r29,0

   ldi r31,0
   ldi r30,100
   st Z+,tmp
   st Z+,tmp
   st Z+,tmp 
   st Z+,tmp 
   st Z,tmp
   ldi r30,100
   
   ldi tmp,0
   out DDRC,tmp
   ldi tmp,0b00110000
   out PORTC,tmp
   ldi tmp,0
   out DDRB,tmp
   ldi tmp,0
   out PORTB,tmp
   ldi tmp,0b00110000
   out TIMSK,tmp
   
ldi tmp,0b00000010
   out OCR1AH,tmp
   ldi r17,0b01110001
   out OCR1AL,r17

   ldi tmp,0b00000000
   out TCCR1A,tmp
   ldi tmp,0b00001011
   out TCCR1B,tmp
   ldi r17,0
   ldi status_reg,0
   
   ldi r28,105
   
ldi dcf_shift_reg,0
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y,dcf_shift_reg
ldi r28,105
sbi PORTD,7
ldi pw_alt,0
   sei

   main:
;**********************************
; Funktion dcf_einholen wird aufgerufen, wenn
; pw > 9  und am ISR Anfang keinSignal da war
; pw wird in dcf_einholen gelöscht
;pw kann nur erhöht werden, wenn 
;lange Pause da war => keine Abfrage von 
;Bit 1 im status_reg nötig
   cpi pw,5
   brlo dcf_nicht_einholen
   sbrc status_reg,0b00000000; 
   rjmp dcf_nicht_einholen
   rcall dcf_einholen
   
;**********************************
;   out PORTD,r28


  sbrc status_reg,0b00000100
   rcall dcf_auswerten
   dcf_nicht_einholen:
   
 sbis PINC,5
 ori status_reg,0b00100000

  

   
   
   
   rjmp main


fehlerroutine:
ldi status_reg,0 
ldi r28,105
st Y,status_reg
ldi r30,104
st Z,status_reg
ldi r30,100
ldi pw,0
ldi pw2,0
ret



dcf_einholen:
/*
1.) prüft Pulsweite auf >< 150 ms
2.) erhöht Y Pointer, wenn ein Byte voll ist
3.) speichert bei "überlauf" von bit_counter=8 bit_counter = 0 ab
24 CK´s inclusive rcall
*/

	 
     ldi r30,dcf_BIT_counter
	 ld tmp,Z
	 ld dcf_shift_reg,Y;
	 lsr dcf_shift_reg
	 
	 cpi pw,16
	 brlo log_null
	 ori dcf_shift_reg,0b10000000
	 log_null:
	 
     st Y,dcf_shift_reg    
	 sbrs tmp,0b00000011
	 rjmp vollmachen
	 ldi tmp,0
	 st Z,tmp
	 inc r28
	 
	 ldi dcf_shift_reg,0
	 vollmachen:
	

     
ldi pw,0
ldi r30,100
inc pw_alt
cpi pw_alt,59
brne mehr1
ori status_reg,0b00010000
mehr1:
ret


dcf_auswerten:

ldi r30,dcf_BIT_counter
ldi tmp,0
st Z,tmp

andi status_reg,0b11101101; löschen der Freigabe von Pause_war_da
                          ; und Aufruf von dcf_auswerten

ldi pw_alt,0

/*
wertet die Bitmuster in RAM 107 bis 109 in Minuten und Stunden aus
81 CK´s inclusive rcall
*/
  
;***************************
;       Minuten


ldi r28,107

ld tmp,Y

inc r28;lädt von 107 dann inc zu 108
ldi r22,0

ldi tmp2,1
sbrc tmp,0b00000101
add r22,tmp2

ldi tmp2,2
sbrc tmp,0b00000110
add r22,tmp2

ldi tmp2,4
sbrc tmp,0b00000111
add r22,tmp2


ld tmp,Y
inc r28;lädt von 108 dann inc zu 109

ldi tmp2,8
sbrc tmp,0b00000000
add r22,tmp2

ldi tmp2,10
sbrc tmp,0b00000001
add r22,tmp2

ldi tmp2,20
sbrc tmp,0b00000010
add r22,tmp2

ldi tmp2,40
sbrc tmp,0b00000011
add r22,tmp2
;out PORTD,r22
;***************************

;***************************
;     Stunde

ldi tmp2,eins
sbrc tmp,0b00000101
add r23,tmp2

ldi tmp2,2
sbrc tmp,0b00000110
add r23,tmp2

ldi tmp2,4
sbrc tmp,0b00000111
add r23,tmp2

ld tmp,Y ;lädt von 109
ldi tmp2,8
sbrc tmp,0b00000000
add r23,tmp2

ldi tmp2,10
sbrc tmp,0b00000001
add r23,tmp2

ldi tmp2,20
sbrc tmp,0b00000010
add r23,tmp2

ldi r22,0
ldi r23,0
;***************************
ldi r28,105
ldi dcf_shift_reg,0
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y+,dcf_shift_reg
st Y,dcf_shift_reg
ldi r28,105

out PORTD,status_reg
sbi PORTD,6
ret


 

 timer1_int:
 in sreg_save,SREG
 sbrs status_reg,0b00000101
 rjmp ignore
  ;****************************
  ; setzt Bit 0 in status_reg, wenn Signal da (PINB_0 HIGH)  ist
  ; setzte Bit 3 in status_reg auf rising edge 
  sbis PINB,0
  rjmp kein_signal_an_pinb0 
   sbrs status_reg,0b00000000
   ori status_reg,0b00001000
    ori status_reg,0b00000001
	rjmp signal_da
  kein_signal_an_pinb0:
  andi status_reg,0b11111110
  signal_da:
;**************************

;***************************
; ausführen wenn kein Signal 

  sbrc status_reg,0b00000000
  rjmp warten_auf_pause

 
    inc pw2
    cpi pw2,100
    brlo warten_auf_pause
	ldi r22,0
    sbrc status_reg,0b00000001
    rjmp fehlerbit_setzten
       ori status_reg,0b00000010
       ldi pw2,0
	  
    rjmp warten_auf_pause
    fehlerbit_setzten:
        ori status_reg,0b00000100    

    ldi pw2,0
	   
	   

    rjmp war_keins_da 
 
 warten_auf_pause:

 war_keins_da: 
 
;***************************

;***************************
;ausführen, wenn zu ISR Anfang Signal da war und
;lange Pause da war
 sbrs status_reg,0b00000000
 rjmp warten_auf_signal
 sbrs status_reg,0b00000001
 rjmp warten_auf_signal
 
 inc pw
 ldi pw2,0
 
 warten_auf_signal:





 sbrc status_reg,0b00000000
 ldi pw2,0
 
 sbrs status_reg,0b00000011
 rjmp fix
 ldi r30,dcf_BIT_counter
 ld tmp,Z
 inc tmp
 
 st Z,tmp
 andi status_reg,0b11110111
 fix: 
 ;out PORTD,status_reg
ignore:

;****************** Zählen der ms RAM 100
  ldi r30,100
  ld tmp,Z
  inc tmp
  st Z,tmp
  cpi tmp,100 
  brlo mehr
  ldi tmp,0
  st Z+,tmp
;******************

;****************** Zählen der sec RAM 101

  ld tmp,Z
  inc tmp
  st Z,tmp

  cpi tmp,60
  brlo mehr 
  ldi tmp,0
  
  st Z,tmp
  inc r30
;****************** 

;****************** Zählen der min RAM 102

 ld tmp,Z
 inc tmp
 st Z,tmp

 cpi tmp,5
 brne ignore2
 sbr status_reg,0b00100000
 cbi PORTD,7
 ignore2:

 cpi tmp,60
 brlo mehr
 ldi tmp,0
 st Z,tmp
 inc r30
;******************

;****************** Zählen der Stunde RAM 103
 ld tmp,Z
 inc tmp
 st Z,tmp
 cpi tmp,25
 ldi tmp,0
 st Z,tmp
;******************
 mehr:
ldi r30,100
 out SREG,sreg_save
reti