Tänker jag rätt nu? HEX till BCD

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
cyprox
Inlägg: 81
Blev medlem: 1 december 2004, 14:49:35

Tänker jag rätt nu? HEX till BCD

Inlägg av cyprox »

Till o börja med vill jag be om ursäkt till de personer som får scrolla i sidled. Hoppas det går bra ändå.
Jag håller på att programmera ett program till en MCU där jag får in ett hexadecimalt värde från ett register (från en A/D-omvandlare i detta fall) och vill omvandla det till BCD för att kunna lägga ut det på en 7-segments LCD.
Detta är den kod jag har skrivt för omvandlingen. Tyvärr har jag inte fårr displayerna än så jag kan inte se resultatet. Men någon här kanske kan se om jag har gjort någon tankevurpa. Själv är jag osäker på om jag har gett varblerna rätt datatyper för ändamålet samt om jag castar rätt.

Kod: Markera allt

  unsigned char hex;                    /* Value in 8-bit Hexadecimal notation (0x00-0xFF) */
  unsigned char bcd[3];                 /* Array containig the Value in Binary Coded Decmal notation ({0b0000,0b0000,0b0000}-{0b0010,0b0101,0b0101}) */
  unsigned short int valFac;            /* Factor containing the value of each bit (0,1) */
  unsigned short int sigFac;            /* Factor containing the significance of each bit (1,2,4,8,16,32,64,128) */
  unsigned short int prod;              /* The product of valFac and sigFac muliplied */
  unsigned short int dec;               /* Value in Decimal notation (0-255)*/
  unsigned short int i;                 /* Counter for loops. Used in both loops */
  
  .
  .
  .

    if (ADSCR & (1 << 7)) {             /* If a conversion was completed (if COCO is set) */
      hex = ADR;                        /* Load Value of A/D data register into hex*/
      dec = 0;                          /* Reset dec */
      bcd = {0, 0, 0};                  /* Reset bcd */
      for (i = 0; i < 8; i++){                                        /* For every bit in hex */
        valFac = (unsigned short int)(hex & (unsigned char)(1 << i)); /* Assign to valFac the value of the current bit in binary*/
        sigFac = (unsigned short int)(1 << i);                        /* Assign to sigFac the significance of the current bit */
        prod = valFac * sigFac;                                       /* Multiply valFac and sigFac to get the value of current bit in decimal*/
        dec += prod;                                                  /* Add the decimal value of every bit to get value of hex in decimal*/
      }                                                               /* Dec now contains the original hex value in decimal notation*/
      for (i = 0; i < 3; i++){                /* For the number of positions needed to display decimal value */
        bcd[i] = (unsigned char)(dec % 10);   /* Assign least significant number in decimal to corresponding element in bcd-array*/
        dec /= 10;                            /* Shift numbers in decimal one position right (to become less signinficant) */
      }                                       /* bcd-array now contains original hex value in BCD (each number in the corresponding element according to significance) */
    }
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Till o börja med vill jag be om ursäkt till de personer som får scrolla i sidled.

Hade du fixat det först så hade du sluppit be om ursäkt... :-)

Sen tror jag att du har rört ihop det...
Varför gör du skillnad på variablerna med avseende på hex/dec ?
Alla integers är binära, hex/dec har bara med preentation att göra...

Dina variabler "hex" resp "dec" kommer så vitt jag ser att innehålla
exakt samma värde.
cyprox
Inlägg: 81
Blev medlem: 1 december 2004, 14:49:35

Inlägg av cyprox »

så egentligen skulle det räcka med detta?

Kod: Markera allt

  unsigned char hex;
  unsigned char bcd[3];
  unsigned short int i;

  .
  .
  .

  if (ADSCR & (1 << 7)) {
    hex = ADR;
    bcd = {0, 0, 0};
    for (i = 0; i < 3; i++){
      bcd[i] = (unsigned char)(hex % 10);
      hex /= 10;
    }
  }
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Testa så får du se !
Jag vet inte om den där koden är korrekt,
jag bara undrade över du du tänkte med hex/dec...
cyprox
Inlägg: 81
Blev medlem: 1 december 2004, 14:49:35

Inlägg av cyprox »

Har lite problem att testat koden nu eftersom jag inte har fått displayen att visa detpå än. Jag har ett gäng LEDs som jag kan kolla på varje enskild siffra med iaf.
Vet inte riktigt varför jag försökte göra om till dec först... jag tänkte nog inte riktigt.

Tack för hjälpen iaf
cyprox
Inlägg: 81
Blev medlem: 1 december 2004, 14:49:35

Inlägg av cyprox »

Testade med den senaste koden som jag skrev efter att ha tagit bort det onödiga dvs. hex till dec-omvandlingen på LEDarna. Kan meddela att det fungerar bättre nu än det gjorde förut. Det blir rätt :)
Troligtvis hade jag nåt fel i den förra koden som ställde till det, Nu försvann det och koden blev mer lättläst
Tack Sodjan!
Användarvisningsbild
kireslin
Inlägg: 18
Blev medlem: 7 december 2007, 15:16:12
Ort: Finspång

Inlägg av kireslin »

Hade du i din första listning skrivit:
valFac = (unsigned short int)((hex >> i) & 1);
så hade det fungerat.
Men det riktigt onödiga då, som Sodjan upplyste om, är att variabeln 'dec' hade fått exakt samma värde som variabeln 'hex'.

Så kör på din bantade kod. Den ser korrekt ut :)
Användarvisningsbild
psynoise
EF Sponsor
Inlägg: 7230
Blev medlem: 26 juni 2003, 19:23:36
Ort: Landvetter

Inlägg av psynoise »

Har inte koll på din kod då jag inte kan C, men att få HEX till BCD borde inte vara så svårt för 8 bitar. En algoritm är att visa talet direkt om det är under 10, om det är över plusar man till 6, vilket borde få segmentdisplayen att visa rätt.
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

BCD är inte det samma som att omvandla till decimal form!

BCD är ett sätt att spara tal där man använder 4 bits per siffer, alltså är 0x99 det samma som 99 decimalt.

Men är det till utläsning är den enklaste form att varje tecken får en byte och det är inte BCD.

Att man sedan kan göra det på olika sätt i C är en annan sak:
char Buffer[10];
sprintf(Buffer, "%u", ADC_Value);
ger det i text, vill du ha ett visst format går det bra också:
sprintf(Buffer, "%3u", ADC_Value);
Det ger 3 tecken, fylls på med mellanslag om talet är mindre än 3 tecken, vill du ha att talen börjar till vänster och fylls på i slutet istället:
sprintf(Buffer, "%-3u", ADC_Value);

Eller vill du bara konvertera utan att kalla in printf-funktionen är den rätta väg som det beskrivs:
Dela med 10, ta resten som lägsta siffer, peka på nästa "lägsta siffer" och upprepa till talet är 0.
cyprox
Inlägg: 81
Blev medlem: 1 december 2004, 14:49:35

Inlägg av cyprox »

Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Ja, den länken förklarar BCD. Men exakt vad är det du vill ha sagt med att lägga in länken? Jag förstår inte...
cyprox
Inlägg: 81
Blev medlem: 1 december 2004, 14:49:35

Inlägg av cyprox »

Sorry, my mistake... Det var jag som missuppfattade en grej. Jag la in länken för att förklara vad jag menar med BCD, men det var jag själv som missuppfattade vad jag hade läst.
Skriv svar