51单片机整数二一十进制转换的快速算法

发布者:温柔浪漫最新更新时间:2012-01-16 关键字:51单片机  进制转换 手机看文章 扫描二维码
随时随地手机看文章

  89C5l系列单片机历经20多年的发展,仍然长盛不衰,在工业控制及仪器仪表中得到广泛应用;用于89C5l单片机软件开发的Keil C51编译系统也日臻成熟,成为89C5l系列单片机软件开发的优先选择。在单片机系统开发中,经常遇到整数二十进制转换的问题,一般可以采用C语言中的标准函数sprintf()来实现;但由于该函数是通用格式输出函数,代码量大(超过l KB),用于整数二一十进制转换的运算时间过妊(在12 MHz晶振频率下超过l ms),这在计算密集(computation intensive)的应用中是一个影响系统性能的重要因素。在低功耗系统设计中,也必须考虑因为运算时间长而增加系统耗电量的问题。经常有网发询问如何高效地实现这种转换。笔者通过对二进制整数的深入分析,巧妙运用89C5l单片机的特殊单字节乘除指令,成功地实现了整数二一十进制转换的快速算法。本文将详细介绍快速算法,给出颇具实用性的优化代码,并与使用sprintf()函数的实现及传统的汇编代码实现进行性能比较。


1 传统的汇编代码实现
  要实现快速运算,很自然地想到教科书中提到的双字节二进制整数转换成3字节BCD码整数的子程序。其采用的算法是,依次将整数的每位左移至CY位,再把CY位左移至一个3字节队列中,并进行十进制调整。通过16次移位完成运算,结果为压缩格式的3字节BCD编码。
  汇编子程序如下:


  该算法代码简洁明了,只使用51条指令代码,但执行这段程序却要耗费312个指令周期。如果要符合C51调用规则,则要多出25个指令代码空间和21个指令周期,显然效率不高。


2 快速算法
  快速算法从千位入手,首先求取整数中包含l 000的个数(以下称为“千数”)。求取了千数,其他问题就迎刃而解了。
  设二进制整数以b=[b15…b0]表示,取值范围为O~65535。其高6位[b15…b10]取值范围为0~63,在整数中代表的数值为(0~63)*1024;后10位[b9…b0]代表的数值范围为O~l 023。可以写出如下算式:
 

  可以用[b15…b10]作为整数中千数的预估。
  余数的最大值为63×24+1 023=2535。这表明余数中最多还有2个l000,也就是说千数的预估误差最多为2,因此最多通过2次校正,就可求得千数的准确值。2次校正方法:
  ①如果余数高位字节≥4(即余数≥1024,这样用只是为了简化代码;也可以用余数≥1000的判定条件),则千数+l,余数~1000;
  ②如果余数≥l000,则千数+1,余数~l000。
  至此就求出了千数。千数用10整除所得商和模余作为万位数和千位数。
  从余数中求取百、十,个位数也很简单:
  余数用100整除得到百位数。实际是先把余数右移2位,此时已成单字节数,再用单字节除指令进行除以25的操作,即得到百位数;而除去百位后的余数已是单字节数,可轻易取得十位数与个位数。
  用C语言编写的函数如下:
  




  在Keil C51集成环境中,为该函数生成汇编程序源码,再对源码进行优化,最后得到满足C51调用规则的、效率极高的汇编语言源代码。(源代码见本刊网站www.mesnct.com.cn——编者注。)
这个汇编语言源代码可以直接作为项目文件使用,也可以用来生成函数库。


3 性能比较
  (1)与传统汇编语言的性能比较
  符合C5l调用规则的传统汇编语言子程序占用76字节的代码空间,耗用333个指令周期;快速算法最多耗用107个指令周期,耗时只有传统算法的32%。
  (2)与使用sprintf()函数相比较
  使用如下的程序来比较二者的性能:


  sprintf()函数占用1064字节的代码空间,耗用1151个指令周期;快速算法占用97字节的代码空间,最多耗用107个指令周期,只占使用sprintf()函数耗时的9.3%。


结论
  无论是与传统汇编语言子程序,还是与使用sprintf()函数的程序相比,快速算法都有很大的速度优势;是一种针对8位机的创新算法,具有很强的工程实用性,值得推广应用。

关键字:51单片机  进制转换 引用地址:51单片机整数二一十进制转换的快速算法

上一篇:51单片机和图形LCD接口技术的实现
下一篇:基于单片机和GPS的时钟信息显示系统

推荐阅读最新更新时间:2024-03-16 12:51

51单片机减1指令(4条)
这组 指令 的作用是把所指的寄存器内容减1,结果送回原寄存器,若原寄存器的内容为00H,减1后即为FFH,运算结果不影响任何标志位,这组指令共有直接、寄存器、寄存器间址等寻址方式,当直接地址是I/O口锁存器时,“读—修改—写”操作与加1指令类似。 DEC A ;(A)-1→(A)累加器A中的内容减1,结果送回累加器A中 DEC data ;(data)-1→(data)直接地址单元中的内容减1,结果送回直接地址单元中 DEC @Ri ;((Ri))-1→((Ri))寄存器Ri指向的地址单元中的内容减1,结果送回原地址单元中 DEC Rn ;(Rn)-1→(Rn)寄存器Rn中的内容减1,结果送回寄存器Rn中
[单片机]
51单片机驱动16*16点阵显示生日快乐程序
自己亲手做的一个点阵屏 仿真+实物, 送给女朋友的生日礼物 单片机+液晶显示 带仿真文件 妞都狠喜欢这个了,显示生日快乐4个字然后还有心型,还有i love you,全部源码和仿真文件的下载地址是:http://www.51hei.com/bbs/dpj-18851-1.html 下面是部分源码预览: #include at89x51.h #include DS1302.h #define din P3_2 #define load P3_3 #define clk P3_4 #define uchar unsigned char #define uint unsigned int unsigned char code
[单片机]
<font color='red'>51单片机</font>驱动16*16点阵显示生日快乐程序
基于51单片机的定时顺序控制器
求代码,作用是单片机控制继电器用于自动操作键盘。 要求: P01 导通三分钟,然后断开; P02 导通 10 秒后断开; P03 导通 0.5 秒后断开; P04 导通 0.2 秒后断开; P05 导通 0.5 秒后断开; P06 导通 0.2 秒后断开。 断开 P06 之后,循环所有。 单片机 89C52RC。 如下程序。 //-------------------------------------------------- #include #define uchar unsigned char #define uint unsigned int sbit P0_1 = P0^1; sbit P0_2 = P0^2; s
[单片机]
基于51单片机的智能晾衣架设计
在Proteus中通过模拟温湿度,外接温湿度值,将模拟到的数据进行采集与A/D转换,显示到LCD液晶并控制后级电路进行反馈,完成晾衣架的功能。 仿真原理图如下 智能晾衣架 第三章:硬件单元电路 经过上述分析明确了本次设计的主要目标,为了实现晾衣自身能够完成对外界数据的采集与分析,集成控制环节我们采用了ATMEL公司生产的AT89C52单片机,与市面上的其他嵌入式控制单元相比较在体积与功耗方面都相当出色。此次设计主要突破在于设计合理的控制电路单元,同时结合采用的主控编写高质量的源码并使系统在实际与应用中能够发挥出色的稳定性和参考价值。本次将围绕主控单元设计合理的电路,结合SHT11温湿度采集单元、感光原件单元、LCD显示单
[单片机]
基于<font color='red'>51单片机</font>的智能晾衣架设计
MCS-51单片机指令系统(4)
某些指令说明 -“读引脚”和“读锁存器”指令的区别 关于并行I/O口的“读引脚”和“读锁存器”指令的区别 例如,当P1口的P1.0引脚外接一个发光二极管LED的阳极,LED的阴极接地。 若想查看一下单片机刚才向P1.x脚输出的信息是“0”还是“1”,如果直接读引脚,结果显然错误。 -“读引脚”和“读锁存器”指令的区别 正确做法是读D锁存器的Q端状态,那里储存的才是前一时刻送给P1.0的真实值。就是说,凡遇“读取P1口前一状态以便修改后再送出”的情形,都应当“读锁存器”的Q端信息,而不是读取引脚的信息。 当P1口外接输入设备时,要想P1口引脚上反映真实的输入信号,必须要 设法先让该引脚内部的场效应管截止才行,否则当场
[单片机]
MCS-<font color='red'>51单片机</font>指令系统(4)
基于51单片机的自行车测速测距程序
实物图如下: 电路原理图如下: 单片机源程序如下: #include reg52.h #include Star1602.h #define CIRCLE 2.0 //宏定义 车轮的周长(这个要根据实际的车轮进行设置) sbit Signal = P1^0; //这里的Signal表示的是霍尔传感器的信号引脚 int m_second=0; //定义变量m_second,用来记录时间(以毫秒为单位) float speed=0.0 ; //定义速度变量 float length=0.0 ;//定义路程变量 void main() { lcd_init(); //初始化液晶函数 TMOD = 0x01; //
[单片机]
基于<font color='red'>51单片机</font>的自行车测速测距程序
串行AD转换器TLC2543与51单片机的接口设计
  TLC2543是11个输入端的12位模数转换器,具有转换快、稳定性好、与微处理器接口简单、价格低等优点,应用前景好。由于它带有串行外设接口(SPI,Seri-al PeripheralInterface),而51系列单片机没有SPI,因此研究它与51单片机的接口就非常有意义。 1 TLC2543的引脚及功能   TLC2543是12位开关电容逐次逼近模数转换器,有多种封装形式,其中DB、DW或N封装的管脚图见图1。引脚的功能简要分类说明如下。 I/OCLOCK:控制输入输出的时钟,由外部输入。   DATAINPUT:控制字输入端,用于选择转换及输出数据格式。   DATAOUT:A/
[单片机]
串行AD<font color='red'>转换</font>器TLC2543与<font color='red'>51单片机</font>的接口设计
51单片机控制步进电机-让电机转起来
摘要: 本节介绍用简单的方式,让步进电机转起来。其目的之一是对电机转动有直观的感受,二是熟悉整个开发流程 本系列教程必要的51单片机基础包括IO口操作、中断、定时器三个部分,相关基础教程网上很多,可以自行学习 一、软件清单 需要用到的软件有keil5编译软件、STC程序烧录软件 二、控制原理 根据TB6600驱动器原理,向PUL口发送脉冲,每发送一个脉冲,电机就转一步。通过单片机延时的方式,切换PUL口电平产生脉冲,从而控制电机转动。 三、程序代码 //毫秒延时函数 void delay(unsigned int z) { unsigned int x,y; for(x=z;x 0;x--) for(y
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved