Der Code ist recht aufwendig geworden, weiß jemand eine Optimierung ?
unsigned char parity_check_1 (unsigned char data, unsigned char parity_bit)
{
unsigned char parity;
data = dez_bcd (data); // data ohne Parity-Bit
data ^= parity_bit; // Wert in data hat gleiche Parität wie
// der Ausgangswert von data inklusive Parity-Bit
parity = (((((data>>4) | (data<<4)) ^ data) + 0x41) & 0x82) + 0x7E;
// parity = 0b1xxxxxxx, wenn data ungerade Anzahl an Einsen enthält
// parity = 0b0xxxxxxx, wenn data gerade Anzahl an Einsen enthält
// Parität muß "gerade" sein
return (!(parity&0x80)); // liefert 1 bei "gerader" Parität
}
Für Datum und Wochentag kannst Du Dir eine nette Eigenschaft der xor-Verknüpfung zu Nutze machen:
Die Parität von "x"
unsigned char x;
x = Tag ^ Monat ^ Jahr ^ Wochentag;
ist identisch mit der Parität über alle vier Werte. Damit hast Du wieder einen 8-Bit Wert, dessen Parität Du mit dem oben gezeigten Code überprüfen kannst.
Wenn Du Die Parität mit der von Dir gezeigten Methode überprüfen willst, würde ich schreiben:
unsigned char parity_check_2 (unsigned char data, unsigned char parity_bit)
{
unsigned char parity, x;
data=dez_bcd(data); // wandle in BCD und lade Prüfbyte
parity=0; // parity Zähler auf Null
for (x=8; x>0; --x)
{
if (data & 0x01)
parity++;
data >>= 1;
}
return ((parity & 0x01) == parity_bit);
}
Von der Codegröße her gibt es keinen großen Unterschied zwischen beiden Varianten. Mein Compiler erzeugt für
parity_check_1() 14 Words Code und für
parity_check_2() 18 Words (Funktionsaufruf von
dez_bcd() jeweils auskommentiert).
Der wirkliche Vorteil der ersten Variante liegt in der Ausführungsgeschwindigkeit:
unsigned char ok;
ok = parity_check_x (0x87, 1);
parity_check_1() benötigt 23 Befehlszyklen (inklusive Parameterübergabe, Funktionsaufruf und Rücksprung),
parity_check_2() hingegen 76 Befehlszyklen, also mehr als die dreifache Zeit.
Wenn Du die DCF77 Daten nur auf dem LCD anzeigen willst, könnte man auf die Umwandlung von BCD nach dezimal und wieder zurück verzichten. Für die Ausgabe auf dem LCD benötigt man letztendlich BCD Daten, die z.B. von printf erst wieder aus dem dezimalen Wert gewonnen werden müssen.
Viele Grüße
Bernd