在实际应用中需要转换超过255的十六进制数转换为BCD码,如0x123456,但是我找了半天没找到解决问题的方式,找到了也有很多问题,所以自己在理解这些代码后自己写一个。 然后我就自己写了第一个版本,支持四个字节的BCD码显示,能转换的十六进制数据范围为:0~ 0x99999999,对应十进制数范围为0~2576980377,返回值为32位的BCD码。代码如下: 这段代码经过测试BCD码是正常一次递增的。
先来一个我之前找到的一个版本,这个版本的问题在于,超过99后,转换的BCD码就乱了,出现0->99->0->99->0->55->100->199->100->199->100->155->200…以此类推的这样的循环。后面看代码发现这个限制,0
uint32_t hex2bcd(unsigned char hex_data)
{
unsigned int bcd_data;
unsigned char temp;
temp = hex_data % 100;
bcd_data = ((unsigned int)hex_data) / 100 << 8;
bcd_data = bcd_data | ((temp / 10) << 4);
bcd_data = bcd_data | (temp % 10);
return bcd_data;
}
uint32_t HEX2BCD(unsigned char *HEX_Table)
{
unsigned int temp_data,bcd_data;
unsigned char temp,temp1;
temp_data = (HEX_Table[0] << 24) | (HEX_Table[1] << 16) //这里将四个字节的十六进制数组合为一个32位的数,方便接下来的处理
| (HEX_Table[2] << 8) | HEX_Table[3];
temp = temp_data / 1000000;
temp1 = temp % 100;
bcd_data = ((unsigned int)temp) / 100 << 28; //这个值再向前进位无意义,但是这里左移32位会提示警告,所以左移28位消除警告,接下来会被下面的数替代
bcd_data = bcd_data | ((temp1 / 10) << 28); //这里
bcd_data = bcd_data | (temp1 % 10)<<24;
BCD_Table[0] = bcd_data >> 24;
temp = (temp_data % 1000000) / 10000;
temp1 = temp % 100;
bcd_data = bcd_data | ((unsigned int)temp) / 100 << 24;
bcd_data = bcd_data | ((temp1 / 10) << 20);
bcd_data = bcd_data | (temp1 % 10) << 16;
temp = (temp_data % 10000) / 100;
temp1 = temp % 100;
bcd_data = bcd_data | ((unsigned int)temp) / 100 << 16;
bcd_data = bcd_data | ((temp1 / 10) << 12);
bcd_data = bcd_data | (temp1 % 10) << 8;
temp = temp_data % 100;
temp1 = temp % 100;
bcd_data = bcd_data | ((unsigned int)temp) / 100 << 8;
bcd_data = bcd_data | ((temp1 / 10) << 4);
bcd_data = bcd_data | (temp1 % 10);
return bcd_data;
}
至此,如果是在嵌入式开发中使用,这个数据长度是够用的了。然后我在想在完善下写个支持范围更宽的版本。



