字节协议传输float类型数据
float类型数据的传输有很多种,例如将float放大为整形进行传输,例如float有两位小数,在传输的过程*100放大为整型进行发送,接收端在收到后/100还原,但这种方法仅仅适用于已知小数位数的操作,如果小数位数未知则不适用,所以通过字节方式直接传输更为方便。本文中用于Android上位机通过自定义字节协议向STM32下位机传输用户输入的不定长小数位的float数据。
传输思路
- android上位机获取EditText中填入的数据
- 将数据通过android自带的“Float.floatToIntBits()”方法将float类型数据转为IEEE 754标准的二进制数据格式
- float为32位4字节,上位机中用4字节的byte数组来保存要传输的数据,通过移位的方法将每个字节放入对应的byte中,注意大小端模式下位机解析时要一致
- 指定协议为0x44,0x4A,(帧头DJ)0x00,0x00,0x00,0x00,(参数1) 0x00,0x00,0x00,0x00,(参数2)0x00,0x00,0x00,0x00,(参数3) 0xFC(帧尾)
- stm32将接收到的4字节byte数组转为二进制,利用IEEE754格式将二进制转为float格式。
上位机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