目录
一、浮点型数据接收
(一)数据包接收
1)逻辑结构
2)代码部分(以下全部放在serial.c中)
1、先定义如下变量:
uint8_t recvData; //接收数据缓存
uint8_t recvFlag; //标志位
uint8_t recvPacket[128] = {0}; //存放接收的数据
2、main中调用一次开启接收中断
void USART_IT_Enable()
{
HAL_UART_Receive_IT(&huart1, &recvData, 1);
}
3、编写回调函数
/* 中断回调函数 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
static uint8_t recvState = 0; //状态标志位
static uint8_t i = 0; //存放数据的数组的下标
//状态机
if (0 == recvState)
{
if (recvData == 0xFF)
{
recvState = 1;
i = 0;
}
}
else if (1 == recvState)
{
recvPacket[i] = recvData;
i++;
if (i >= DATALENGTH) //指定接收数据的长度
{
recvState = 2;
}
}
else if (2 == recvState)
{
if (recvData == 0xFE)
{
//到这里已经接收完成,添加对recvPacket的操作
i = 0;
recvState = 0;
recvFlag = 1; //表示接收完成
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&recvData, 1); //再开启接收中断
}
(二)对浮点型数据的处理(这里以接收三轴浮点数为例)
//先定义一个全局变量
float aim_x = 0, aim_y = 0, aim_z = 0;
//数据解析函数
static void Analysis_Data(uint8_t re_data[],float *x,float *y,float *z)
{
*x = Aplice_Float(re_data,0); //解析xyz数据
*y = Aplice_Float(re_data,1);
*z = Aplice_Float(re_data,2);
}
//字符拼接函数
static float Aplice_Float(uint8_t Tobe_Spliced[],int k)
{
uint8_t byteStream[sizeof(float)] = {0};
int added = 4*k; //用于拆分数据
// 逐字节接收字节流
for (int i = added; i < sizeof(float)+added; i++) {
byteStream[i - added] = Tobe_Spliced[i];
}
float data;
//memcpy(&data, byteStream, sizeof(float));//转换成float型
data = *(float*)byteStream;
return data;
}
//返回三轴数据
void Get_xyz(float *x, float *y, float *z)
{
*x = aim_x;
*y = aim_y;
*z = aim_z;
}
二、float型数据的发送
//串口发送函数
void bsp_USART_SendData(float floatData)
{
HAL_UART_Transmit(&huart1,(uint8_t*)0xA5,1,0xfffff);//头部标识
// 将 float 数据的地址强制转换为字节流的地址
uint8_t* byteStream = (uint8_t*)&floatData;
// 通过 USART 逐字节发送字节流
for (int i = 0; i < sizeof(float); i++) {
HAL_UART_Transmit(&huart1,&byteStream[i],1,0xffff);
}
}
通过以上代码自收发,实验测试如下:
三、使用stm32遇到的大小端问题
在stm32芯片中使用小端存储数据,即高位数据存储在高地址,这就导致发送端发送的是3F 99 99 99,单片机接收到的四个字节也依次是3F 99 99 99,但是将其直接转换为浮点数,它是将99 99 99 3F转换为浮点数,其结果是-1.5881724819422105e-23,所以,在数据解析时要进行字节转换。
float SwapFloat(float value) //Float大小端转换
{
union{
float f;
unsigned char b[4];
}source, dest;
source.f = value;
dest.b[0] = source.b[3];
dest.b[1] = source.b[2];
dest.b[2] = source.b[1];
dest.b[3] = source.b[0];
return dest.f;
}
double SwapDouble(double value) //Double大小端转换
{
union{
double d;
unsigned char b[8];
}source, dest;
source.d = value;
dest.b[0] = source.b[7];
dest.b[1] = source.b[6];
dest.b[2] = source.b[5];
dest.b[3] = source.b[4];
dest.b[4] = source.b[3];
dest.b[5] = source.b[2];
dest.b[6] = source.b[1];
dest.b[7] = source.b[0];
return dest.d;
}