C语言小结--float short等非char型数据传输问题

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u014421520/article/details/83001948

1.问题描述

最近开发中需要使用can传输float和short型数据,我们知道一般的嵌入式平台的通讯端口如CAN、串口、网络等都是以字节(byte)为单位传输的,那么怎么传输float、short等类型的数据呢?尤其是带符号位的数据。

2.解决思路

使用共用体(union)
首先创建一个结构体,然后在结构体成员中创建共用体。如下所示:

//底盘状态结构体
typedef struct _T_UnderPanState
{
    uint32_t TimeStopCount; //运动停止计时
    bool TimeCountFlag;     //开始运动计数标志
    bool TimeStopCountFlag; //运动停止计时标志    
    int16_t GetLeftSpeed;      //左轮反馈速度
    int16_t GetRightSpeed;     //右轮反馈速度
    float InitDenc[3];      //起始编码器位置
    union
    {
        int16_t MotorSpeed;     //电机转速
        uint8_t ucMotorSpeed[2];
    };
    union
    {
        uint32_t TimeCount;     //运动时间计数
        uint8_t ucTimeCount[4];    
    };    
    union
    {
        float Distance;         //运动距离  mm
        uint8_t ucDistance[4];
    };
    union
    {
        float Angle;            //转动角度
        uint8_t ucAngle[4];
    };
    union
    {
        float VxMMPS;            //直线运动速度 mm/s
        uint8_t ucVxMMPS[4];
    };
    union
    {
        float OmegaRPM;            //旋转速度  
        uint8_t ucOmegaRPM[4];
    };

}T_UnderPanState;


extern T_UnderPanState UnderPanState;

这么做的好处就是在运算的时候,我们可以直接使用float型数据做运算,然后在传输的时候,使用uint8_t类型的数组传输,在接收端,同样定义一个这样的结构体,使用uint8_t类型的数组接收数据,然后使用float型的变量做运算,这样不但节省了内存,而且跨平台,通用性好。

接下来贴一个我的打包发送代码片段,大家体会一下。

           memcpy(&wifimesstemp[0], UnderPanState.ucMotorSpeed, 2);
           memcpy(&wifimesstemp[2], UnderPanState.ucTimeCount, 4);
           memcpy(&wifimesstemp[6], UnderPanState.ucDistance, 4);
           memcpy(&wifimesstemp[10], UnderPanState.ucAngle, 4);
           memcpy(&wifimesstemp[14], UnderPanState.ucVxMMPS, 4);
           memcpy(&wifimesstemp[18], UnderPanState.ucOmegaRPM, 4);
           WifiMsgPack(23, APP_GET_UNDERPAN_STATE_BACK, wifimesstemp,TRUE,&WifiTcpMessage);  

在接收端的处理非常简单:
我们先定义一个同发送端一样的结构体:

//底盘状态结构体
typedef struct _T_TestUnderPanState
{

        int16_t MotorSpeed;     //电机转速

        uint32_t TimeCount;     //运动时间计数

        float Distance;         //运动距离  mm

        float Angle;            //转动角度

        float VxMMPS;            //直线运动速度 mm/s
 
        float OmegaRPM;            //旋转速度  


}T_TestUnderPanState;

然后直接拷贝数据到该结构体中:

//模拟发送部分
    memcpy(&temp[0], UnderPanState.ucMotorSpeed, 2);
    memcpy(&temp[2], UnderPanState.ucTimeCount, 4);
    memcpy(&temp[6], UnderPanState.ucDistance, 4);
    memcpy(&temp[10], UnderPanState.ucAngle, 4);
    memcpy(&temp[14], UnderPanState.ucVxMMPS, 4);
    memcpy(&temp[18], UnderPanState.ucOmegaRPM, 4);     
    
    //假设我们收到的数据存在temp数组中
    memcpy((uint8_t *)(&TestUnderPanState.MotorSpeed), temp, 22);	//接收

是不是使用起来非常方便。

在keil中这样定义一个无名union的时候记得要勾选上 GNU extensios,如下图,否则会报错。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u014421520/article/details/83001948