浮点数与IEEE格式转换
eeskill 2022-01-19

1. 问题的提出

笔者在系统开发中采用RS485实现单片机与外围设备的通信,通信采用通用串行接口协议(USS),按照串行总线的主从通讯原理来确定访问的方法。USS规定了一套严格的通信规则,关于浮点数参数值,USS规定采用IEEE-754格式进行传送。例如,浮点数50.0,在通信中传送的是它的IEEE-754格式,即4字节的十六进制424800H.因此,单片机的C程序,在发送或接收外围设各的参数值时,需要解决如何实现浮点数与IEEE格式转换的问题。

2.IEEE浮点数的格式

在计算机中,浮点数的存储均采用4字节的IEEE-754格式。例如,浮点数50.0的IEEE表示形式如下:二进制:

其中,最高位表示符号,"1"表示负,"0"表示正;第23~30位表示阶码。注意:阶码是以2为底的指数再加上偏移量127.第0~22位是尾数部分。尾数的整数部分永远为1,因此不予保存,但它是隐含存在的。一个浮点数计算式为:

例如,前面绘出的浮点数的表示形式中,s=0,n=132,m=(1/2+0/4+0/8+1/16+0/32+……),则计算结果为50.0.

3.浮点数与IEEE格式转换

在最初的C语言编程中,笔者根据上面介绍的IEEE表示形式,采用移位计算的方法实现浮点数和IEEE格式转换。当接收到外围设备传来的4字节IEEE格式参数值时,依次将符号、阶码、尾数通过移位取出,然后按照IEEE计算规则计算出对应的浮点数。当需要发送给外围设备的浮点数时,按相反的方法将其转化为IEEE格式后再发送出去。

笔者一直感觉上述方法太麻烦,而且效率太低。后来笔者想到,既然在C语言中浮点数本身就是采用IEEE格式来存储的,能否利用C语言本身的机制来实现浮点数和IEEE格式的转换?经过尝试,发现利用unlon数据类型可以很好地完成这工作,即只需定义下面这个union类型:

注意:类型定义的后面别忘了还有个符号";",union类型虽然有两个内部变量,但两个内部变量占用同-地址空间,它只占用4个字节。内部float变量a(占用4个字节)和char数组b(同样占用4个字节)从同一个地址开始存放,并共享同一块内存空间。C语言中,对于单精度浮点数a,采用四个字节(IEEE格式)来存储,依次存储在四个连续的存储单元内,低字节存储在低地址存储单元,高字节存在高地址存储单元;字符数组b也采用和a同样的存储方式。利用unlon数据类型,可以直接访问浮点数以IEEE格式存放在存储单元中的十六进制字节,通过直接读取或修改这些十六进制字节,便可以巧妙地实现浮点数与IEEE格式的转换。

(1)IEEE格式转换浮点数

当单片机接收来自USS总线的数据时,只需将4个字节的数据放到内部变量b中,再访问内部变量a,即可实现转换。下面给出示意程序,供参考。

(2)浮点数转换IEEE格式

当单片机处理好数据后,需要把浮点型的数据转换成IEEE格式,输出给USS总线。只需把数据赋予内部变量a,再从内部变量b中取出对应的4个字节即可。

此方法缩短了代码的长度,效率得到明显提高,在实际应用中效果非常好。

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 相关技术文库
  • C语言
  • 编程
  • 软件开发
  • 程序
  • 初学者学习C51的一些误区和注意事项

    [导读]这里讲述一些初学者学习C51的一些误区和注意事项。高手的特别应用不包括在内。1)C忌讳绝对定位。常看见初学者要求使用_at_,这是一种谬误,把C当作AS

    9小时前
  • 单片机C语言K1-K4分组控制LED

    [导读]/* 名称:K1-K4 分组控制 LED*/说明:每次按下 K1 时递增点亮一只 LED,全亮时再次按下则再次循环开始, K2 按下后点亮上面

    9小时前
  • 单片机C语言程数码管移位、加减显示

    [导读]K1-K4 控制数码管移位显示/* 名称:K1-K4 控制数码管移位显示说明:按下 K1 时加 1 计数并增加显示位,按下 K2 时减 1 计数并减

    9小时前
  • PIC的配置位

    [导读]一.配置字PIC单片机的配置字可以用__CONFIG命令来定义:# include__CONFIG(x)其中x是配置字,头文件中定义了相应的配置说明符,

    05-13
  • Linux进程调度模拟程序(最高优先算法源码)

    1.最高优先算法源码:要求:对课程设计题目(以下简称课题)进行综述,明确提出本文的目的,写出关键内容和主要观点,#include#include#include

    05-13
  • 代码实例:LCD1602 显示程序

    [导读]#include#define uchar unsigned charsbit rs=P2^0; //lcd1602 rs端sbit rw=P2^1;

    05-13
  • 基于微控制器的架构中的传感器采集架构解析

    引言今天的便携式设备通过持续的活动监测和情境感知来了解周围环境。为了实现这个功能,设备集成了越来越多的传感器和外设,由此产生大量数据。这反过来使得集成更强大的C

    05-12
  • ARM汇编MRS指令的格式

    1、MRS指令MRS指令的格式为:MRS{条件}通用寄存器程序状态寄存器(CPSR或SPSR)MRS指令用于将程序状态寄存器的内容传送到通用寄存器中。该指令一般

    05-10
  • C语言中各变量存储的位置

    局部变量、局部静态变量、全局变量、全局静态变量区别如下:局部变量:栈区;局部静态变量:静态区;全局变量:静态区的常量区;全局静态变量:静态区。在进行C/C++编

    05-07
  • 细说ISP 和IAP 的区别

    IAP(InAppplicationProgram),即在应用中可编程。顾名思义,就是在系统运行的过程中动态编程,这种编程是对程序执行代码的动态修改,而且毋须借

    05-06
  • 单片机C语言程序设计:闪烁的LED

    [导读]/* 名称:闪烁的 LED说明:LED 按设定的时间间隔闪烁*/#include#define uchar unsigned ch

    05-05
  • 单片机C语言程序设计:从左到右的流水灯程序

    [导读]/* 名称:从左到右的流水灯说明:接在 P0 口的 8 个 LED从左到右循环依次点亮,产生走马灯效果*/#include#inc

    05-05
下载排行榜
更多
广告