Offline
Newbie
Karma: 0
Posts: 25
|
 |
« on: April 03, 2011, 11:32:22 pm » |
Hi, I am trying to convert a decimal value to the corresponding BCD code. However, this seems not to be working at all, because only gives the 'tens' part and the 'unit' is lost. Such as, 27 only return 2. I want the result into a 8-bit array (the result will not be greater than 99)... byte decToBcd(byte val) { return ( (val/10*8) + (val%10) ); }
|
|
|
|
« Last Edit: April 04, 2011, 08:27:16 am by SpcCode »
|
Logged
|
|
|
|
|
Global Moderator
Boston area, metrowest
Offline
Brattain Member
Karma: 240
Posts: 16465
Available for Design & Build services
|
 |
« Reply #1 on: April 03, 2011, 11:40:10 pm » |
So you want 27 for example to come back as 0010 0111? (2 & 7)?
and 99 would be 1001 1001 (9 & 9)?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #2 on: April 03, 2011, 11:45:51 pm » |
So you want 27 for example to come back as 0010 0111? (2 & 7)?
and 99 would be 1001 1001 (9 & 9)?
Correct.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Boston area, metrowest
Offline
Brattain Member
Karma: 240
Posts: 16465
Available for Design & Build services
|
 |
« Reply #3 on: April 03, 2011, 11:49:59 pm » |
This is kinda crude, but could be a way to do it given the assumption above:
x = 0 stop = 0 while (x<10 and stop = 0){ value = value - x*10 // reduce by 10, keep count, stop when value is <10 if (value < 10){ upperbyte = x stop = 1} else {x=x+1} } lowerbyte = (value, HEX)
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Boston area, metrowest
Offline
Brattain Member
Karma: 240
Posts: 16465
Available for Design & Build services
|
 |
« Reply #4 on: April 03, 2011, 11:56:28 pm » |
Thinking a little more, that doesn't quite do it.
maybe need this to put the two together
lowerbyte = value & 0x0F // AND forces upper bits low, leaves hex value in lower nibble upperbyte = x<<4 // moves the found nibble into the upper bits newbyte = upperbyte | lowerbyte // OR them together
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #5 on: April 03, 2011, 11:57:29 pm » |
This is kinda crude, but could be a way to do it given the assumption above...
I added that code, but for some reason is not showing anything on the Serial Monitor? int x = 0; int sstop = 0; byte upperbyte; byte lowerbyte; byte newbyte; while (x<10 and sstop == 0) { DecResult = DecResult - x*10; // reduce by 10, keep count, stop when value is <10 if (DecResult < 10) { upperbyte = x; sstop = 1; } else { x=x+1; } } lowerbyte = DecResult & 0x0F; // AND forces upper bits low, leaves hex value in lower nibble upperbyte = x<<4; // moves the found nibble into the upper bits newbyte = upperbyte | lowerbyte; // OR them together Serial.print("Result: "); Serial.println(newbyte, BYTE);
|
|
|
|
« Last Edit: April 04, 2011, 12:00:21 am by SpcCode »
|
Logged
|
|
|
|
|
Global Moderator
Boston area, metrowest
Offline
Brattain Member
Karma: 240
Posts: 16465
Available for Design & Build services
|
 |
« Reply #6 on: April 04, 2011, 12:03:24 am » |
It could be creating non-printing characters. Try using HEX instead of BYTE.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #7 on: April 04, 2011, 12:19:01 am » |
It could be creating non-printing characters. Try using HEX instead of BYTE.
Thanks ! I am trying now to display the upperbyte but it says that is zero Serial.print("Lowerbyte: "); Serial.println(lowerbyte, HEX); Serial.print("Upperbyte: "); Serial.println(upperbyte, HEX);
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Boston area, metrowest
Offline
Brattain Member
Karma: 240
Posts: 16465
Available for Design & Build services
|
 |
« Reply #8 on: April 04, 2011, 12:28:44 am » |
I gotta get to bed.
Try putting some ()s in the while test:
while ((x<10) && (sstop == 0)){
Concept seems straight forward tho, yes? Keep playing with the code, you'll get there.
G'night.
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5453
Strongly opinionated, but not official!
|
 |
« Reply #9 on: April 04, 2011, 12:42:04 am » |
byte decToBcd(byte val) { return ( (val/10*8) + (val%10) ); } I don't see much wrong with that other than that the "8" should be a "16", and maybe some more parens: byte decToBcd(byte val) { return ( (val/10)*16) + (val%10) ); }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #10 on: April 04, 2011, 12:56:03 am » |
I gotta get to bed. Try putting some ()s in the while test: while ((x<10) && (sstop == 0)){ Concept seems straight forward tho, yes? Keep playing with the code, you'll get there. G'night. You give me the idea. I made this way and works perfect. I will improve it tomorrow. int upint = 0; int lowint = 0; int upbits[4] = {0,0,0,0}; int lowbits[4] = {0,0,0,0}; upint = DecResult/10; lowint = DecResult%10; //Converting Decimal to Binary for (int i=3; i >= 0; i--) { upbits[i] = upint % 2; upint = upint/2; lowbits[i] = lowint % 2; lowint = lowint/2; } byte Result[8] = {0,0,0,0,0,0,0,0}; // Reorganizing the bits Result[0] = lowbits[3]; Result[1] = lowbits[2]; Result[2] = lowbits[1]; Result[3] = lowbits[0]; Result[4] = upbits[3]; Result[5] = upbits[2]; Result[6] = upbits[1]; Result[7] = upbits[0];
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 87
Posts: 9371
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #11 on: April 04, 2011, 02:12:54 am » |
I want the result into a 8-bit array (the result will be greater than 99)... byte decToBcd(byte val) { return ( (val/10)*16) + (val%10) ); }
// macro version #define DEC2BCD(dec) (((dec / 10) << 4) + (dec % 10))
works for values 0..99, how for bigger values 100-255?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Online
Brattain Member
Karma: 137
Posts: 19006
I don't think you connected the grounds, Dave.
|
 |
« Reply #12 on: April 04, 2011, 02:18:39 am » |
how for bigger values 100-255? I don't understand the question - you can't fit three BCD digits in a byte.
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 87
Posts: 9371
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #13 on: April 04, 2011, 02:39:09 pm » |
@AWOL The input of the function can ....
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 39
|
 |
« Reply #14 on: April 04, 2011, 05:50:30 pm » |
Not sure I understand the question. Do you mean your decimal interpretation of a value in a register? ie does "15" =0x0F? isn't the example "27" stored internally as 0x1B? if so then what you want is Binary to BCD. Here is my take on using the ADD3 algorithm for converting binary to BCD. I only needed two BCD digits but it can be easily expanded. //-------------- binary to BCD using add3 algorithm ----------- byte binaryToBcd(byte binSource){ byte bcdResult=0;
byte tempA=0; byte tempB=0; byte tempC=0;
for (int y=0;y<8;y++){ tempC=binSource & B10000000; binSource=binSource<<1; bcdResult=bcdResult<<1; if(tempC>0){ bcdResult=bcdResult | B00000001; }
if (y<7){ //don't check or do add 3 on last shift tempA=bcdResult & B00001111; //check lo nibble if (tempA >= 5) { bcdResult=bcdResult+3; }
tempB=bcdResult&B11110000; tempB=tempB>>4; // check hi nibble if(tempB>=5) { tempB=tempB+3; }
tempB=tempB<<4; tempA=bcdResult & B00001111; bcdResult= tempB | tempA ; // reassemble nibbles } } return bcdResult;
|
|
|
|
|
Logged
|
|
|
|
|
|