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.
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) */
}
> 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.
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.
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!
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'.
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.
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.
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.