1. 程式人生 > >C語言小結--float short等非char型資料傳輸問題

C語言小結--float short等非char型資料傳輸問題

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,如下圖,否則會報錯。

在這裡插入圖片描述