Hallo

Ich hab viel im Netz gelesen und mir viele Codebeispiele angesehen.
(Hier die eine gute Site, die viel Informationen gibt:
http://www.heret.de/funkuhr/index.htm)


Mit einem OSZI hab ich mir dann das Empfangs-Signal mal angesehen ...
... und endlich verstanden

... jetzt weiß ich auch, warum bei so 'ner Funkuhr das Signalzeichen mal da ist, mal nicht ... Der Empfang der Zeit ist nicht immer ungestört und somit die Information nicht vollständig. Informationsperiode ist eine Minute.

Meine Lösung basiert auf folgende Vorgehensweise:

1. Ein Timer (alle ~ 2,1ms) zählt den Zähler für Minutensignal und Secsignal hoch - void dcf_timer_overflow(void) // alle ~2,1ms

2. Der Interrupt (auf beide Flanken des Impulses) entscheidet über Zählerfunktionen - void dcf_interrupt(void) // Signal vom DCF_Modul

Das alles hat den Vorteil. daß der Timer imemr normal durchlaufen kann und mehrfach benutzt werden kann (bei mir u.a. für Tastenentprellung, Erkennung Lang- und Kurzdrücken einer Taste, Auswerten von Drehimpulsgebern, ...)

3. Und wenn grad kein Interruptjob oder sonst was läuft, wird die Zeit ermittelt ... void dcf_auswertung()


Hier mein Zeh - Code

Hier die Header-Datei
Code:
#ifndef _dcf77_h_
#define _dcf77_h_

typedef struct
{
   byte valid;
   byte MESZ;
   byte min;
   byte valid_min;
   byte std;
   byte valid_std;
   byte tag;
   byte wota;
   byte mon;
   int  year;
   byte valid_datum;
}DCF_TIME;
   
#ifdef __dcf77_h_intern_

DCF_TIME DCF_time;
long     lval_dcf_store;

void dcf_Init(void);
void dcf_timer_overflow(void);
void dcf_interrupt(void);
void dcf_auswertung(void);

#else

extern DCF_TIME DCF_time;
extern long     lval_dcf_store;
extern void dcf_Init(void);
extern void dcf_timer_overflow(void);
extern void dcf_interrupt(void);
extern void dcf_auswertung(void);

#endif
#endif
Und hier dier Quälcode
Code:

#include <inttypes.h>
#include <avr/io.h>
//#include <avr/signal.h>
//#include <avr/interrupt.h>
//#include <avr/delay.h>
#include <stdio.h> // für printf
//#include <stdlib.h>
#include <string.h>
//-------------------------------------------------------

#include "basdef_h"
#include "ic2twi_h.h"

#include "defines_h.h"

#define __dcf77_h_intern_
#include "dcf77_h.h"

// die folgenden Konstanten regel das Zeitfenster
const int cnt_mehrals_1secin2erms  = 490; // 1000ms / 2,048 = 488,28 -> 490
const int cnt_kanpp_100msin2erms   =  45; // 100 ms / 2,048 = 48,828 -> 45
const int cnt_kanpp_200msin2erms   =  90; // 200 ms / 2,048 = 97,656 -> 90
byte bitbuffer[60];
byte bitauswertung[60];
int  bitposition         = -1;
int  flag_auswertung     = -1; // auswertung läuft erst ab 0
int  cnt_dcf_min_zeit    = -1;
int  cnt_dcf_sig_zeit    = -1;


void dcf_Init(void) // Grundinitialisierung bei Programmstart
{
   lval_dcf_store = 0;
   memset(&DCF_time, 0, sizeof(DCF_TIME));
}


void dcf_auswertung()
{
	if(flag_auswertung > 0)
	{
		int p, sum;
		memset(&DCF_time, 0, sizeof(DCF_TIME));
			
		DCF_time.valid = 1;
		for(p = 20; p < 59; p++)
		{
			if(bitauswertung[p] == 0)
			{
				DCF_time.valid = 0;
				break;
			}
		}
		if(bitauswertung[20] != 2) // immer Logisch 1
			DCF_time.valid = 0;
		
		
		if(DCF_time.valid)
		{
			DCF_time.MESZ =	((bitauswertung[17] == 1) && (bitauswertung[18] == 0));
			
			// 21-27: 7 Bits  Minute 1,2,4,8,10,20,40
			DCF_time.min  =	(bitauswertung[21] == 2) *  1 +
							(bitauswertung[22] == 2) *  2 +
							(bitauswertung[23] == 2) *  4 +
							(bitauswertung[24] == 2) *  8 +
							(bitauswertung[25] == 2) * 10 +
							(bitauswertung[26] == 2) * 20 +
							(bitauswertung[27] == 2) * 40;
			// 28:    1 Bit   Paritiy Minute - Bit 21-27
			sum = 0;
			for(p = 21; p <= 28; p++)
				sum += (bitauswertung[p] == 2);
			DCF_time.valid_min = !(sum % 2);
							
			// 29-34: 6 Bits  Stunde 1,2,4,8,10,20
			DCF_time.std  =	(bitauswertung[29] == 2) *  1 +
							(bitauswertung[30] == 2) *  2 +
							(bitauswertung[31] == 2) *  4 +
							(bitauswertung[32] == 2) *  8 +
							(bitauswertung[33] == 2) * 10 +
							(bitauswertung[34] == 2) * 20;
			// 35:    1 Bit   Parity Stunde - Bit 29-34
			sum = 0;
			for(p = 29; p <= 35; p++)
				sum += (bitauswertung[p] == 2);
			DCF_time.valid_std = !(sum % 2);
			
			// 36-41: 6 Bits  Tag 1,2,4,8,10,20
			DCF_time.tag  =	(bitauswertung[36] == 2) *  1 +
							(bitauswertung[37] == 2) *  2 +
							(bitauswertung[38] == 2) *  4 +
							(bitauswertung[39] == 2) *  8 +
							(bitauswertung[40] == 2) * 10 +
							(bitauswertung[41] == 2) * 20;
				
			// 42-44: 3 Bits  Wochentag 1,2,4 - 1=Mo .. 7=So
			DCF_time.wota  =(bitauswertung[42] == 2) *  1 +
							(bitauswertung[43] == 2) *  2 +
							(bitauswertung[44] == 2) *  4;
							
			// 45-49: 5 Bits  Monat 1,2,4,8,10
			DCF_time.mon  =	(bitauswertung[45] == 2) *  1 +
							(bitauswertung[46] == 2) *  2 +
							(bitauswertung[47] == 2) *  4 +
							(bitauswertung[48] == 2) *  8 +
							(bitauswertung[49] == 2) * 10;
							
			// 50-57: 8 Bits  Jahr 2005+ 1,2,4,8,10,20,40,80
			DCF_time.year  =	(bitauswertung[50] == 2) *  1 +
							(bitauswertung[51] == 2) *  2 +
							(bitauswertung[52] == 2) *  4 +
							(bitauswertung[53] == 2) *  8 +
							(bitauswertung[54] == 2) * 10 +
							(bitauswertung[55] == 2) * 20 +
							(bitauswertung[56] == 2) * 40 +
							(bitauswertung[57] == 2) * 80 + 2000;
			// 58:    Paritiy Datum - Bit 35-57
			sum = 0;
			for(p = 36; p <= 58; p++)
				sum += (bitauswertung[p] == 2);
			DCF_time.valid_datum = !(sum % 2);

			/*
			printf("\n%02d:%02d (%d/%d) - %02d.%02d.%04d (%d)", (int)DCF_time.std, (int)DCF_time.min, (int)DCF_time.valid_std, (int)DCF_time.valid_min,
															    (int)DCF_time.tag, (int)DCF_time.mon, (int)DCF_time.year,      (int)DCF_time.valid_datum);
																
			23:44 (1/1) - 03.02.2006 (1)
			*/
		}
		/*
		else
		{
			printf("\n#");
			for(int i = 0; i < 60; i++)
			{
				switch(bitauswertung[i])
				{
					case 1 : printf("0"); break;
					case 2 : printf("1"); break;
					default: printf("_"); break;
				}
			}
			printf("#");
		}
		*/
		
		flag_auswertung = 0;
	}
}








// Bei jedem TimerZyklus wird ggf. entsp. Zähler erhöht
void dcf_timer_overflow(void) // alle ~2,1ms
{
	if(cnt_dcf_min_zeit >= 0)
		cnt_dcf_min_zeit++;
	
	if(cnt_dcf_sig_zeit >= 0)
		cnt_dcf_sig_zeit++;
	
	// wenn kein Empfang ist, aber die timer gestartet wurden,
	// werden sie automatisch angehalten, wenn MAXINT überschritten wurde ;-)
}

// Signal vom DCF_Modul
void dcf_interrupt(void)
{
	byte SigVal =  DCF77_Port & (1 << DCF77_INT); // INT - Port
	if(SigVal) // Beginn der Sekunde
	{
		cnt_dcf_sig_zeit = 0; // Zähler für Längenmessung des Sec.Signals löschen
		
		int store_cnt_dcf_min_zeit = cnt_dcf_min_zeit;
		cnt_dcf_min_zeit = 0; // Sekundenzeitmessung neu starten

		if(store_cnt_dcf_min_zeit > 0) // Sekundenzeitmessung lief
		{
			if(store_cnt_dcf_min_zeit > cnt_mehrals_1secin2erms) // letzter Durchgang länger als 1 sec, somit MinutenStart = neue Auswertung beginnt 
			{
				if(flag_auswertung < 0)
					flag_auswertung = 0; // ab jetzt sind Auswertungen möglich
				else
				{
					memcpy(bitauswertung, bitbuffer, 60);
					flag_auswertung = 1; // Auswertung abgeschlossen, Haupt-Loob-Job freigeben
				}
				
				// ab jetzt darf gespeichert werden
				memset(bitbuffer, 0, 60); // alle Felder ohne Empfangsinformation
				bitposition = 0;
			}
		}
	}
	else // Ende der Zeitmessung einer sec.
	{
		int store_cnt_dcf_sig_zeit = cnt_dcf_sig_zeit;
		cnt_dcf_sig_zeit = -1; // Zähler aus
		
		if((bitposition >= 0) && (bitposition < 60))
		{
			if(store_cnt_dcf_sig_zeit > cnt_kanpp_100msin2erms)
			{
				if(store_cnt_dcf_sig_zeit > cnt_kanpp_200msin2erms)
					bitbuffer[bitposition] = 2; // Logische 1
				else
				{
					bitbuffer[bitposition] = 1; // Logische 0
				}
			}
			
			// im Nichtempfangsfall bleibt ArrayFeld "leer"
				
			bitposition++;
		}
	}
}

Hier die empfangenen Bitfolgen mit Erklärung in Kurzform
Code:
#ifndef erklaerung_der_empfangenen_bits

00000000000000000010100101101101010111000010101000011000001_
00000000000000000010110101100101010111000010101000011000001_
00000000000000000010111101101101010111000010101000011000001_
00000000000000000010100011101101010111000010101000011000001_
00000000000000000010110000010101010111000010101000011000001_
00000000000000000010101000010101010111000010101000011000001_
00000000000000000010111000011101010111000010101000011000001_
00000000000000000010100100010101010111000010101000011000001_
00000000000000000010110100011101010111000010101000011000001_
00000000000000000010110010011101010111000010101000011000001_
00000000000000000010100001010101010111000010101000011000001_
00000000000000000010110001011101010111000010101000011000001_
00000000000000000010101001011101010111000010101000011000001_
00000000000000000010100101011101010111000010101000011000001_
00000000000000000010110011010101010111000010101000011000001_
00000000000000000010100000000011010111000010101000011000001_
00000000000000000010110000001011010111000010101000011000001_ 
00000000000000000010111000000011010111000010101000011000001_
00000000000000000010100100001011010111000010101000011000001_
00000000000000000010110100000011010111000010101000011000001_ 
00000000000000000010100100100011010111000010101000011000001_

012345678901234567890123456789012345678901234567890123456789
0         1         2         3         4         5
_________________Z1   17: MEZ  = 0 MESZ = 1 => 0 = MEZ
__________________Z2  18: MEZ  = 1 MESZ = 0 => 1 = MEZ
____________________X 20: immer 1           => 1 o.k.
_____________________mmmmmmm
_____________________0010010 = 2+10=12
____________________________Pm
____________________________0 Summe 2 o.k.
_____________________________hhhhhh
_____________________________011010 = 2+4+10=16
___________________________________Ph
___________________________________1 Summe 4 o.k.
____________________________________dddddd
____________________________________110000 = 1+2=3 o.k.
__________________________________________www
__________________________________________101 = 1+4=5 = Fr. o.k.
_____________________________________________mmmmm
_____________________________________________01000 = 2 = Feb. o.k.
__________________________________________________yyyyyyyy
__________________________________________________01100000 = 2+4=6 = 2006
__________________________________________________________Py
____________________________________11000010101000011000001 Summe = 8 o.k.

// 21-27: 7 Bits  Minute 1,2,4,8,10,20,40
// 28:    1 Bit   Paritiy Minute - Bit 21-27
// 29-34: 6 Bits  Stunde 1,2,4,8,10,20
// 35:    1 Bit   Parity Stunde - Bit 29-34
// 36-41: 6 Bits  Tag 1,2,4,8,10,20
// 42-44: 3 Bits  Wochentag 1,2,4 - 1=Mo .. 7=So
// 45-49: 5 Bits  Monat 1,2,4,8,10
// 50-57: 8 Bits  Jahr 2005+ 1,2,4,8,10,20,40,80
// 58:    Paritiy Datum - Bit 36-57
// 59:    nichts, Minutenende-Absenkung
//
// even parity .. ergänzen auf gerade anzahl bits

#endif
Vorteil durch Übergabearray - alles schön Übersichtlich fürs Verständnis ...

Einen "Fehler" hat meine Auswertung noch, meine Uhr wird nicht genau auf Sekunden eingestellt ... das mach ich noch, wenn ichs brauch.

Viel Spaß damit
Vajk