Binär-Armbanduhr. Int to BCD - geht das so?

OP #6504435
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 (:
Angehängte Dateien:
Gast #6504454
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
Gast #6505297
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.
#6505360
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren