Keil™, An ARM® Company

Discussion Forum

Need BINARY to BCD function

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Adi Sapner
Posted
11-Dec-2004 18:28 GMT
Toolset
C51
New! Need BINARY to BCD function
Hi,

Does anyone know how to convert a BINARY 8 bit to a 2 digit packed BCD.

Example if I have value 0x0C (wich is 12 decimal) the result will be 12 or a char value of 0x12.


thank you,

Adi,
Read-Only
Author
Graham Cole
Posted
13-Dec-2004 09:09 GMT
Toolset
C51
New! RE: Need BINARY to BCD function
This wouldn't be homework would it?

Firstly, an 8-bit value will be in the range 0 to 255, so obviously some values require more than 2 decimal digits.

To convert a value in the range 0..99, simply divide the value by 10 to obtain the most significant digit and take the modulo 10 value to obtain the least significant digit. The DIV instruction will all this in one go.

Compacting two digits into one byte requires moving some bits and ORing the results together.

To convert a decimal digit to ASCII, you just have to add a magic value.
Read-Only
Author
Adi Sapner
Posted
13-Dec-2004 14:20 GMT
Toolset
C51
New! RE: Need BINARY to BCD function
Hi,

Thanks for the HELP. No its not homework...I finished school long time ago :-) It was for communicating with a DALLAS RTC DS1337.

Is your code better than this one ? I mean will it run faster ?

Because I didn't use the MODULO 10, here is what I did:

char bin2BCD8(char cValue)
{
char cDig10=0;
char cDig1=0;
char cTemp;
cTemp=cValue; // Backup the value
do{
cTemp=cTemp-10;
if(cTemp<0)
{
break;
}
else
{
cDig10++;
}
}while(1);
cDig1=cValue-(cDig10*10);
cDig10=(cDig10<<4)|cDig1;
return cDig10;
}
Read-Only
Author
Ingvar Kreft
Posted
13-Dec-2004 14:30 GMT
Toolset
C51
New! RE: Need BINARY to BCD function
Hi
unsigned char chartobcd(unsigned char n)
{
  return ((n / 10) << 4) | (n % 10);
}
Read-Only
Author
erik malund
Posted
13-Dec-2004 14:37 GMT
Toolset
C51
New! danger af assumptions
the above should be
unsigned char chartobcd(unsigned char )
{
  if (n >99) crash();
  return ((n / 10) << 4) | (n % 10);
}

While the code, indeed, works, any function that can not handle all values of the input (255 for a byte, ffff for an int) should trap invalid input values. Bugs occuring from someone seeing the above function prototyped and use it can be lenghty to trap.

Erik
Read-Only
Author
Adi Sapner
Posted
13-Dec-2004 14:50 GMT
Toolset
C51
New! RE: danger af assumptions
Hi,

WOW I'm learning from the PRO...your code seems very compact.

I will try it. But will I get a packed BCD value ?

I'll get back to you if I have some problems.

Thank you,

Adi,
Read-Only
Author
Stewart J Cort
Posted
13-Dec-2004 15:10 GMT
Toolset
C51
New! RE: danger af assumptions
will I get a packed BCD value ?

Yes, by "ORing" the two halves of the number together, you get a single byte, two digit BCD number.
Read-Only
Author
Hans-Bernhard Broeker
Posted
13-Dec-2004 16:15 GMT
Toolset
C51
New! RE: danger af assumptions
And now the add-on question for extra points: how many assembly instructions is the minimum this functionality can be achieved in? You may assume all inputs are already in the correct registers, and it doesn't matter where the output is, as long as it's somewhere.
Read-Only
Author
J. Lehmo
Posted
15-Dec-2004 10:41 GMT
Toolset
C51
New! RE: danger af assumptions
But what is the more interesting value - the number of assembly instructions or code efficiency? A DIV and MODULO takes very long, so it might be better to use some add-and-compare loops

Jochen
Read-Only
Author
Hans-Bernhard Broeker
Posted
15-Dec-2004 13:34 GMT
Toolset
C51
New! RE: danger af assumptions
A DIV and MODULO takes very long,

Indeed. And it's too many instructions, anyway ;-) So sorry, but no cigar yet.
Read-Only
Author
Ingvar Kreft
Posted
13-Dec-2004 14:58 GMT
Toolset
C51
New! RE: danger af assumptions
Hi
If a want to write a BCD number to a RTC, I prefear to do that check in the input routine, and that because of the different of input values.

year = 00 - 99
month = 01 - 12
day = 01 - 31
hour = 0 - 23
min = 0 - 59
sec = 0 - 59

Ingvar
Read-Only
Author
Brad Holeman
Posted
15-Dec-2004 15:38 GMT
Toolset
C51
New! RE: danger af assumptions
if (n >99) crash();

The above line (or something akin to it) is used thousands of times in all Microsoft products. They of course document better so their equivalent would be.

/* Randomly screw the customer so they purchase an upgrade. *.
if (user_is_doing_something_important)
{
   crash_horribly_and_do_not_save();
}

Next Thread | Thread List | Previous Thread Start a Thread | Settings