自定义字节协议传输float数据类型

字节协议传输float类型数据

float类型数据的传输有很多种,例如将float放大为整形进行传输,例如float有两位小数,在传输的过程*100放大为整型进行发送,接收端在收到后/100还原,但这种方法仅仅适用于已知小数位数的操作,如果小数位数未知则不适用,所以通过字节方式直接传输更为方便。本文中用于Android上位机通过自定义字节协议向STM32下位机传输用户输入的不定长小数位的float数据。

传输思路

  1. android上位机获取EditText中填入的数据
  2. 将数据通过android自带的“Float.floatToIntBits()”方法将float类型数据转为IEEE 754标准的二进制数据格式
  3. float为32位4字节,上位机中用4字节的byte数组来保存要传输的数据,通过移位的方法将每个字节放入对应的byte中,注意大小端模式下位机解析时要一致
  4. 指定协议为0x44,0x4A,(帧头DJ)0x00,0x00,0x00,0x00,(参数1) 0x00,0x00,0x00,0x00,(参数2)0x00,0x00,0x00,0x00,(参数3) 0xFC(帧尾)
  5. stm32将接收到的4字节byte数组转为二进制,利用IEEE754格式将二进制转为float格式。

上位机android部分

android测试数据

上位机数据转换

 if(!et_para1.getText().toString().isEmpty()) {
	/*获取输入的float类型数据*/
	para1_f = Float.parseFloat(et_para1.getText().toString());
    /*将float类型转换为IEEE 754数据格式*/
    int fbit1 = Float.floatToIntBits(para1_f);
    /*向下位机传输4字节的float类型值*/
    send_byte[2] = (byte) (fbit1 >> 24);
    send_byte[3] = (byte) (fbit1 >> 16);
    send_byte[4] = (byte) (fbit1 >> 8);
    send_byte[5] = (byte) fbit1;
}

上位机解析IEEE754标准的float数据

 /**
     * 字节转换为浮点
     * @param b 字节(4个字节)
     * @return
     */
    public static float fourbyteTOfloat(byte[] b) {
        int l;
        l = b[0];
        l &= 0xff;
        l |= ((long) b[1] << 8);
        l &= 0xffff;
        l |= ((long) b[2] << 16);
        l &= 0xffffff;
        l |= ((long) b[3] << 24);
        return Float.intBitsToFloat(l);
    }
	@Override
	public void onClick(View view) {
		byte[] para1 = new byte[4];
	    para1[3] = send_byte[2];
	    para1[2] = send_byte[3];
	    para1[1] = send_byte[4];
	    para1[0] = send_byte[5];
	    String str_anls = "para1:"+ fourbyteTOfloat(para1) + "\r\n";
	    anls_tev.setText(str_anls);
	}

下位机C语言部分

利用C语言在线编译将参数对应的byte数组带入测试

#include <stdio.h>
#include <math.h>

typedef unsigned char byte;
int fourBytesToInt( byte b1, byte b2, byte b3, byte b4 ) {
    return ( b1 << 24 ) + ( b2 << 16 ) + ( b3 << 8 ) + b4;
}
float intBitsToFloat( int bits ) {
    /* s 为符号(sign);e 为指数(exponent);m 为有效位数(mantissa)*/
    int
    s = ( bits >> 31 ) == 0 ? 1 : -1,
    e = ( bits >> 23 ) & 0xff,
    m = ( e == 0 ) ?
                     ( bits & 0x7fffff ) << 1 :
                     ( bits & 0x7fffff ) | 0x800000;
    return s * m * ( float ) pow( 2, e - 150 );
}
int main()
{
	int bits = fourBytesToInt(0x3f,0x8f,0xcd,0x36);
   	printf("para1: ");
	printf( "%f\n", intBitsToFloat(bits) );
	
	int bit2 = fourBytesToInt(0x41,0xbc,0x8a,0xdb);
	printf("para2: ");
	printf( "%f\n", intBitsToFloat(bit2) );
	
	int bit3 = fourBytesToInt(0x42,0x10,0x00,0x00);
   	printf("para3: ");
	printf( "%f\n", intBitsToFloat(bit3) );
	
	return 0;
}

运行结果:

$gcc -o main *.c -lm
$main
para1: 1.123450
para2: 23.567801
para3: 36.000000
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值