Forum: Mikrocontroller und Digitale Elektronik Binär-Armbanduhr. Int to BCD - geht das so?


von Micha W. (blackxiiv)



Lesenswert?

Moin,

ich bastel gerade an einer Binär-Armbanduhr. Verwendet wird ein 
Atmega168P und eine RV-4162. Wie fast jede (oder sogar jede) RTC bekomme 
ich BCD-codierten Output. Das Auslesen der RTC, Umrechnen von BCD auf 
Binary/Int und Darstellen auf meinen Ports funktioniert bereits. Jetzt 
ist die Zeit natürlich nicht richtig. Das muss geändert werden!

Jetzt habe ich kurz nach "Binary to BCD" und "Int to BCD" gesucht und 
bin auf recht große Konstrukte gestoßen. Zum Umrechnen auf Binary habe 
ich ja bereits eine kleine Funktion gebaut, die offensichtig 
funktioniert und jetzt ist die Idee es andersrum auch so zu machen. In 
meinem Fall (eine Uhr) brauche ich ja "nur" 2-stellige Zahlen.
Hier meine Funktion:
1
int Sekunden_in_Binary(I2C_Read_Sekunden)
2
    {
3
    return (((I2C_Read_Sekunden >> 4) * 10) + (I2C_Read_Sekunden & 0x0F);
4
    }

Meine Idee für die Umrechnung zum Stellen der RTC:
1
int Sekunden_in_BCD(Neue_Sekunde_in_Binary)
2
    {
3
    return (((Neue_Sekunde_in_Binary / 10) << 4) | (Neue_Sekunde_in_Binary % 10));
4
    }

*Variablennamen fiktiv, weil Bastelobjekt und Code nicht vor Ort.

Kann ich das so machen? Gibts was fertiges von Atmel/Microchip (habe nix 
gefunden)? Wie gesagt - in meinem Fall nur 2-stellige Zahlen.
Ich habe leider gerade keine Möglichkeit das einfach so auszuprobieren.

Zur Belustigung noch ein paar Bilder vom Projekt (:

gruß, michi (:

von c-hater (Gast)


Lesenswert?

Micha W. schrieb:

> Ich habe leider gerade keine Möglichkeit das einfach so auszuprobieren.

Warum nicht? Das Atmel-Studio stellt doch für den Mega168P einen 
Simulator bereit. Da braucht man zum Ausprobieren nichtmal echte 
Hardware...

von Stefan F. (Gast)


Lesenswert?

Man könnte den Code auch mit irgendeinem anderen Compiler auf dem PC 
ausprobieren. Unter Linux mache ich das z.B. so:
1
#include <stdio.h>
2
3
int Sekunden_in_BCD(int Neue_Sekunde_in_Binary)
4
{
5
    return (((Neue_Sekunde_in_Binary / 10) << 4) | (Neue_Sekunde_in_Binary % 10));
6
}
7
8
int main()
9
{
10
    printf("Ergebnis: %02x\n", Sekunden_in_BCD(36));
11
}
1
gcc test.c 
2
./a.out 
3
Ergebnis: 36

von Micha W. (blackxiiv)


Lesenswert?

Coole, danke Dir.

Ja, werde bei Gelegenheit mal forschen, was auf dem MacOS so geht.

von Stefan F. (Gast)


Lesenswert?

Micha W. schrieb:
> Ja, werde bei Gelegenheit mal forschen, was auf dem MacOS so geht.

Das geht da bestimmt (fast) genau so. Musst nur den C Compiler 
installieren.

von W.S. (Gast)


Lesenswert?

Micha W. schrieb:
> In
> meinem Fall (eine Uhr) brauche ich ja "nur" 2-stellige Zahlen.

Das mag ja so sein, es ist aber dennoch Pfusch. Also schreibe dir lieber 
zwei saubere Funktionen, die binär nach bcd und bcd nach binär wandeln 
und dabei auch mit binär > 99 klarkommen.

Wie du das bei deiner Uhr hältst, ob also die BinToBCD(byte bin) sich in 
solchem Falle verhält, ist Geschmackssache. Entweder einfach die 
Hunderterstelle abschneiden oder (was ich für sinnvoller halte) in 
solchem Falle einfach als BCD 99 zurückliefern. Dann kann man nämlich an 
der Uhrzeit sofort sehen, wenn da mal was schief gelaufen sein sollte.

W.S.

von Maxim B. (max182)


Lesenswert?

Bei mir stehen dafür zwei Funktionen:
1
// gepackte bcd in bin
2
u8 bcdtochar(u8 num){
3
    return ((num/16 * 10) + (num % 16));
4
}
5
6
// bin in gepackte bcd
7
u8 dectobcd(u8 num){
8
    return ((num/10)<<4) + (num % 10);
9
}
Ach ja, noch typedefs in main.h:
1
typedef uint8_t   u8;
2
typedef  int8_t   s8;
3
typedef uint16_t  u16;
4
typedef  int16_t  s16;
5
typedef uint32_t  u32;
6
typedef  int32_t  s32;
7
typedef uint64_t  u64;
8
typedef  int64_t  s64;
9
typedef __uint24  u24;
10
typedef __int24  s24;

W.S. schrieb:
> Also schreibe dir lieber
> zwei saubere Funktionen, die binär nach bcd und bcd nach binär wandeln
> und dabei auch mit binär > 99 klarkommen.
>
> Wie du das bei deiner Uhr hältst, ob also die BinToBCD(byte bin) sich in
> solchem Falle verhält, ist Geschmackssache. Entweder einfach die
> Hunderterstelle abschneiden oder (was ich für sinnvoller halte) in
> solchem Falle einfach als BCD 99 zurückliefern. Dann kann man nämlich an
> der Uhrzeit sofort sehen, wenn da mal was schief gelaufen sein sollte.

Wenn das wirklich notwendig ist (wofür ich Zweifel habe), dann einfach
1
// bin in gepackte bcd
2
u8 dectobcd(u8 num){
3
   u8 temp = 0x99;
4
   if(num < 100) temp = ((num/10)<<4) + (num % 10);
5
   return temp;
6
}

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.