tsuibeyond的博客

大道至简 知易行难

单片机中16进制与浮点数互换

@(攻城狮)[单片机,数据传输]
声明:
本文内容主要参考
十六进制 浮点数格式
单片机传递浮点数方法

对于大小为32-bit的浮点数(32-bit为单精度,64-bit浮点数为双精度,80-bit为扩展精度浮点数),
1、其第31 bit为符号位,为0则表示正数,反之为复数,其读数值用s表示;
2、第30~23 bit为幂数,其读数值用e表示;
3、第22~0 bit共23 bit作为系数,视为二进制纯小数,假定该小数的十进制值为x;

用数学公式表示为:
(1)s(1+x)2(e127)

举个例子:
16进制:49E48E68
2进制:0100 1001 1110 0100 1000 1110 0110 1000
从右往左数,分别是第0位,第1位,……,第31位

那么
- 第31位是0,即s=0;
- 第30~23位依次是 10010011,转换成10进制是147,也就是说e=147
- 第22~0位依次是11001001000111001101000,是二进制纯小数,即0.11001001000111001101000,其10进制形式为0.78559589385986328125,也就是说x=0.78559589385986328125

说明:一个二进制数:abc.def=a22+b21+c20+d2(1)+e2(2)+f2(3)
- 最后,该浮点数的10进制表示

(1)s×(1+x)×2e127=(1)0×(1+0.78559589385986328125)×2147127=1872333

在单片机的处理中,通常有三种方法进行浮点数的传输:
- 将浮点数转化为整数,然后传递整数的ascII码形式;
- 进行编码,这个暂时我是这样理解的,比方说a=7.345678这样的浮点数,可以进行编码 成一个帧数据 帧头 +数据位+ 整数编码+加小数点+小数编码,具体的解码方法是:a/1取整,得到整数7,然后再添加一个小数点编码!(如0x55),然后再用a-7得到小数部分,然后将小数扩大10倍。再取整然后继续进行取整,以此类推将
- 第三种方法也是利用内存,不用知到浮点数的具体编码方式,因为在单片机中浮点数占4个字节,就知道这一点就可以了,我们可以采用联合体的方式。

显然,第三种方法更好,不会带来更多的编解码负担。
直接上代码:

#include<iostream>
#include<string.h>
using namespace std;

float hexTofloat(char* test);
union data
{
    float out;
    char in[4];
}temp;
int main(void)
{
    temp.in[0] =0X00;
    temp.in[1] =0X58;
    temp.in[2] =0X7F;
    temp.in[3] =0XBF;
    cout << temp.out << endl;
    getchar();
    return 0;
}

直接运行后,屏幕上会显示:-0.997437
(加速度计的z轴数据,单位:g,数据来源于curs2传感器)

关于程序的理解,可以查阅关于联合体的定义与使用,因为浮点数占用四个字节,那我们就直接把存放这四个字节的地址中的内容拿出来发送出去就可以了。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tsuibeyond/article/details/52370492
想对作者说点什么? 我来说一句

浮点数与十六进制数互转工具

2016年11月20日 56KB 下载

没有更多推荐了,返回首页

不良信息举报

单片机中16进制与浮点数互换

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭