在实际应用中需要转换超过255的十六进制数转换为BCD码,如0x123456,但是我找了半天没找到解决问题的方式,找到了也有很多问题,所以自己在理解这些代码后自己写一个。
先来一个我之前找到的一个版本,这个版本的问题在于,超过99后,转换的BCD码就乱了,出现0->99->0->99->0->55->100->199->100->199->100->155->200…以此类推的这样的循环。后面看代码发现这个限制,0<hex_data<255,离谱,离了个大谱就。说明:下面这段代码是CSDN上找到最多的,但是,但是这段代码它转换超过0x63的数据后向前进的那一位就给省略了,这段代码有问题的是。
/*十六进制转换为bcd码
功能:将十六进制转换为bcd码
说明:转换的十六进制数的范围: 0<hex_data<0xff
*/
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;
}
然后我就自己写了第一个版本,支持四个字节的BCD码显示,能转换的十六进制数据范围为:0~ 0x99999999,对应十进制数范围为0~2576980377,返回值为32位的BCD码。代码如下:
/*十六进制转换为BCD码
功能:将十六进制转换为BCD码
传入参数:unsigned char类型的数组,数组最大只能有4个字节
说明:可转换的十进制数范围为:0~2576980377,即BCD码的99 99 99 99;
因为我这里使用的是四个字节表示BCD码,数据再大就需要再增加BCD码字节数了
因为定义的unsigned int类型的取值范围为:0~4294967295,理论上应该也是能达到这么大的,如果BCD码有5个字节显示的话
*/
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;
}
这段代码经过测试BCD码是正常一次递增的。
至此,如果是在嵌入式开发中使用,这个数据长度是够用的了。然后我在想在完善下写个支持范围更宽的版本。