Cortex--M0单片机二-十进制整数转换的快速算法

发布者:Meshulun最新更新时间:2018-03-20 来源: eefocus关键字:Cortex--M0  单片机  整数转换  快速算法 手机看文章 扫描二维码
随时随地手机看文章

  为了提高Cortex—M0系列单片机应用系统的二进制到十进制BCD码整数转换代码的执行效率,采用除十求余数法来实现。该快速算法的核心内容是通过高效的汇编语言来实现常数除法,无论在程序代码的运行时间和存储空间上,都远胜于sprintf函数。

  在单片机应用系统中,一般都需要高效快速地完成系统所需要的任务,并在任务完成后使系统进入睡眠或低功耗状态,以便最大限度地节省系统功耗,增强系统的抗干扰能力。因此,必须优化和提高系统中各个模块的运算速度,以最大限度地压缩软件运行时间。许多单片机应用系统中都需要进行二进制整数转换为十进制BCD码的操作,以便实现系统信息的显示。对于Cortex—M0系列单片机,由于其指令系统中没有十进制调整指令和除法指令,使得一些文献中提供的高效算法和技巧不再适用于这类单片机,从而造成上述转换操作成为影响系统性能的重要因素,因此提高上述数制转换速度对于提高系统运行效率有极大的促进作用。

  1 传统的实现方法

  要实现快速运算,很自然地想到经典的双字节二进制整数转换成3字节BCD码整数的子程序。其采用的算法是预先将一个3字节队列的内容清除为0,然后依次将需要变换成BCD码的二进制整数的每位依次左移至CY位,再把3字节队列中的数据带进位自身相加,并对相加的结果进行十进制调整。通过16次移位完成运算,结果为压缩格式的3字节BCD编码。由于ARM指令系统中没有类似于MCS-51单片机系统中的十进制调整指令,所以在Cortex—M0系列单片机上实现该算法比较困难。

  2 快速算法概述

  本快速算法采用除十求余数法来实现。设需要转换的数据也就是被除数为W,除数为10,整数除法的商为S,除法运算的余数为R,根据数学运算规则有:

  S=W/10                          (1)

  R=W-S×10=W-(W/10)×10          (2)

  经过上述的运算,所得余数R就是从被除数中分离出来的个位数字,也就是首先得到了被除数的最低位的BCD码。为了获取被除数其他位的BCD码,只需要将上面得到的商S作为新的被除数W,然后重复执行上述整数除法运算,就可以分别得到被除数其他位上的BCD码,从而完成将二进制数转换为BCD码的操作。实现上述操作的关键在于如何快速地完成除数为10的快速除法任务。

  3 除法运算的实现

  为了将被除数除以10,可以将其转化为将被除数乘以0.1来实现,为此可以先写出十进制数据0.1所对应的二进制小数的表示形式:

  (0.1)D=0.000 1100 1100 1100 1100 1100 1100 1100 1100 1100……为方便32位单片机进行整数运算,预先将上式中的二进制数左移35位,即将其扩大235倍后得到除数10的魔术数(MagIC_Number)为:

  Magic_Number=CCCCCCCDH(十六进制数)当得到除数10的魔术数后,将被除数与该魔术数相乘,然后将所得的乘积右移35位,即将乘积缩小235倍后得到最终的数据就是所期望的除法结果。

  由于Cortex—M0系列单片机的乘法指令只能保留两个32位数相乘后的乘积的低32位,乘积的高32位被舍弃,所以不能直接采用被除数与除数的魔术数相乘的方法来实现将除法转换为乘法的运算。好在这个魔术数很有特点,可以将其表示为:

  Magic_Number=C0000000H+0C000000H+0CC0000H+0CCCCH        (3)由于是通过求余数的方法来获取原始数据的各位BCD码,所以在不损失运算精度的原则下,舍弃了原魔术数Magic_Number的最低位,但这不妨碍最后通过式(2)来求余数的操作。下面就是对式(1)中的除10操作变换为乘法操作的具体实现方法:

   e.jpg
    通过(4)式,采用Cortex—M0系列单片机指令中的移位指令和加减法指令的组合运算就可以快速地得到整数除法的商S,进而采用式(2)来求余数R。


4 算法中除法运算的汇编代码实现
    Cortex—M0系列单片机采用Thumb指令集,式(4)中各数据项中的分数项都可以利用该指令集中的右移指令来实现,并且采用多次累加的办法来完成运算。下面给出具体的汇编语言源程序:
    d.jpg
    b.JPG

    结语
    Cortex—M0系列单片机的开发一般采用集成开发环境,为方便使用,可以将上面的子程序封装成符合集成开发环境调用规则的函数,封装时最好包含有将单字节、双字节、三字节和四字节数据转化为BCD码的多个函数。为测试该函数的性能,在IAR集成开发环境下,将General options→Library Options选项卡中的Printf formatter设置成Tiny模式,以便尽量减小Sprintf函数的代码长度和运行时间。为叙述方便,这里假定封装好的函数名为Hex2Bcd,表1给出其与系统函数sprintf的指令运行周期数(CCSTEP)的对比数据。

c.JPG


    由表1可以看出,Hex2Bcd函数的平均运行时间不足sprintf函数的5%,速度优势极其明显。另外Hex2Bcd函数的程序代码仅有100字节左右,远少于sprintf函数的1.5 KB,极大地节省了存储空间。因此,本文中的快速算法具有很强的实用性,值得推广应用。

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

上一篇:基于STM32闭环张力控制系统设计
下一篇:基于ARM+WinCE项目开发过程中动态加载GPIO端口驱动程序的设计方法

推荐阅读最新更新时间:2024-03-16 15:57

基于51单片机的LCD1602液晶驱动实现
本文的主要内容目录: 一、LCD1602的基本介绍 二、LCD1602液晶驱动的实现     根据对现有的LCD1602液晶的驱动进行分析,总感觉写的有些乱,有些麻烦,说白了就是不好用,这里打算自己写一个,既简单又实用的。 一、LCD1602的基本介绍 开发环境:keil, 睿智51开发板 LCD1602的液晶原理图如下: 引脚对应关系:     P2.0  : 状态引脚,为0时表示指令或者状态,为1时表示数据     P2.1  :读写引脚,为0时表示写,为1时表示读     P2.2  :使能引脚,为1时使能     P0.0 ~ P0.7 :数据引脚,用来传输数据 经过分析,整个液晶时序的核心就是两个:写命令、写数据
[单片机]
针对C8051F单片机的手持编程器(SMP)介绍
   C8051F单片机是高度集成的混合信号系统级芯片(SoC),具有与8051 兼容的高速CIP-51 内核,与MCS-51 指令集完全兼容,内置程序存储器FLASH、数据存储器RAM;片内集成了ADC、DAC 等常用的模拟外设及UART、SMBus、SPI 等数字外设。   C8051F单片机具有片内调试电路,通过4 脚的JTAG 接口或者2线的C2接口可以进行非侵入式、全速的在系统调试及下载。   基于以上特点,C8051F单片机在工业控制、消费电子、通信等领域得到了广泛应用。但是,用户在生产过程中,希望一种方便快捷地对单片机编程,针对这种情况,深圳世强电讯有限公司设计开发了一款手持编程器(以下简称:SMP)方便用
[单片机]
针对C8051F<font color='red'>单片机</font>的手持编程器(SMP)介绍
led灯闪光程序 avr单片机
#include avr/io.h stat IC void io_init(void) { PORTA = 0xff; DDRA = 0xff; } void mDelay(uint16_t DelayTim) { uint16_t i; for(;DelayTim 0;DelayTim--) { for(i=0;i 40000;i++) {;} for(i=0;i 3900;i++) {;} } } int main(void) { uint8_t i=0; io_init(); while(1) { if(++i =8) i=0; PORTA=~(0x01 i); //改为0x80 i可改变流水灯方向 mDelay(5
[单片机]
单片机AT89C51--5.流水灯
1. 宏定义 勇define进行宏定义 #define uchar unsigned char //宏定义,不能加;是预处理指令不是语句 uchar i; 2. 函数的定义 函数类型 函数名(形式参数表) { 局部变量定义 函数体语句 } 3. 标准库中的循环移位函数 标准库函数: intrins.h 内部函数: 左移: _crol_ 右移: _cror_ #include reg52.h #include intrins.h #define uchar unsigned char //宏定义,不能加;是预处理指令不是语句 uchar i=0XFE; // 1111 11
[单片机]
<font color='red'>单片机</font>AT89C51--5.流水灯
单片机笔记】OLED控制器SSD1306及驱动代码
前言: 很长一段时间内用OLED的机会都很少,即使用了也是参考的大牛的代码,最近迫不得已又仔细研究了一遍。记下来省的忘记。 手头上用到的是0.61寸的OLED分辨率是96*16,也就是横向有96个点,纵向有16个点,贴上这个的尺寸图 我并没有看太多的资料,网上的资料也非常多,大多数是将SSD1306的,这里就简单通俗的记录一下,拿这个96*16的为例子,SSD把纵向(y方向)做了分页处理,每8个像素点作为一组(8个像素点=8个bit=一个字节),那么对于y方向有16个点的那就是分成两页了,从0开始就是0和1。对于其他分辨率的也一样,向上加就对了。在驱动的时候最常规的方法是从左到右,从上到下。值得注意的是不同型号可
[单片机]
【<font color='red'>单片机</font>笔记】OLED控制器SSD1306及驱动代码
51单片机-静态变量
1.static static一般不用在主函数中,大多数在中断函数和封装好的子函数里运用,它的作用是保证在子函数或中断函数中定义的变量每次调用完之后都可以保持调用完时候的值,《手把手教你学51单片机》文档7.2节有这个知识点的讲解,不过我们还是用代码来解释这个static的作用吧。 2.举例 我们要实现像第四章第2讲的实验现象让数码管0从0到F循环显示。本次我们用的是函数封装,代码如下 #include reg52.h sbit ADDR2 = P1^2; sbit ADDR1 = P1^1; sbit ADDR0 = P1^0; sbit ENLED = P1^4; sbit ADDR3 = P1^3; unsign
[单片机]
51单片机+带字库液晶12864+DS1302数字时钟C源程序
经过两天的搜索与调试,在别人程序的基础上,不断修改,终于调试成功了这个程序。 目前还不能修改时间与日期,只是以预定时间以始。 适用于开发板:51单片机(AT89S52)+带字库液晶12864(ST7920)+DS1302(实时时钟) 实现功能:简单,数字时钟+日期(以后会不断完美)。 C语言源程序如下: #include reg52.h #include intrins.h #define uchar unsigned char #define uint unsigned int /*DS1302 端口设置 */ sbit SCK=P3^6; //DS1302时钟 sbit SDA=P3^4; //DS1
[单片机]
单片机浮点数的实用快速降法
    摘要: 介绍一种在8096/96系列单片机上实现的单精度浮点数快速除法。该算法采用了预估一修正的数值计算方法,并充分利用了16位CPU中的乘除法指令,计算速度快、精度高,有很强的实用性。     关键词: 浮点数 除法 尾数 预估-修正 误差 精度 在较为复杂的单片机系统中,为扩大取值范围,实现复杂的计算和控制,一般都要涉及浮点数的运算。而一般单片机是没有浮点数运算指令的,必须自行编制相应软件。在进行除法计算时,通常使用的方法是比较除法 ,即利用循环移位和减法操作来得到24~32位商,效率很低。有些文献给出了一些改进方法 ,但思想不清晰,很难推广使用。这里给出一种浮点数除法运算的实用快速算法。该方法以
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

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