1. 问题提出
笔者在系统开发中采取RS485实现单片机和外围设备通信,通信采取通用串行接口协议(USS),根据串行总线主从通讯原理来确定访问方法。USS要求了一套严格通信规则,相关浮点数参数值,USS要求采取IEEE-754格式进行传送。比如,,在通信中传送是它IEEE-754格式,,单片机C程序,在发送或接收外围设各参数值时,需要处理怎样实现浮点数和IEEE格式转换问题。
在计算机中,浮点数存放均采取4字节IEEE-754格式。比如,:二进制:
其中,最高位表示符号,"1"表示负,"0"表示正;第23~30位表示阶码。注意:~22位是尾数部分。尾数整数部分永远为1,所以不予保留,但它是隐含存在。一个浮点数计算式为:
比如,前面绘出浮点数表示形式中,s=0,n=132,m=(1/2+0/4+0/8+1/16+0/32+……),.
在最初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个字节即可。
定义union数据
typedef union
IEEE754数据转换程序样稿 来自淘豆网m.daumloan.com转载请标明出处.