16位二进制数转换成BCD码的的快速算法-51单片机2010-02-18 00:43在做而论道上篇博文中,回答了一个16位二进制数转换成BCD码的问题,给出了一个网上广泛流传的经典转换程序。
说它经典,不仅是因为它已经流传已久,重要的是它的编程思路十分清晰,十分易于延伸推广。做而论道曾经利用它的思路,很容易的编写出了48位二进制数变换成16位BCD码的程序。
但是这个程序有个明显的缺点,就是执行时间太长,转换16位二进制数,就必须循环16遍,转换48位二进制数,就必须循环48遍。
上述的HEX2BCD子程序,虽然长度仅仅为26字节,执行时间却要用331个机器周期。
.
单片机系统多半是用于各种类型的控制场合,很多时候都是需要“争分夺秒”的,在低功耗系统设计中,也必须考虑因为运算时间长而增加系统耗电量的问题。
为了提高整机运行的速度,在多年前,做而论道就另外编写了一个转换程序,程序的长度为81字节,执行时间是81个机器周期,(这两个数字怎么这么巧!) 执行时间仅仅是经典程序的1/4!
.
近来,在网上发现了一个链接:u123/news/Article/uc/uc8051//4751.html,也对这个经典转换程序进行了改进,话是说了不少,只是没有实质性的东西。这篇文章提到的程序,一直也没有到,也难辩真假。
这篇文章好像是选自某个著名杂志,但是在术语的使用上,有着明显的漏洞,不像是专业人员的手笔。比如说文中提到的:“使用51条指令代码,但执行这段程序却要耗费312个指令周期”,就是败笔。51条指令代码,真不知道说的是什么,指令周期是因各种机型和指令而异的,也不能表示确切的时间。
.
下面说说做而论道的编程思路。
;-----------------------------------------------------------------------
;已知16位二进制整数n以b15~b0表示,取值范围为0~65535。
;那么可以写成:
; n = [b15 ~ b0]
;把16位数分解成高8位、低8位来写,也是常见的形式:
; n = [b15~b8] * 256 + [b7~b0]
;那么,写成下列形式,也就可以理解了:
; n = [b15~b12] * 4096 + [b11~b0]
;式中高4位[b15~b12]取值范围为0~15,代表了4096的个数;
;上式可以变形为:
; n = [b15~b12] * 4000 + {[b15~b12] * (100 - 4) + [b11~b0]}
;用x代表[b15~b12],有:
; n = x * 4000 + {x * (100 - 4) + [b11~b0]}
;即:
; n = 4*x (千位) + x (百位) + [b11~b0] - 4*x
;写到这里,就可以看出一点BCD码变换的意思来了。
;
;上式中后面的位:[b11~b0] - 4*x,如果小于256,那就太简单了,马上就可以去按照常规转换BCD了。
;如果数值较大,就要把[b11~b7]看成128的个数y;在百位中加上y、在十位加上3*y、并在[b6~b0]中减去2*y。
;
那么就有:
; n = 4*x (千位) + x (百位) + [b11~b0] - 4*x
; n = 4*x (千位) + (x + y) (百位) + 3*y (十位) + [b6~b0] - 2*y
;由此,就可以明确由高9位[b15~b7]变换出来十进制的各个位的数值,可能大于9,到最后整理一下即可。
;剩下的低7位[b6~b0],已经是单字节数据,变换成BCD码那就十分简单了。
;-----------------------------------------------------------------------
从最后的表达式中可以看出,高9位变换的计算方法极为简单,只是使用左移、加减等指令即可,基本上不涉及多字节的运算。
编程的时候,要充分利用单字节、单周期的指令,使程序的长度和执行时间尽量缩短。
做而论道的编程思路已经给出,程序代码还是过一段时间再公布,给大家留下一个发挥的时间。
感兴趣的网友可以留言,写出自己编写的程序。
51单片机把4位16进制数转成10进制数的方法2010-02-10 23:33, 2位16进制转10进制,用除以10求商跟余数的方法,即可。
4位16进制数呢?DIV指令只可以对2位16进制数进行除法运算啊,求高手解答。
例如把TH1 TL1的数值转成十进制, 分别存入R4 R3 R2 R1 R0。
我要的是汇编的方法,C语言还没学到。
悬赏分:30 - 解决时间:2010-2-10 22:47
;------------------------------------------------------------------
最佳答案:两个字节的二进制数转换成BCD码,必须编写程序来解决。
下面把这段转换程序,写成子程序的结构,便于网友移植。
;
程序经过仿真调试通过,如下所示:
;------------------------------------------------------------------
;
MOV R0, TH1
MOV R1, TL1
CALL HEX2BCD ;调用子程序把R0 R1中的数字,转换成压缩的BCD码,送到R2 R3 R4
;-------下面,把万千百十个位,分别存入R4 R3 R2 R1 R0
MOV A, R4 ;先分离R4中的压缩型BCD码,包含的是十位与个位的数
MOV B, #16
DIV AB ;除以16,目的是分离出高、低四位
MOV R1, A ;存放十位
MOV R0, B ;存放个位
;
MOV A, R2 ;万位数不超过6,即R2中的压缩型BCD码只有一个,直接放到万位R4中
MOV R4, A ;存放万位
;
MOV A, R3 ;分离R3中的压缩型BCD码,其包含的是千位和百位数
MOV B, #16 ;半字节分离
DIV AB
MOV R3, A
MOV R2, B
SJMP $ ;到此,完成了题目要求
;------------------------------------------------------------------
;两个字节的二进制数转换成BCD码的程序如下:
;功能:16位二进制数变换成为 BCD 码;
;入口:R0 R1 中是 16 位二进制数,其中R0中是高 8 位;
;出口:R2 R3 R4 中是 BCD 码,其中R2中是万位,R3中是千、百位,R4中是十、个位。
HEX2BCD:
CLR A
MOV R2, A ;先对要放入转换后的压缩型BCD码的寄存器通通清零
MOV R3, A
MOV R4, A
MOV R5, #16 ;共转换十六位数
LOOP:
CLR C
MOV A, R1 ;从待转换数的高端移出一位到Cy(从低8位R1开始转换)
RLC A
MOV R1, A
MOV A, R0
RLC A
MOV R0, A
MOV A, R4 ;送到BCD码的低端
ADDC A, R4 ;带进位加。自身相加,相当于左移一位
DA A ;十进制调整,变成BCD码
MOV R4, A
MOV A, R3
ADDC A, R3
DA A
MOV R3, A
MOV A, R2
ADDC A, R2
MOV R2, A
二进制编码转换 DJNZ R5, LOOP ;共转换十六位数
RET
将A中的二进制数转换为3位的BCD码,其中百位数存放......2010-01-11 09:13请各位懂得帮写下这个程序片段。
将A中的二进制数转换为3位的BCD码。其中百位数存放到31H中,十位和个位数压缩后,存放到30H中。
悬赏分:80 - 解决时间:2009-10-19 09:59
最佳答案:
;------------------------------------------
看来这个题目是属于MCS-51单片机的。
下面用51单片机的汇编语言来求解。
MOV B, #100
DIV AB
MOV 31H, A ;存百位数
MOV A, #10
XCH A, B
DIV AB
SWAP A ;十位数换到高四位
ADD A, B ;加上个位数
MOV 30H, A ;保存
R0中的8位二进制数转换成3位BCD码 -单片机编程2010-01-10 23:18单片机的不难编程题!急!!!!!!
将R0中的8位二进制数转换成3位BCD码,结果存入外部RAM的1002H~1000H(从高位到低位)单元中。
例如:地址:R0 执行后:1002H 1001H 1000H
数据:81H 01 02 09
悬赏分:15 - 解决时间:2009-10-15 19:10
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论