引言
在嵌入式系统和移动应用开发领域,理解蓝牙通信中的数据传输和格式转换是至关重要的。本文深入探讨STM32(一种广泛使用的微控制器)与Android手机通过蓝牙进行通信时,数据的格式和转换过程。特别是,我们将聚焦于二进制与十六进制数据的转换以及其在实际应用中的重要性。
蓝牙数据传输格式
在蓝牙通信中,无论是从STM32到Android手机还是反向传输,数据本质上都是以二进制字节流的形式进行的。二进制格式是计算机和电子设备最基础的数据表示方式,它以字节(通常是8位)为单位传输信息。
十六进制数据的角色
尽管二进制格式在机器层面上是通用的,但对于人类来说,直接阅读和理解二进制数据却是困难的。这就是十六进制(Hex)格式的用武之地。十六进制格式通过将每个字节表示为两个十六进制数字,提供了一种更易于阅读和理解的数据格式。例如,二进制字节 `10101010` 可以表示为十六进制的 `AA`。
数据转换的实际应用
考虑一个具体的场景:STM32发送以下16进制表示的数据:
```
BB CC 00 00 05 9A 00 00 05 9A 00 00 00 00 00 00 00 00 0D 0A
```
这串数据首先在stm32中以二进制形式发送,然后在Android端收到的数据也是二进制的字节流,所以我们要以十六进制字符串的形式显示,用于调试或展示目的。
二进制字节流转成16进制字符串:
// read回调函数 接收消息
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
//接收数据
byte[] bytes = characteristic.getValue();
final StringBuilder stringBuilder = new StringBuilder(bytes.length);
for (byte byteChar : bytes)
stringBuilder.append(String.format("%02X ", byteChar));
Log.d(TAG, String.valueOf( stringBuilder));
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
在Android应用中的处理
当需要对接收到的数据进行解析或操作时,十六进制字符串需要被转换回二进制格式。这是因为大多数程序逻辑和数据处理操作都是在二进制数据上进行的。
例如,如果我们接收到的十六进制字符串表示某些特定的命令或测量数据,我们需要将其转换为二进制格式以便进一步解析这些值。
在Android中,这个转换可以通过以下函数实现:
public static byte[] hexString2Bytes(String hex) {
if ((hex == null) || (hex.equals(""))){
return null;
}
else if (hex.length()%2 != 0)
{
Log.d(TAG, "%2 != 0");
return null;
}
else
{
hex = hex.toUpperCase();
int len = hex.length()/2;
byte[] b = new byte[len];
char[] hc = hex.toCharArray();
for (int i=0; i<len; i++){
int p=2*i;
b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p+1]));
}
return b;
}
}
这个函数将十六进制字符串转换为字节流,使其可以被程序逻辑正确地处理。例如,解析特定的传感器数据或执行与设备状态相关的命令。
数据解析
一旦数据以二进制格式回复,我们就可以在原始格式上执行数据解析。这可能包括提取特定的数值、解码指令或执行与数据相关的操作。
例如,一个常见的操作可能是解析位置和速度信息,以便在应用程序中使用:
public void parseAndDisplayData(byte[] data) {
if (data.length < 20) {
// 数据不完整
return;
}
// 检查数据包的起始字节
if (data[0] == (byte)0xBB && data[1] == (byte)0xCC) {
// 解析 L_pos
int L_pos = ((data[2] & 0xFF) << 24) |
((data[3] & 0xFF) << 16) |
((data[4] & 0xFF) << 8) |
(data[5] & 0xFF);
// 解析 R_pos
int R_pos = ((data[6] & 0xFF) << 24) |
((data[7] & 0xFF) << 16) |
((data[8] & 0xFF) << 8) |
(data[9] & 0xFF);
// 解析 L_speed
short L_speed = (short)(((data[10] & 0xFF) << 8) |
(data[11] & 0xFF));
// 解析 R_speed
short R_speed = (short)(((data[12] & 0xFF) << 8) |
(data[13] & 0xFF));
// 输出解析结果
Log.d("BluetoothData", "L_pos: " + L_pos + ", R_pos: " + R_pos + ", L_speed: " + L_speed + ", R_speed: " + R_speed);
} else {
// 数据包不是以0xBB, 0xCC开头的,可能是无效的
Log.d("BluetoothData", "Received data does not start with expected header.");
}
}
结论
理解STM32与Android设备之间蓝牙通信的数据格式及其转换过程,对于开发相关的应用程序至关重要。十六进制格式提供了一种方便的方式来记录和调试传输的数据,而二进制格式则是执行程序逻辑和处理数据的基础。