BCD in Dezimalwerte umrechnen

In einigen Bausteinen wird eine besondere Art der binären Codierung verwendet – der BCD-Code. Dabei werden Dezimalwerte, Stelle für Stelle, in 4-Bit große Binärecodes verwandelt. Diese Codierung ist vor allem in Systemen zur Zeitanzeige zu finden, wie z.B. einer sog. Real Time Clock oder im DCF77 Signal.

Ein BCD-codierter Wert kann vom ATMega128 nicht direkt verwendet werden. Daher ist es nötig, diese Information in einen Dezimalwert zu transformieren, bevor dieser für eine Anzeige auf einem LCD-Display oder weitere Berechnungen nutzbar ist. Natürlich ist auch eine Umwandlung vom Dezimalwert in einen BCD-Code notwendig.

Der Aufbau

Der BCD-Wert wird fast wie ein normaler Binärwert dargestellt. Jedoch wird beim BCD-Code jede Ziffer separat codiert, wobei nur vier Bits benötigt werden. Dadurch können je zwei Ziffern in einem Byte zusammengefasst werden. Die Wertigkeit pro Bit ist wie gehabt:

Bit 0  >>  1
Bit 1  >>  2
Bit 2  >>  4
Bit 3  >>  8

 Soll z.B. eine 5 codiert werden, lautet der BCD-Code 0101. Die verschiedenen Codes habe ich in der folgenden Liste aufgeführt:

BCD Codierung - Übersicht

BCD Codierung – Übersicht

Da jede Ziffer separat codiert wird, werden Dezimalwerte (BCD-codiert) von 00 bis 99 in einem Byte gespeichert. Das ist eigentlich eine große Verschwendung, da eine Binärzahl einen Dezimalbereich von 00 bis 127 abdecken kann. Moderne Mikrocontroller können auch nicht direkt mit BCD Werten rechnen, sondern benötigen eine Umwandlung in eine Binärinformation. Nach der Berechnung werden diese wieder in BCD zurück verwandelt.

BCD Codierung - Aufbau des BCD-Codes

BCD Codierung – Aufbau des BCD-Codes

Umrechnung

Bei einer einstelligen Zahl ist eine Umrechnung nicht nötig, aber sobald es um zwei Ziffern geht, ist die Umrechnung unvermeidlich. Am folgenden Beispiel versuche ich das mal zu verdeutlichen:

BCD Codierung - Unterschied des BCD- und Binär-Wertes

BCD Codierung – Unterschied des BCD- und Binär-Wertes

Bei der binären Codierung gibt es nicht nur vier Bits, sondern acht. Das Bit 4 hat hier eine Wertigkeit von 16, beim BCD-Code hätte es eine von 1, da dieses Bit das erste Bit der zweiten Ziffer ist. Das ist der Grund, warum die Umrechnung nötig ist.

BCD zu Dezimal umrechnen

Sicherlich gibt es eine Bitmanipulations-Methode, um den BCD-Code in eine Binäre-Information und damit in eine Dezimalzahl umwandeln zu können.  Aber es ich benutze die folgende Berechnung, für ein C-Programm, dass diese Umwandlung erledigt:

( BCD / 16 * 10 ) + (BCD % 16) = Dezimal

Sieht einfach aus, oder? Ich nehme einfach das Beispiel von letzten Bild und der Mikrocontroller erhält (über den I²C-Bus) den BCD-Wert 18. Hier ist zu beachten, dass dieser den Wert 24 (0001 1000) einliest. Er weiß schließlich nicht, dass es sich um einen BCD-Code handelt. Um aber die tatsächliche Information zu erhalten, wird dieser Wert mit der o.g. Formel umgewandelt.

Zwei Dinge könnten an dieser Stelle für Verwirrung sorgen. Zum Einen ist es das % in der Rechnung. Dies ist eine sogenannte Modulo-Operation, die den Rest einer Division zurück gibt. Im diesem Beispiel wird 24 durch 16 geteilt. 16 Passt einmal in 24 rein und es bleiben 8 übrig für die Berechnung der Kommastelle. Und diese 8 sind das Ergebnis der Modulo-Operation. Das Zweite ist die Tatsache, dass nur ganze Zahlen (Integer) verwendet werden. Kommastellen werden nicht berücksichtigt!

Das gesamte Beispiel sieht also wie folgt aus:

Dezimal = (24 / 16 * 10) + (24 % 16) =
Dezimal = (1,5 * 10) + (8)
Dezimal = 18

Da ist die gewünschte 18! Super, oder? 😉

Dezimal in BCD umrechnen

Natürlich gibt es auch eine Formel um den Weg in die andere Richtung gehen zu können. Damit ist es möglich, das Ergebnis von Berechnungen wieder an einen Baustein zu senden, der mit BCD-codierten Daten arbeitet. Ein schönes Bauspiel ist hierbei eine Real Time Clock an die Zeitdaten gesendet werden um die Uhrzeit einzustellen.

( Dezimal / 10 * 16 ) + (Dezimal % 10) = BCD

Auch hier nehme ich das bekannte Beispiel und wandle eine dezimale 18 in eine BCD-codierte Zahl um.

BCD = (18 / 10 * 16) + (18 % 10) =
BCD = (1,8 * 16) + (8)
BCD = 24

Die 24 wird (z.B. über I²C) an eine Real Time Clock gesendet und dort als 18 verstanden. Eigentlich sendet der Mikrocontroller den Binärcode 0001 1000 (Dezimal = 24), was im BCD-Code einer 18 entspricht, was ich weiter oben bereits gezeigt habe.

Fazit

Bei der Umrechnung sind nur ein, zwei Besonderheiten zu beachten. Doch im Grunde ist es mit den beiden Formeln einfach und nachvollziehbar um beide Typen ineinander umzuwandeln.

In einem C-Programm würde ich die Formeln jeweils in eine Funktion packen und bei Bedarf aufrufen:

uint8_t BCDzuDezimal(uint8_t dez)
{
  return (dez / 16 * 10) + (dez % 16);
}
uint8_t DezimalzuBCD(uint8_t bcd)
{
  return (bcd/10*16) + (bcd%10);
}

Aufgerufen werden die Funktionen mit:

a = BCDzuDezimal (24);   // Schreibt 18 in Variable a
a = DezimalzuBCD (18);   // Schreibt 24 in Variable a

Jetzt sollte die Umwandlung kein Problem mehr darstellen.

Alles Gute, Timo

 

PS: Vor kurzem habe ich das Real-Time-Clock Modul (Version 1.0) erstellt, das hervorragend in das GREETBoard System passt und auch in eigene Projekte integriert werden kann. Unter anderem lässt es sich gut in eine „Breadboard“-Schaltung einfügen. Hier der Link zum Shop:

linkzumshop

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.