您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# STM32怎么收发float类型数据
## 引言
在嵌入式开发中,STM32系列MCU因其高性能和丰富的外设被广泛应用。实际项目中经常需要处理浮点数(float)数据,例如传感器采集的温湿度、运动控制的坐标值等。本文将详细介绍STM32如何通过串口、CAN、SPI等通信接口收发float类型数据,并分析其中的关键技术要点。
---
## 一、float类型的数据特性
### 1.1 float的内存表示
- 遵循IEEE 754标准
- 32位存储(1位符号 + 8位指数 + 23位尾数)
- 示例:3.14f的十六进制表示为0x4048F5C3
### 1.2 嵌入式系统中的处理难点
- 不同平台可能存在字节序差异
- 直接传输二进制可能引发兼容性问题
- 部分低端MCU不支持硬件浮点运算
---
## 二、基础传输方法:字节拆分与重组
### 2.1 使用指针强制转换
```c
float f = 3.14f;
uint8_t buffer[4];
*(float*)buffer = f; // 写入缓冲区
// 接收端重组
float received = *(float*)buffer;
typedef union {
float f_val;
uint8_t bytes[4];
} FloatConverter;
FloatConverter converter;
converter.f_val = 3.14f;
HAL_UART_Transmit(&huart1, converter.bytes, 4, 100);
发送端代码:
void send_float_via_uart(float data) {
uint8_t *p = (uint8_t*)&data;
HAL_UART_Transmit(&huart1, p, 4, HAL_MAX_DELAY);
}
接收端代码:
float receive_float_via_uart() {
uint8_t buffer[4];
HAL_UART_Receive(&huart1, buffer, 4, HAL_MAX_DELAY);
return *(float*)buffer;
}
// 发送端
char str[32];
sprintf(str, "%.4f", 3.1415);
HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), 100);
// 接收端
char rx_buf[32];
HAL_UART_Receive(&huart1, (uint8_t*)rx_buf, sizeof(rx_buf), 100);
float val = atof(rx_buf);
CAN_TxHeaderTypeDef tx_header;
uint8_t can_data[8];
float temp = 25.5f;
memcpy(can_data, &temp, 4);
tx_header.StdId = 0x123;
tx_header.IDE = CAN_ID_STD;
tx_header.RTR = CAN_RTR_DATA;
tx_header.DLC = 4;
HAL_CAN_AddTxMessage(&hcan, &tx_header, can_data, &tx_mailbox);
当需要传输多个float时:
float dataset[2] = {1.23f, 4.56f};
memcpy(can_data, dataset, 8);
tx_header.DLC = 8;
float spi_send_float(float data) {
uint8_t tx_buf[4], rx_buf[4];
*(float*)tx_buf = data;
HAL_SPI_TransmitReceive(&hspi1, tx_buf, rx_buf, 4, 100);
return *(float*)rx_buf;
}
// 大端转小端
void float_to_bytes_big_endian(float f, uint8_t bytes[4]) {
uint32_t val = *(uint32_t*)&f;
bytes[0] = (val >> 24) & 0xFF;
bytes[1] = (val >> 16) & 0xFF;
bytes[2] = (val >> 8) & 0xFF;
bytes[3] = val & 0xFF;
}
推荐添加CRC8校验:
uint8_t crc8(const uint8_t *data, size_t len) {
uint8_t crc = 0xFF;
while (len--) {
crc ^= *data++;
for (uint8_t i = 0; i < 8; i++)
crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : crc << 1;
}
return crc;
}
__attribute__((aligned(4)))
[头0xAA][float roll][float pitch][float yaw][CRC8]
本文详细介绍了STM32处理float数据的各种方法。关键点总结: 1. 理解float的内存表示是基础 2. 指针和联合体是实现转换的有效工具 3. 不同通信接口需要适配对应的传输方案 4. 必须考虑字节序和校验等可靠性问题
实际项目中建议根据具体需求选择最适合的方案,平衡性能、可靠性和开发效率。
注意事项:
- 启用FPU需在CubeMX中配置
- 跨平台通信时务必验证字节序
- 关键数据建议增加时间戳和校验机制 “`
该文章包含: 1. 技术原理说明 2. 多种通信接口的实现代码 3. 实际应用案例 4. 常见问题解决方案 5. 格式规范的代码片段 6. 关键注意事项提示
可根据需要进一步扩展具体通信协议的实现细节或添加性能测试数据。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。