0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

16进制数转换成8421BCD编码函数

PoisonApple 来源:网络整理 2018-03-02 10:11 次阅读

十六进制

十六进制(英文名称:Hexadecimal),是计算机中数据的一种表示方法。同我们日常生活中的表示法不一样。它由0-9,A-F组成,字母不区分大小写。与10进制的对应关系是:0-9对应0-9;A-F对应10-15;N进制的数可以用0~(N-1)的数表示,超过9的用字母A-F。

1、BCD码与十进制数的转换

BCD码与十进制数的转换关系很直观,相互转换也很简单,将十进制数75.4转换为BCD码:7-》0111,5-》0101,4-》0100所以拼成8421BCD码的结果是:(0111 0101.0100)BCD;若将BCD码1000 0101.0101转换为十进制数:1000-》8,0101-》5,0101-》5所以结果是:(85.5)D。

注意:同一个8位二进制代码表示的数,当认为它表示的是二进制数和认为它表示的是二进制编码的十进制数时,数值是不相同的。

例如:00011000,当把它视为二进制数时,其值为24;但作为2位BCD码时, 其值为18。

又例如00011100,如将其视为二进制数,其值为28,但不能当成BCD码,因为在8421BCD码中,它是个非法编码 。

2、BCD码的格式

计算机中的BCD码,经常使用的有两种格式,即分离BCD码,组合BCD码。

所谓分离BCD码,即用一个字节的低四位编码表示十进制数的一位,例如数82的存放格式为:

_ _ _1 0 0 0 _ _ _ _0 0 1 0 其中_表示无关值。

组合BCD码,是将两位十进制数,存放在一个字节中,例82的存放格式是1000 0010

16进制数转换成8421BCD编码函数

3、BCD码的加减运算

由于编码是将每个十进制数用一组4位二进制数来表示,因此,若将这种BCD码直接交计算机去运算,由于

计算机总是把数当作二进制数来运算,所以结果可能会出错。例:用BCD码求38+49。

解决的办法是对二进制加法运算的结果采用“加6修正,这种修正称为BCD调整。即将二进制加法运算的结果修正为BCD码加法运算的结果,两个两位BCD数相加时,对二进制加法运算结果采用修正规则进行修正。修正规则:

(1)如果任何两个对应位BCD数相加的结果向高一位无进位,若得到的结果小于或等于9,则该位不需修正;若得到的结果大于9且小于16时,该位进行加6修正。

(2)如果任何两个对应位BCD数相加的结果向高一位有进位时(即结果大于或等于16,注意不是修正时的进位),该位进行加6修正。

(3)低位修正结果使高位大于9时,高位进行加6修正。

下面通过例题验证上述规则的正确性。

a)用BCD码求35+21

35-》 0011 0101+

21-》 0010 0001=

0101 0110-》56

注意:0101+0001并没有满足上述3条规则,同时0011+0010也没有满足上述3条规则,所以结果不作处理。

b)BCD码求25+37

25-》0010 0101+

37-》0011 0111=

0101 1100+(低位0101+0111=1100-》12》9所以需要调整)

06-》 0110=

0110 0010-》62

注意:在给低位加0110调整时也有向高位进位发生,但是这是在调整时的进位,故不做处理。

c)用BCD码求38+49

38-》0011 1000+

49-》01001001=

1000 0001+(低位1000+1001相加时有进位发生,所以需要给低位加0110-》调整)

06-》 0110=

10000111-》87

注意调整后的结果也不满足上述(3)的条件所以不再调整

d)用BCD码求42+95

42-》0100 0010+

95-》1001 0101=

11010111-》13 7+(1101是一个非法8421BCD码,事时上0100+1001相加满足(1)条件)

06-》0110(注意是给1001+0100加0110调整)

00010011 0111-》1 3 7

注意结果不满足(3)条件所以不再调整。

c)用BCD码求91+83

91-》1001 0001+

83-》1000 0011=

00010001 0100 +(1001+1000有进位发生所以需要给1001+1000相加结果0001+0110调整)

06-》0110 =

00010111 0100-》174

注意结果不满足(3)条件所以不再调整。

d)用BCD码求94+7

94-》1001 0100+

07-》0000 0111=

10011011+(由于结果的两位编码数满足上述条件1所以需要给0100+0111+0110调整)

06-》0110=

1010 0001+(由于结果的高位1010-》10》9所以满足上述(3)条件给高位加0110调整)

06-》0110 =

0001 0000 0001-》101

注意:对于调整我们只需要关心结果是不是满足上述(3)条件,不满足不予调整。

e)用BCD码求76+45

76-》0111 0110+

45-》0100 0101=

1011 1011+(注意这里0101+1011和0111+0100都满足上述(1)条件所以需要都调整)

06-》01100110=

000100100001-》121

注意结果满足上述(3)条件所以不再调整。(例子补充于2015-1-11)

两个组合BCD码进行减法运算时,当低位向高位有借位时,由于”借一作十六“与”借一作十“的差别,将比正确的结果多6,所以有借位时,可采用”减6修正法“来修正。两个BCD码进行加减时,先按二进制加减指令进行运算,再对结果用BCD调整指令进行调整,就可得到正确的十进制运算结果。 实际上,计算机中既有组合BCD数的调整指令,也有分离BCD数的调整指令。另外,BCD码的加减运算,也可以在运算前由程序先变换成二进制数,然后由计算机对二进制数运算处理,运算以后再将二进制数结果由程序转换为BCD码。

16进制数转换成8421BCD编码函数

.INCLUDE hardware.inc

.IRAM

_Led_Out:

.dw 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000

_List_8421_Data: //16进位数转换成8421码的位权表,万位每千位进位,千位每百位进位,百位每十位进位

.dw 0xFFFF,0xEA60,0xC350,0x9C40,0x7530,0x4E20,0x2710

//60000-10000

.dw 0x2328,0x1F40,0x1B58,0x1770,0x1388,0x0FA0,0x0BB8,0x07D0,0x03E8

//9000-1000

.dw 0x0384,0x0320,0x02BC,0x0258,0x01F4,0x0190,0x012C,0x00C8,0x0064

//900-100

.dw 0x005A,0x0050,0x0046,0x003C,0x0032,0x0028,0x001E,0x0014,0x000A

//90-10

//.RAM

//.DATA

.code

//=========================================================================================

//函数: hex_to_8421()

//语法:hex_to_8421(被转换数,符号标记)

//描述:16进位数转换成8421码,存放在C段中定义好的数组当中

//须定义一个下标8位的整数数组,C段中如下书写

//extern int led_out [8]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

//参数:被转换数小于0xFFFF的数,符号标记0或非零的数

//返回:无

//=============================================================================================

.PUBLIC _hex_to_8421;

_hex_to_8421: .PROC

push bp to [sp];

bp=sp+1; //基址重定位,准备取参数

r1=[bp+3]; //备转换成8421码的16进位数字

r3=[bp+4]; //符号位标志,为0,则做无符号整数处理,非1做有符号数处理

R4=_Led_Out; //输出数据的地址******************************可修改输出名称

bp=_List_8421_Data; //基址定位到位权表头**************************对应.IRAM段,可修改输入名称

//------------------------------------------

test R3,0xFFFF; //检查R3是否非0,如果非零,做有符号数处理,如果为0,做无符号数处理

je _hex_loop0; //为0,做无符号数处理,跳到_hex_loop0

R3=0xF000; //非0,做有符号数处理

[R4]=r3; //表的第1个单元高4字节存放符号标记,F为负,0为正

R1-=0X0001; //包括下1步,减1后反码转换成10进位正数

R1^=0xFFFF;

_hex_loop0:

R2=0X0007; //R2为进位标志,从9到1循环,R2初置7,进入循环后减1为6做初值

16进制数转换成8421BCD编码函数

//------------------------------------------

_hex_loop1: //位权表遍历开始标记

CALL _Clear_WatchDog; // 清看门狗

BP+=0X0001; //基址加1,定位到位权表第一个有效数字

R2-=0X0001; //位权减1,准备输出位权表第一个有效数字所对应的位数字

cmp r1,[bp]; //比较被转换数和当前位权的大小

jb _hex_loop2; //如果被转换数小于当前位权,则跳到“_hex_loop1”,继续比较

jmp _hex_loop3; //如果被转换数大于当前位权,则跳到“_hex_loop3”,进行转换

_hex_loop2: //R2进位循环处理的标记

CMP R2,0X0002;

JB _hex_loop4; //包括上1步,如果R2小于2,跳到_hex_loop4,将R2置为10

JMP _hex_loop1; //如果R2大于等于2,跳到“_hex_loop1”,继续比较

_hex_loop4:

R2=0x000A; //包括下1步,将R2置为10,跳到“_hex_loop1”,继续比较

JMP _hex_loop1;

//------------------------------------------

_hex_loop3: //判断并输出数据的标记

cmp r1,0x2710;

jnb _hex_2710; //包括上1步,如果R1大于等于0x2710(10000),跳到_hex_2710处理

cmp r1,0x03e8;

jnb _hex_03e8; //包括上1步,如果R1大于等于0x03E8(1000),跳到_hex_03E8处理

cmp r1,0x0064;

jnb _hex_0064; //包括上1步,如果R1大于等于0x0064(100),跳到_hex_0064处理

cmp r1,0x000a;

jnb _hex_000a; //包括上1步,如果R1大于等于0x000A(10),跳到_hex_000A处理

//------------------------------------------

R3=R4+5; //包括下2步,输出10进制第1位,跳到“_hex_000”,结束转换

[R3]=R1;

jmp _hex_over;

_hex_2710:

R3=R4+1; //包括下3步,输出10进制第5位,被转换数减位权,做被转换数,跳到“_hex_loop1”,继续比较

[R3]=R2;

r1-=[bp];

jmp _hex_loop1;

_hex_03e8:

R3=R4+2; //包括下3步,输出10进制第4位,被转换数减位权,做被转换数,跳到“_hex_loop1”,继续比较

[R3]=R2;

r1-=[bp];

jmp _hex_loop1;

_hex_0064:

R3=R4+3; //包括下3步,输出10进制第3位,被转换数减位权,做被转换数,跳到“_hex_loop1”,继续比较

[R3]=R2;

r1-=[bp];

jmp _hex_loop1;

_hex_000a:

R3=R4+4; //包括下3步,输出10进制第2位,被转换数减位权,做被转换数,跳到“_hex_loop1”,继续比较

[R3]=R2;

r1-=[bp];

jmp _hex_loop1;

_hex_over:

pop bp from [sp];

RETF

.ENDP;

.PUBLIC _Clear_WatchDog;

_Clear_WatchDog: .PROC

PUSH R1 TO [SP];

R1 = 0x0001;

[ASM_Port_Watchdog_Clear] = R1;

POP R1 FROM [SP];

RETF

.ENDP;

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 16进制
    +关注

    关注

    1

    文章

    13

    浏览量

    8706
  • BCD码
    +关注

    关注

    1

    文章

    52

    浏览量

    18123
  • 8421码
    +关注

    关注

    1

    文章

    8

    浏览量

    3958
收藏 人收藏

    评论

    相关推荐

    常用编码(BCD编码、余3码、格雷反射码、奇偶校验码)

    使用8421BCD码时一定要注意其有效的编码仅十个,即:0000~1001。四位二进制的其余六个编码1010,1011,1100,1101
    发表于 04-11 10:00

    什么是BCD码、8421码、余三码、格雷码

    的是8421BCD码,无权码用得较多的是余三码和格雷码,我们通常所说的BCD码指的是8421BCD码。这些编码跟十进制
    发表于 11-03 17:36

    Labview将4字节16进制转换成10进制小程序

    Labview将4字节16进制转换成10进制小程序
    发表于 10-29 16:47

    用FPGA设计将BCD转换成进制电路

    用FPGA设计将BCD转换成进制电路
    发表于 03-11 20:37

    谁能帮忙设计一个数字电路

    用两片四位全加器74283和必要的逻辑门设计一个数制转换电路,实现将输入的两位十进制转换成进制
    发表于 07-09 16:12

    如何将labview串口接收到的多路16进制数据转换成相应的10进制,并可以选择输出

    如何将labview串口接收到的多路16进制数据转换成相应的10进制,并可以选择输出?小弟目前已经做到串口收到的数据先
    发表于 04-07 14:26

    关于两位十进制转换成进制的仿真 求助啊

    求助,不怎么懂这题该怎么做。求教。用两片四位全加器74283和必要的逻辑门设计一个数制转换电路,实现将输入的两位十进制转换成进制
    发表于 07-01 20:13

    如何用两片四位全加器和必要的逻辑门设计数制转换电路

    如何用两片四位全加器和必要的逻辑门设计数制转换电路 将输入的十进制转换成进制进制输入采用8421B
    发表于 07-04 14:52

    怎么将16位二进制转换成进制函数

    有没有人建立一个将16位二进制转换成进制函数
    发表于 03-26 11:21

    C语言中十进制8421BCD码是用的什么方法?

    今天FPGA的同事问我C语言中十进制8421BCD码是用的什么方法?第一时间我在想除了除10取余还能有什么办法?过了一会儿,突然想起有没有办法从移位上解决这个问题呢?于是乎就看到这个链接。然后就
    发表于 07-15 09:21

    8421BCD码与二进制原码的相互转换

    8421BCD码与二进制原码的相互转换。九层妖塔 起于垒土【蓝桥杯】—{模板Template}—{Part7:DS18B20温度传感器}一、基本模板1、`头文件`● 改编自国信长天蓝桥杯官方蓝皮书
    发表于 01-17 07:13

    在FPGA中实现一种二进制BCD码的电路设计

    字逻辑设计课程中,我们已经学过了BCD码的相关知识,它用4位二进制数来表示1位十进制中的09,是二进制
    发表于 07-12 16:41

    常用编码(BCD编码、余3码、格雷反射码、奇偶校验码)

    常用编码1、BCD编码    例 写出十进数563.97D对应的8421BCD码。     563.97D=0101 0110 0011 . 1001 01118421
    发表于 09-19 11:23 8336次阅读

    余3码至8421BCD码的转换_8421BCD转换成余3码

    进制编码的十进制数,简称BCD码。这种方法是用4位二进制码的组合代表十进制数的0,1,2,3,
    的头像 发表于 03-02 09:38 18.5w次阅读
    余3码至<b class='flag-5'>8421BCD</b>码的<b class='flag-5'>转换</b>_<b class='flag-5'>8421BCD</b>码<b class='flag-5'>转换成</b>余3码

    8421BCD转换成5421BCD

    5421BCD码,是二—十进制代码(BCD码)的一种;二—十进制代码(BCD码)的一种;5421BCD
    的头像 发表于 03-02 13:48 7.6w次阅读
    <b class='flag-5'>8421BCD</b>码<b class='flag-5'>转换成</b>5421<b class='flag-5'>BCD</b>码