I am trying to use the following code to convert 2 digit ASCII numbers to BCD number, for setting RTC Clock DS1307.
unsigned char ASCII_TO_BCD(unsigned char ascii_text[2]) { unsigned char bcd_value; ascii_text[0] &= 0x0F; // set high nibble(3) to 0 (may not be needed) ascii_text[0] <<= 4; // shift lower nibble to higher ascii_text[1] &= 0x0F; // set high nibble(3) to 0 (may not be needed) bcd_value = ascii_text[0] | ascii_text[1]; // mix both to get BCD return bcd_value; }
When I pass '12' to the function, 0x33 is returned instead of 0x12. Is something wrong in this code? Thanks.
use "-'0'" to convert ASCII characters to numbers ('1' ->1, 'n'->n), on which the BCD transform should be made - not the ASCII values themselves!
try this.
unsigned char ASCII_TO_BCD(unsigned char ascii_text[2]) { unsigned char bcd_value; // left side if(ascii_text[0] >= '0' && ascii_text[0] <= '9') // 0-9 range { bcd_value = ( ascii_text[0] - 48) << 4 ; // 48 for '0' ASCII offset } else if (ascii_text[0] >= 'A' && ascii_text[0] <= 'F') // A-F range { bcd_value = ( 10 + ascii_text[0] - 65 ) << 4 ; // 65 for 'A' ASCII offset } else if (ascii_text[0] >= 'a' && ascii_text[0] <= 'f') // a-f range { bcd_value = ( 10 + ascii_text[0] - 97) << 4 ; // 97 for 'a' ASCII offset } // right side if(ascii_text[1] >= '0' && ascii_text[1] <= '9') // 0-9 range { bcd_value |= ( ascii_text[1] - 48); // 48 for '0' ASCII offset } else if (ascii_text[1] >= 'A' && ascii_text[1] <= 'F') // A-F range { bcd_value |= ( 10 + ascii_text[1] - 65) ; // 65 for 'A' ASCII offset } else if (ascii_text[1] >= 'a' && ascii_text[1] <= 'f') // a-f range { bcd_value |= ( 10 + ascii_text[1] - 97 ) ; // 97 for 'a' ASCII offset } return bcd_value; }
Thank you Sir! It is perfectly working. I am not using the alphabets a-f or A-F. Only numbers are used. So I tried skipping the 'if-else if', but it is not working. I will use the code as it is for now, & will study it later on.
unsigned char bcd_value; bcd_value = ( ascii_text[0] - 48) << 4 ; // 48 for '0' ASCII offset bcd_value |= ( 10 + ascii_text[1] - 97 ) ; // 97 for 'a' ASCII offset return bcd_value;
I am also not getting why my code(which I posted) was not working. Anyway, THANK YOU VERY MUCH.
It is possible to appease a crocodile? Imagine the swarms of lazy, stupid, uneducated and rude idiots that are going to come down here asking for free code now that they see such a noble act of charity. Well done christian crosa, well done.
No Sir, I am not asking for free code. If you have read my post properly, I was asking to spot the mistake in my code. I even don't use any code in my design until I understand it. That's why I specially mentioned that I will use the code as it is for now, & will study it later on.
I was not specifically referring to you.
Now if you only use digits (0..9) - why then did you suddenly include the one line that makes use of character 'a' and was intended for the hexadecimal range 'a' .. 'f'?
Next thing - the guy who did give you example code does something I don't like:
bcd_value = ( ascii_text[0] - 48) << 4 ; // 48 for '0' ASCII offset
ascii_text contains characters ('0', '1', ... '9') 48 is a magic number that requires the comment "48 for '0' ASCII offset".
So a comment is explicitly needed just because the code is mixing between characters and the ordinal numbers of characters.
It is way better to write:
bcd_value = ( ascii_text[0] - '0') << 4 ;
Suddenly, no comment is needed since there is no longer any magic value 48 to explain.
There is a big reason why the C language allows us to perform mathematical operations directly using characters.
Thanks Per, I had used wrong line of code. I also changed 48 to '0'. Certainly it is more readable & understandable.
No problem.
Try some other arguments besides "12", and maybe you'll notice a pattern...
It fails because of the difference between what you think an array-type function argument as in
void func(int in[2])
does, and what actually happens. You believe this behaves vaguely like
void func(int in1, int in2)
while it really is equivalent to
void func(int *in)
I'll also venture an educated guess that in the actuall call of your function, which you didn't show, the argument is a string literal, i.e. it looks like this:
result = asciitobcd("12");
, and that changing the call to
{ unsigned char tempstr[] = "12"; result = asciitobcd(temp);}
magically cures it.
A note to the experts in here: please don't spoil the OP's a-ha! experience. Let him figure this one out for himself.