Ich wandle gerade mein DCF Signal Welches in einem 58fach Array liegt
(0-1) folgendermaßen um:
1
voiddcf_calc(void){
2
char*TestCRCOut;
3
is_dcf_ok=0;
4
dcf_calc_v=0;
5
6
if(dcf_bitmask[20]==1){
7
8
// Calc Stunde
9
dcf_Stunde=0;
10
if(dcf_bitmask[29]==1)dcf_Stunde=dcf_Stunde+1;
11
if(dcf_bitmask[30]==1)dcf_Stunde=dcf_Stunde+2;
12
if(dcf_bitmask[31]==1)dcf_Stunde=dcf_Stunde+4;
13
if(dcf_bitmask[32]==1)dcf_Stunde=dcf_Stunde+8;
14
if(dcf_bitmask[33]==1)dcf_Stunde=dcf_Stunde+10;
15
if(dcf_bitmask[34]==1)dcf_Stunde=dcf_Stunde+20;
16
17
// Calc Minuten
18
dcf_Minute=0;
19
if(dcf_bitmask[21]==1)dcf_Minute=dcf_Minute+1;
20
if(dcf_bitmask[22]==1)dcf_Minute=dcf_Minute+2;
21
if(dcf_bitmask[23]==1)dcf_Minute=dcf_Minute+4;
22
if(dcf_bitmask[24]==1)dcf_Minute=dcf_Minute+8;
23
if(dcf_bitmask[25]==1)dcf_Minute=dcf_Minute+10;
24
if(dcf_bitmask[26]==1)dcf_Minute=dcf_Minute+20;
25
if(dcf_bitmask[27]==1)dcf_Minute=dcf_Minute+40;
26
27
// Calc Datum Tag
28
dcf_Tag=0;
29
if(dcf_bitmask[36]==1)dcf_Tag=dcf_Tag+1;
30
if(dcf_bitmask[37]==1)dcf_Tag=dcf_Tag+2;
31
if(dcf_bitmask[38]==1)dcf_Tag=dcf_Tag+4;
32
if(dcf_bitmask[39]==1)dcf_Tag=dcf_Tag+8;
33
if(dcf_bitmask[40]==1)dcf_Tag=dcf_Tag+10;
34
if(dcf_bitmask[41]==1)dcf_Tag=dcf_Tag+20;
35
36
// Calc Datum Monat
37
dcf_Monat=0;
38
if(dcf_bitmask[45]==1)dcf_Monat=dcf_Monat+1;
39
if(dcf_bitmask[46]==1)dcf_Monat=dcf_Monat+2;
40
if(dcf_bitmask[47]==1)dcf_Monat=dcf_Monat+4;
41
if(dcf_bitmask[48]==1)dcf_Monat=dcf_Monat+8;
42
if(dcf_bitmask[49]==1)dcf_Monat=dcf_Monat+10;
43
44
// Calc Datum Jahr
45
dcf_Jahr=0;
46
if(dcf_bitmask[50]==1)dcf_Jahr=dcf_Jahr+1;
47
if(dcf_bitmask[51]==1)dcf_Jahr=dcf_Jahr+2;
48
if(dcf_bitmask[52]==1)dcf_Jahr=dcf_Jahr+4;
49
if(dcf_bitmask[53]==1)dcf_Jahr=dcf_Jahr+8;
50
if(dcf_bitmask[54]==1)dcf_Jahr=dcf_Jahr+10;
51
if(dcf_bitmask[55]==1)dcf_Jahr=dcf_Jahr+20;
52
if(dcf_bitmask[56]==1)dcf_Jahr=dcf_Jahr+40;
53
if(dcf_bitmask[57]==1)dcf_Jahr=dcf_Jahr+80;
54
55
crc_read=0;
56
if(crc_old_minute[0]==dcf_Minute+4){crc_read++;}
57
if(crc_old_minute[1]==dcf_Minute+3){crc_read++;}
58
if(crc_old_minute[2]==dcf_Minute+2){crc_read++;}
59
if(crc_old_minute[3]==dcf_Minute+1){crc_read++;}
60
61
crc_old_minute[3]=crc_old_minute[2];
62
crc_old_minute[2]=crc_old_minute[1];
63
crc_old_minute[1]=crc_old_minute[0];
64
crc_old_minute[0]=dcf_Minute+5;
65
66
// itoa(TestCRCOut,crc_read);
67
// UART1_Write_text(TestCRCOut);
68
69
70
if(crc_read>=3)
71
{
72
Tag=dcf_Tag;
73
Monat=dcf_Monat;
74
Jahr=dcf_Jahr;
75
76
Stunde=dcf_Stunde;
77
Minute=dcf_Minute;
78
sekunde=0;
79
is_dcf_ok=1;
80
}
81
}
82
}
Da selbstverständlich die Abfragen mit IF jede Menge speicher kostet,
würde ich dies sehr gerne etwas "anders" machen.
Hat jemand einen kleinen Tipp parat?!
Rene K. schrieb:> Hat jemand einen kleinen Tipp parat?!
Finde die Gemeinsamkeit, die all den Codesequenzen gemeinsam ist.
Du hast
beginnend ab einem bestimmten Arrayindex eine Anzahl x an 'Bits'.
Jedes darauffolgende Bit hat die doppelte Wertigkeit des
vorhergehenden, wobei es noch zwischen Einern und Zehnern zu
unterscheiden gilt.
dieses Wissen kann man in eine/zwei Funktionen zusammenfassen, so dass
sich zb folgende Auswertung ergibt
1
dcf_Stunde=DecodeZehner(dcf_bitmask,33,2)+
2
DecodeEiner(dcf_bitmask,29,4);
3
4
dcf_Minute=DecodeZehner(dcf_bitmask,25,3)+
5
DecodeEiner(dcf_bitmask,21,4);
6
7
dcf_Tag=DecodeZehner(dcf_bitmask,40,2)+
8
DecodeEiner(dcf_bitmask,36,4);
9
10
dcf_Monat=DecodeZehner(dcf_bitmask,49,1)+
11
DecodeEiner(dcf_bitmask,45,4);
12
13
dcf_Jahr=DecodeZehner(dcf_bitmask,54,4)+
14
DecodeEiner(dcf_bitmask,50,4);
Sieht doch schon viel besser aus :-)
Sieht man sich die Zahlen beim Aufruf etwas genauer an, dann findet man
noch mehr Gemeinsamkeiten. Zb hat man in allen Fällen immer 4 Stellen
für die Einer (also die volle Dröhnung), d.h. die einzelnen Fälle
unterscheiden sich nur in der Anzahl der Bits für dir Zehner.
Auch gibt es (natrülich) einen Zusammenhang, wo die Zehner-Bits
anfangen, wenn man den Index der Einer Bits kennt.
All das kann man ausnutzen, um eine einzige Funktion zu schreiben.
1
dcf_Stunde=Decode(dcf_bitmask,29,6);
2
dcf_Minute=Decode(dcf_bitmask,21,7);
3
dcf_Tag=Decode(dcf_bitmask,36,6);
4
dcf_Monat=Decode(dcf_bitmask,45,5);
5
dcf_Jahr=Decode(dcf_bitmask,50,8);
und jetzt siehst das doch schon richtig gut aus :-)
Und die Funktion Decode. Jetzt da wir wissen was sie machen muss, ist
sie ziemlich trivial.
Das wäre mir deutlich zuviel Schreibaufwand.
Schau dochmal die einzelnen Fälle an, sie machen doch immer das gleiche:
Abhängig vom Index (Sekunde) wird auf eine SRAM-Adresse ein Wert
addiert.
Also einfach ne Tabelle erstellen mit der Adresse und dem Wert, fertig.
Beitrag "DCF77 Uhr in C mit ATtiny26"
Und man muß nicht die Bits erst speichern, das Auswerten kann man in
"harter Echtzeit" machen.
Pro Bit hast Du eine volle Sekunde Zeit, da langweilt sich die CPU
entsetzlich.
Peter
redyszhrtjk schrieb:> Ob das besser ist?
Vielen Dank! Funktioniert wunderbar, der Code ist um einen enormen
Faktor zurückgegangen.
Peter Dannegger schrieb:> Und man muß nicht die Bits erst speichern, das Auswerten kann man in> "harter Echtzeit" machen.> Pro Bit hast Du eine volle Sekunde Zeit, da langweilt sich die CPU> entsetzlich.
Ist im Grunde richtig, aber wie du oben erkennen kannst, benötige ich
die Werte auch um eine 5fache logische Prüfung zu machen, ich hatte
einige ELV / Reichelt DCF Module, welche enorm gesaut haben auf der
Leitung.
Übrigens kann ich da die DCF Module von Pollin sehr empfehlen... die von
Pollin sind, man mag es kaum glauben, die stabilsten und
störunempfindlichsten DCF Modul die ich bekommen konnte, dicht gefolgt
von den ELV Dingern.