您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 51单片机汇编程序范例
16位二进制数转换成BCD码的的快速算法-51单片机2010-02-1800:43在做而论道上篇博文中,回答了一个16位二进制数转换成BCD码的问题,给出了一个网上广泛流传的经典转换程序。程序可见:中的HEX2BCD子程序。.说它经典,不仅是因为它已经流传已久,重要的是它的编程思路十分清晰,十分易于延伸推广。做而论道曾经利用它的思路,很容易的编写出了48位二进制数变换成16位BCD码的程序。但是这个程序有个明显的缺点,就是执行时间太长,转换16位二进制数,就必须循环16遍,转换48位二进制数,就必须循环48遍。上述的HEX2BCD子程序,虽然长度仅仅为26字节,执行时间却要用331个机器周期。.单片机系统多半是用于各种类型的控制场合,很多时候都是需要“争分夺秒”的,在低功耗系统设计中,也必须考虑因为运算时间长而增加系统耗电量的问题。为了提高整机运行的速度,在多年前,做而论道就另外编写了一个转换程序,程序的长度为81字节,执行时间是81个机器周期,(这两个数字怎么这么巧!)执行时间仅仅是经典程序的1/4!.近来,在网上发现了一个链接:,也对这个经典转换程序进行了改进,话是说了不少,只是没有实质性的东西。这篇文章提到的程序,一直也没有找到,也难辩真假。这篇文章好像是选自某个著名杂志,但是在术语的使用上,有着明显的漏洞,不像是专业人员的手笔。比如说文中提到的:“使用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-1023:33,2位16进制转10进制,用除以10求商跟余数的方法,即可。4位16进制数呢?DIV指令只可以对2位16进制数进行除法运算啊,求高手解答。例如把TH1TL1的数值转成十进制,分别存入R4R3R2R1R0。我要的是汇编的方法,C语言还没学到。悬赏分:30-解决时间:2010-2-1022:47;------------------------------------------------------------------最佳答案:两个字节的二进制数转换成BCD码,必须编写程序来解决。下面把这段转换程序,写成子程序的结构,便于网友移植。;程序经过仿真调试通过,如下所示:;------------------------------------------------------------------;MOVR0,TH1MOVR1,TL1CALLHEX2BCD;调用子程序把R0R1中的数字,转换成压缩的BCD码,送到R2R3R4;-------下面,把万千百十个位,分别存入R4R3R2R1R0MOVA,R4;先分离R4中的压缩型BCD码,包含的是十位与个位的数MOVB,#16DIVAB;除以16,目的是分离出高、低四位MOVR1,A;存放十位MOVR0,B;存放个位;MOVA,R2;万位数不超过6,即R2中的压缩型BCD码只有一个,直接放到万位R4中MOVR4,A;存放万位;MOVA,R3;分离R3中的压缩型BCD码,其包含的是千位和百位数MOVB,#16;半字节分离DIVABMOVR3,AMOVR2,BSJMP$;到此,完成了题目要求;------------------------------------------------------------------;两个字节的二进制数转换成BCD码的程序如下:;功能:16位二进制数变换成为BCD码;;入口:R0R1中是16位二进制数,其中R0中是高8位;;出口:R2R3R4中是BCD码,其中R2中是万位,R3中是千、百位,R4中是十、个位。HEX2BCD:CLRAMOVR2,A;先对要放入转换后的压缩型BCD码的寄存器通通清零MOVR3,AMOVR4,AMOVR5,#16;共转换十六位数LOOP:CLRCMOVA,R1;从待转换数的高端移出一位到Cy(从低8位R1开始转换)RLCAMOVR1,AMOVA,R0RLCAMOVR0,AMOVA,R4;送到BCD码的低端ADDCA,R4;带进位加。自身相加,相当于左移一位DAA;十进制调整,变成BCD码MOVR4,AMOVA,R3ADDCA,R3DAAMOVR3,AMOVA,R2ADDCA,R2MOVR2,ADJNZR5,LOOP;共转换十六位数RET将A中的二进制数转换为3位的BCD码,其中百位数存放......2010-01-1109:13请各位懂得帮写下这个程序片段。将A中的二进制数转换为3位的BCD码。其中百位数存放到31H中,十位和个位数压缩后,存放到30H中。悬赏分:80-解决时间:2009-10-1909:59最佳答案:;------------------------------------------看来这个题目是属于MCS-51单片机的。下面用51单片机的汇编语言来求解。MOVB,#100DIVABMOV31H,A;存百位数MOVA,#10XCHA,BDIVABSWAPA;十位数换到高四位ADDA,B;加上个位数MOV30H,A;保存R0中的8位二进制数转换成3位BCD码-单片机编程2010-01-1023:18单片机的不难编程题!急!!!!!!将R0中的8位二进制数转换成3位BCD码,结果存入外部RAM的1002H~1000H(从高位到低位)单元中。例如:地址:R0执行后:1002H1001H1000H数据:81H010209悬赏分:15-解决时间:2009-10-1519:10提问者:stefine_-一级最佳答案:;-------------------------------------------------------呵呵,楼上的程序,使用了DECDPTR,要知道,51单片机指令系统里面,是没有DECDPTR指令的。按照下面的思路做,还可以再简练些。R0中的8位二进制数转换成3位BCD码:MOVDPTR,#1000H;个位的地址MOVA,R0MOVB,#10DIVABXCHA,BMOVX@DPTR,AINCDPTRMOVA,#10XCHA,BDIVABXCHA,BMOVX@DPTR,AINCDPTRXCHA,BMOVX@DPTR,ARET仅用了24字节16位二进制转BCD码--单片机2010-01-0314:19要求:编写一段程序,把计数器中T0中计的数(TH0和TL0)转成8421BCD码。并且高8位给p1口,低8位给p0口,要是转成BCD码超过16位,则给p2.0高电平。我是做单片机课设的,这段程序实在编不明白了,向各位大侠请教了!无比感谢中!答对有额外加分啊!!!!悬赏分:200-解决时间:2010-1-313:03最佳答案:16bit表示:65536,万位不超6――――――――――――――――――――――――――程序如下:MOVR0,TL0;MOVR1,TH0;待转换的16bit数分别放入(由高到低)R1R0中;CLRAMOVR2,A;先清零MOVR3,AMOVR4,AMOVR5,#16;共转换16位数LOOP:CLRC;c=0MOVA,R0;从待转换低8bit数的高端移出一位到Cy(转换最先由低8位开始)RLCA;R0中的最高位移入到A中MOVR0,AMOVA,R1;(高8位二进制数)RLCA;此时C中的由低8位所移入的数重新移入高8位的低端MOVR1,A;相当于16bit的高端移出了1bit到C中了MOVA,R4;送到BCD码的低端ADDCA,R4;带进位加。自身相加,相当于左移一位DAA;十进制调整,变成BCD码MOVR4,AMOVA,R3ADDCA,R3DAAMOVR3,AMOVA,R2ADDCA,R2MOVR2,ADJNZR5,LOOP;循环16遍,转换即完成;MOVP0,R4;按照要求输出MOVP1,R3CLRP2.0MOVA,R2JZP20_LSETBP2.0P20_L:RET如果随意对一个累加器A中的二进制数据进行“二进制转十进制”调整是没有任何实际意义的!DA调整的对象是在ADD或ADDC之后的结果,而且是以BCD码相加以后才能够调整,否则没有实际意义!比如,现在要执行12D+39D也就是两个十进制数相加这样一个加法(有时候程序处理的需要,数据在单片机中是以BCD码的形式存储的,也就是12H和39H(十六进制),但我们可以人为将它们看为12D和39D(十进制),而且还希望相加以后的结果为51H,也就是说符合十进制运算规则12+39=51,而不是4BH的结果),但这样的十进制加法运算在单片机中是不能够直接实现的。因为单片机只能够执行二进制加法指令,也就是所有的运算都按照二进制中的规则进行!于是就出现了DA调整指令!现在12H+39H,将12H放于A中,执行ADDA,#39H指令,则结果为4BH,这不是我们希望的51H的数据形式!!这时执行DAA指令后,就会将A中的数据调整为51H(具体调整过程和原理你可以详细看书,如果单片机书中讲的不详细,那么微机原理中一定说的非常详细),而我们按照BCD码规则就将其看为51D,符合我们的要求!也就是说加数和被加数都是BCD码的形式,最大也只可能是99H,也就是我们十进制数中的99,只有这样才会有实际的意义!所以你说的当A=#24H的时候的情况是不会存在的,严格的说是没有意义的!而且DAA指令只用于十进制
本文标题:51单片机汇编程序范例
链接地址:https://www.777doc.com/doc-5017341 .html