将BCD码转换为十进制数 联系客服

发布时间 : 星期四 文章将BCD码转换为十进制数更新完毕开始阅读50275bed988fcc22bcd126fff705cc1755275f5d

将BCD码转换为十进制数

? 将8421BCD码转换为十进制数(转)(2009-10-30 08:36:48) 转载标签:杂谈 分类:单片机学习

在读写DS1302时需要把读写数据BCD码转换成十进制,一下是本人在网络上看到的一篇解释较为简单易懂的解释

//*****************************************************************

//bcd hex //此函数用于将8421BCD码转换为十进制数,从函数参数可以看出此BCD码是由两位十进制数组成的。

BCD码是用二进制数对十进制数的各个位数进行编码,比如十进制数58,那么转换为BCD码为0x58,356对应BCD码就是0x356。注意这是编码不是数进制间的转换,他们之间不存在等价关系。只是进行编号,为了方便对编号后的数据用十六进制数表示。对应编码规则如下:

十进制数---8421BCD码----编码后用等价的十六进制数表示 0-----------0000----------0x0 1-----------0001----------0x1 2-----------0010----------0x2 3-----------0011----------0x3 4-----------0100----------0x4 5-----------0101----------0x5 6-----------0110----------0x6 7-----------0111----------0x7 8-----------1000----------0x8 9-----------1001----------0x9

知道了编码规则,那么将2位8421bcd码编号的数,还原为十进制数也就方便了。函数参数是一个字节那么决定了此8421BCD码是两位码即高四位是一个码值、低四位是一个码值,将高四位乘以10加上低四位码值就得到了十进制数。 byte bcd2_hex(byte val) {

byte i;

i = val&0x0f; //按位与,i得到低四位数。

val >>= 4; //右移四位,将高四位移到低四位的位置,得到高四位码值。 val &= 0x0f; //防止移位时高位补进1,只保留高四位码值 val *= 10; //高位码值乘以10

i += val; //然后与第四位码值相加。 return i; //将得到的十进制数返回 }

//***************************************************************** //这个应该是一个类似I2C协议的字节写操作。

static void DS1302_WriteByte(byte val) {

byte i;

//MinCardClk(0); //stop clk //Sys_SetCpuClk(clockdiv1);

for(i = 0; i < 8; i++) //通过循环将1字节也即8位二进制数送给i2c数据线。 {

if(val&0x01)DS1302_SDA_W(1); //如果此位是1,那么送给数据线1 else DS1302_SDA_W(0); //如果是0,那么给数据线0 DS1302_SCK(0); //时钟线置0也即拉低 DS1302_SCK(1); //时钟线置1,通过这两个动作时钟线产生一个从低到高的跳变,作用是通知从器件取走数据线上的数据。

val >>= 1;// FOR DELAY AND SHIFT //右移数据,接着发送下一位数据,数据是从低位到高位发送。 }

//DS1302_SCK(0);

//Sys_SetCpuClk(clockdiv0); //MinCardClk(1); //start clk }

//***************************************************************** //同理i2c读字节

static byte DS1302_ReadByte(void) {

byte i,val;

//MinCardClk(0); //stop clk //Sys_SetCpuClk(clockdiv1); val=0;

DS1302_SDA_W(1); for(i = 0; i < 8; i++)

//循环 从数据线上读取8位数据,然后凑成一字节。 {

DS1302_SCK(1);

DS1302_SCK(0); //时钟一个从高到低的跳变,通知从器件将数据放到数据线上。

val >>= 1; //接收完1位后右移数据,准备接收下一位,这里也是从低位到高位接收数据。

if(DS1302_SDA_R())val |= 0x80; //如果是1那么与0x80或后就得到了1,如果是0,就不用管了因为在移位时直接补的是0. }

//Sys_SetCpuClk(clockdiv0); //MinCardClk(1); //start clk return val; }

一下是汇编的:

re: asm BCD2BIN:

; INPUT: R3:R2 -- BCD ; OUTPUT: R5:R4 -- BIN ; USE: A, B, PWS MOV A, R2

CALL BCD_BYTE2BIN MOV R4, A MOV A, R3

CALL BCD_BYTE2BIN MOV B, #100 MUL AB ADD A, R4 MOV R4, A CLR A ADDC A, B MOV R5, A RET

BCD_BYTE2BIN:

; 10*Y + X = (16*Y + X)-6*Y = 250 * Y + (16*Y + X) - 256 * Y MOV R5, A ANL A, #0F0H SWAP A

MOV B, #250 MUL AB ADD A, R5 RET