www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit uint32_t


Autor: Luky (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe eine Routine um einen 24Bit Wert dezimal darzustellen.
Leider funktioniert das Teil bei größeren Zahlen nicht so wie gewünscht 
und ich komme einfach nicht auf den Fehler... Es werden dann 
irgendwelche Sonderzeichen angezeigt und nicht die Zahlenwerte.
void print_number_u24(uint32_t d) {
    uint8_t zehner=0, hunderter=0, tausender=0, zehntausender=0, hunderttausender=0, millionste=0, zehnmillionste=0;

  while ( (uint32_t) d >= 10000000UL) {
    d = (uint32_t) d - 10000000UL;
    zehnmillionste++;
  }
  while ( (uint32_t) d >= 1000000UL) {
    d = (uint32_t) d - 1000000UL;
    millionste++;
  }
  while ( (uint32_t) d >= 100000UL) {
    d = (uint32_t) d - 100000UL;
    hunderttausender++;
  }
  while (d >= 10000) {
    d = (uint16_t) d - 10000;
    zehntausender++;
  }
  while (d >= 1000) {
    d = (uint16_t) d - 1000;
    tausender++;
  }
  while (d >= 100) {
    d = (uint16_t) d - 100;
    hunderter++;
  }
  while (d >= 10) {
    d = d - 10;
    zehner++;
  }

  uint8_t printzero=0;
  if (zehnmillionste) {
    print(zehnmillionste);
    printzero = 1;
  }
  if (millionste || printzero) {
    print(millionste);
    printzero = 1;
  }
  if (hunderttausender || printzero) {
    print(hunderttausender);
    printzero = 1;
  }
  if (zehntausender || printzero) {
    print(zehntausender);
    printzero = 1;
  }
  if (tausender || printzero) {
    print(tausender);
    printzero = 1;
  }
  if (hunderter || printzero) {
    print(hunderter);
    printzero = 1;
  }
  if (zehner || printzero) {
    print(zehner);
  }
  print(d);
}

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
print(0) druckt nicht '0' (=0x30) sondern 0x00.
Also: print('0'+zehner).

Autor: Johannes Schmid (jhs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Was macht den print()?

Außerdem halte ich deine ganzen casts (uint32t, uint16t) für 
überflüssig.

Gruß
Johannes

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
darf ich fragen warum du nicht einfach ultoa benutzt?

(Und schmeiss die casts raus. Die braucht kein Mensch)

Autor: Jean (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>while (d >= 10000) {
>    d = (uint16_t) d - 10000;
>    zehntausender++;
>  }

Das geht in die Hose, was machste wenn die vorherige Zahl z.B. 190.000 
war und du 100.000 abziehst. Dann castest du 90.000 nach uint16 uund du 
schneidest die oberen Bytes ab.

Gruß

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Solche Konvertierungen sind übrigens rückwärts effizienter. Die Ziffern 
von rechts nach links konvertieren und anschliessend per strrev 
umdrehen.

Autor: Luky (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein print addiert selber '0'. Das funktioniert schon. Und für 16Bit 
Zahlen geht das Ganze ja auch. Nur wenn ich eine 32Bit Zahl umwandeln 
will läufts schief...
Für Alternativen bin ich aber immer offen, mit ultoa habe ich auf dem 
AVR noch nie herumgespielt. Mal probieren...

Autor: Robert L. (manateemoo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht hilfts

#include "stdafx.h"

#define byte  unsigned char
#define word  unsigned short
#define dword  unsigned int

void dword2string(dword dwNbr,char * pString)
{
  dword dwDigit;
  dword dwDivisor = 1000000000;  //because range 0..4294967296
  bool boShowZero = false;

  while(dwDivisor)
  {
    dwDigit = dwNbr / dwDivisor;
    dwNbr -=  dwDigit * dwDivisor;
    dwDivisor /= 10;
    if ( (0 != dwDigit) || ( true == boShowZero ) )
    {
      *pString = dwDigit + '0';
      pString++;
      boShowZero = true;
    }
  }
  *pString = 0;
}


char mySting[12];

int main(void)
{
  dword2string(123056,mySting);
  printf(mySting);

  return 0;
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Luky schrieb:
> Mein print addiert selber '0'. Das funktioniert schon. Und für 16Bit
> Zahlen geht das Ganze ja auch. Nur wenn ich eine 32Bit Zahl umwandeln
> will läufts schief...

Was jetzt?
Weiter oben war noch von maximal 24 Bit die Rede.
Du hast in deinem Code keinerlei Vorkehrungen getroffen, wenn die Zahl 
größer als 99999999 wird.

Autor: Luky (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz Buchegger:
Ja ein 24Bit ADC spuckt halt 24 Bit aus, die muss man aber leider in 
32Bit abspeichern da es kein uint24_t gibt.
Trotzdem kommen da keine Zahlen > 16777216 raus...
Das ist aber nicht das Problem. Das Problem entsteht sobald die Zahl 
größer 2^16 wird...

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.