www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik [C][AVR] - Speicherschonende long zu BCD Konversation


Autor: Rubelus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin auf der Suche nach einer Resourcenschonenden Möglichkeit aus 
einer 'unsigned long' Variablen eine BCD Variable zu erzeugen. Im Grunde 
eine ltoa Anweisung würde schon reichen, jedoch bietet dies mir mein 
MicroC nicht an.

Oder noch einfacher wäre dies zu berechnen, jedoch scheitere ich dann 
schon an einer dreistelligen zahl :D Bis zwei Stellen kann man ja 
einfach noch den HEX mit einer 6 addieren, dann hörts aber irgendwie 
schon auf.

Jemand was parat?!

Jede einzelne Stelle herrauszusubtrahieren ist wahrscheinlich nicht die 
feine Englische Art oder?!

Autor: Frank Buss (foobar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also was genau möchtest du denn jetzt? ltoa wandelt in dezimal um, aber 
nicht im BCD-Format (zwei Ziffern pro Byte, im high-nibble und 
low-nibble codiert), sondern als Zeichenkette.

Hier mal ein Beispiel aus einem meiner Programme, direkt mit Ansteuerung 
einer 7-Segment Anzeige:
void showNumber(long number)
{
  long tests[] = { 100000, 10000, 1000, 100, 10 };
  unsigned char i;
  for (i = 0; i < 5; i++) {
    unsigned char c = 0;
    long test = tests[i];
    while (number > test) {
      c++;
      number -= test;
    }
    ledSetDigit(i, c);
  }
  ledSetDigit(5, number);
}

Kann man noch eleganter und kompakter schreiben. Kommt ganz drauf an, ob 
dein Microcontroller auch Multiplikation oder Division kann und wie 
schnell es sein muß. Auf einem kleinen 16fxx'er PIC, mit einigem anderen 
drumherum, ist das schon wieder fast zu langsam (nur maximal ein paar Hz 
Anzeigerate, mit Division, statt der Tabelle).

Autor: Rubelus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank Buss schrieb:
> Also was genau möchtest du denn jetzt? ltoa wandelt in dezimal um, aber
> nicht im BCD-Format (zwei Ziffern pro Byte, im high-nibble und
> low-nibble codiert), sondern als Zeichenkette.

Ja im Grunde schon, jedoch ist ja bis 1-0-0-1 je nibble das BCD Format 
identisch mit dem Hex Format, also eine 9 ist im Hex auch eine 9 - 
zumindest im Low/High Nibble. Momentan wandel ich die Daten z.b. 12345 
als in ein Char Array um 1-2-3-4-5 und sende diese dann zur 
Anzeige/Treiber. Quasi so ähnlich wie es deine Lösung ist, (itoa macht 
ja im Grunde auch nichts anderes)

Jedoch frage ich mich halt ob man es auch errechnen kann...

Autor: Frank Buss (foobar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, bis 9 stimmt das schon, daß das mit dem Hex-Format im Low-Nibble 
identisch ist. High-Nibble sehe ich jetzt nicht, da "1" im High-Nibble 
ja schon 16 dezimal bedeutet. Was meintest du mit 6 addieren im ersten 
Posting?

Aber wenn du Rechenleistung zuviel hast, kannst du natürlich auch jede 
Ziffer direkt berechnen. Hier mal eine nicht so sinnvolle Umsetzung, 
aber zumindest auch mit Unterdrückung von führenden Nullen :-)
char* itoaMalAnders(long value)
{
  static char buf[10];
  int i = -1;
  for (int j = 8; j >= 1; j--) {
    int p = (int) powf(10.0f, (float) j);
    int digit = (value % p) / (p / 10);
    if (i < 0) if (digit || j == 1) i++;
    if (i >= 0) buf[i++] = digit + '0';
  }
  buf[i] = 0;
  return buf;
}

Autor: Entwickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Resourcenschonenden

Willst Du den Regenwald schützen? Trinkwasser sparen? Erderwärmung 
stoppen?

Du bist ein junger Mensch und hast offensichtlich eine gewisse Scheu in 
der Codesammlung oder hier im Forum nach Beiträgen zu suchen die älter 
als fünf Jahre sind. Da wurde das Thema schon hinreichend verkaut. Die 
kürzeste Wandlungszeit betrugt 0,3761µs.
Ist es das, was Du suchst?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Frank Buss (foobar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner schrieb:
> Siehe Festkommaarithmetik

Ist aber noch verbesserungsfähig. Warum werden die führenden Nullen 
nicht direkt bei der Konvertierung unterdrückt? Ein ziemliches Gemurkse, 
erstmal prüfen, ob das Vorzeichen da ist, dann die folgenden führenden 
Nullen unterdrücken und dann erst die Ziffern ausgeben. Das ganze 
braucht man dann auch noch redundant je nach Ausgabekanal.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Frank Buss (Firma: IT4 Systems GmbH & Co. KG) (foobar)

>> Siehe Festkommaarithmetik

>Ist aber noch verbesserungsfähig. Warum werden die führenden Nullen
>nicht direkt bei der Konvertierung unterdrückt?

Lies den Artikel. Ausserdem geht es um Lehrzwecke, nicht die 1001. Kopie 
eines ultrakompakten printf().

MFG
Falk

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank Buss schrieb:
> Was meintest du mit 6 addieren im ersten
> Posting?

Er meint vermutlich, direkt BCD-Arithmetik. Z.B. bei der Addition zweier 
BCD-Zahlen muß jedes Nibble evtl. mit 6 addiert werden um eine 
BCD-Korrektur durchzuführen. Viele Mikrocontroller bieten einen 
Assembler-Behehl für die BCD-Korrektur an (für BCD Arithmetik). Das 
ganze in 'C' zu machen ist aber mehr als unnötig.

Beispiel:

  0x09  BCD 9
 +0x03  BCD 3
------
 =0x0C  <-- Fehler, kein BCD Wert mehr
 +0x06  BCD Korrektur
------
 =0x12  Ergebnis wieder BCD

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn man Rubelus' letzten Beitrag ansieht, weiß man, dass eigentlich gar 
kein BCD notwendig ist.
Beitrag "Mal wieder: C, AVR und das Bitshiften"

Nimm Peter Daneggers Ausgaberoutine und sende jeweils 4 Bits auf einmal.
Dann sparst Du Dir das kompaktieren von 2 Digits in ein Byte..

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.