什么是BCD码?
BCD码(Binary-Coded Decimal),用4位二进制数来表示1位十进制数中的0~9这10个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。
BCD码也称二进码十进数,BCD码可分为有权码和无权码两类。其中,常见的有权BCD码有8421码、2421码、5421码,无权BCD码有余3码、余3循环码、格雷码,其中最常使用的为8421码,下面所述的都是基于8421码。
BCD码的优点
相对浮点数,采样BCD码可保持数据精度,又可以免去CPU计算浮点所消耗的时间。
相对浮点数,BCD码使用二进制编码表示十进制编码,使得数字可读性更好。如数字1234.56,使用BCD码表示为0x123456。
相对字符串,BCD编码效率更高,如数字1234.56,使用字符串需7个字节,采用BCD只需3字节。
BCD码应用
数据传输编码。
仪器设备显示。
常用BCD数据格式转换
- BCD码转字符串
uint8_t bcd_to_integer_string(char* pDes, uint8_t* bcd_buf, uint8_t bcd_size)
{
uint8_t cnt = 0;
for (cnt = 0; cnt < bcd_size; cnt++)
{
pDes[cnt * 2 + 1] = NUM_TO_CHAR(bcd_buf[bcd_size - 1 - cnt] & 0x0f);
pDes[cnt * 2] = NUM_TO_CHAR((bcd_buf[bcd_size - 1 - cnt] >> 4) & 0x0f);
}
pDes[cnt * 2] = '\0';
return cnt * 2;
}
单元测试
static BOOL bcd_to_string_test1(void )
{
uint8_t bcd_buf[5] = { 0x90,0x78,0x56,0x34,0x12 }; //BCD 0X1234567890
char ch[20] = “”;
bcd_to_integer_string(ch, bcd_buf, sizeof(bcd_buf));
assert(strcmp(ch, “1234567890”) == 0);
return TRUE;
}
- BCD转32位整数
uint32_t bcd_to_u32(const uint8_t* bcd_buf,uint8_t bcd_size)
{
uint8_t* data = (uint8_t*)bcd_buf;
uint32_t multipy = 1;
uint32_t sum = 0;
uint8_t temp = 0;
int i = bcd_size;
while (i-- > 0)
{
sum *= 100ul;
temp = (data[i] & 0xf);
temp += ((data[i] >> 4) & 0xf) * 10u;
sum += temp;
}
return sum;
}
单元测试
static void bcd_to_u32_test1(void)
{
uint8_t bcd_buf[5] = { 0x90,0x78,0x56,0x34,0x12 }; //BCD 0X1234567890
uint32_t temp = 0;
temp = bcd_to_u32(bcd_buf, sizeof(bcd_buf));
assert(temp == 1234567890);
return;
}
static void bcd_to_u32_test2(void)
{
uint8_t bcd_buf[4] = { 0x44,0x66,0x33,0x55 }; //BCD 0X1234567890
uint32_t temp = 0;
temp = bcd_to_u32(bcd_buf, sizeof(bcd_buf));
assert(temp == 55336644);
return;
}
static void bcd_to_u32_test3(void)
{
uint8_t bcd_buf[2] = { 0x44,0x66}; //BCD 0X1234567890
uint32_t temp = 0;
temp = bcd_to_u32(bcd_buf, sizeof(bcd_buf));
assert(temp == 6644);
return;
}
static void bcd_to_u32_test4(void)
{
uint8_t bcd_buf[1] = { 0x55}; //BCD 0X1234567890
uint32_t temp = 0;
temp = bcd_to_u32(bcd_buf, sizeof(bcd_buf));
assert(temp == 55);
return;
}
void bcd_to_u32_unit_test(void)
{
bcd_to_u32_test1();
bcd_to_u32_test2();
bcd_to_u32_test3();
bcd_to_u32_test4();
}