c语言0xaf咋转成十进制,bcd码转换成十进制 bcd码怎么转换为十进制

bcd码转换成十进制 bcd码怎么转换为十进制

BCD码的运算规则:BCD码是十进制数,而运算器对数据做加减运算时,都是按二进制运算规则进行处理的。这样,当将 BCD码传送给运算器进行运算时,其结果需要修正。修正的规则是:当两个BCD码相加,如果和等于或小于 1001(即十进制数9),不需要修正;如果相加之和在 1010 到1111(即十六进制数0AH~0FH)之间,则需加 6 进行修正;如果相加时,本位产生了进位,也需加 6 进行修正。这样做的原因是,机器按二进制相加,所以 4 位二进制数相加时,是按“逢十六进一”的原则进行运算的,而实质上是 2 个十进制数相加,应该按“逢十进一”的原则相加,16 与10相差 6,所以当和超过 9或有进位时,都要加 6 进行修正。下面举例说明。

【例 1.3】 需要修正 BCD码运算值的举例。

(1) 计算 5+8;(2) 计算 8+8

解:(1) 将 5 和 8 以 8421 BCD输入机器,则运算如下:

0 1 0 1

+) 1 0 0 0

1 1 0 1 结果大于 9

+) 0 1 1 0 加 6 修正

1 0 0 1 1 即13 的 BCD码

结果是 0011,即十进制数3,还产生了进位。5+8=13,结论正确。

(2)将8以8421 BCD输入机器,则运算如下:

1 0 0 0

+)1 0 0 0

1 0 0 0 0 结果大于9

+)0 1 1 0 加6修正

1 0 1 1 0 16的BCD码

结果是0110,即十进制的6,而且产生进位。8+8=16,结论正确。

微机原理代码: (AL=BCD 5,BL=BCD 8) 设AH=0,则

ADD AL,BL

AAA

结果为 AX=0103H,表示非压缩十进制数,CF=1,AF=1,AH=1,AL=3

使用AAA指令,可以不用屏蔽高半字节,只要在相加后立即执行AAA指令,便能在AX中得到一个正确的非压缩十进制数

在读写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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值