串口數據的打包和解包


串口通信實際包含了物理層、數據鏈路層、應用層三方面的功能。這里的解包和打包指的是在應用層的操作,因為應用數據是在這一層由開發人員自行編寫的;
如果應用數據采用的純ASCII方式傳輸的,主要好處就是人為可識別,但報文會相應加長;采用純Hex字節方式傳輸的,同樣的數據量下報文較短,但是不好識別,字符顯示看起來就像亂碼。也有混合在一起,報文的部分字段用ASCII定義,部分字段采用Hex字節方式的,這里不表。


一、像純ASCII方式的,一般用字符串格式命令,比如sprintf,sscanf等;比如報文是以固定的“$AAA,”開頭並帶固定格式的,就可采用下述方式的解析:

struct MS_AAA
{
   char flag;
   float PDOP;
   float HDOP;
   float VDOP;

   int analyze(const char* ch)
   {
       int crc = 0;
       if ( 0 < sscanf (ch, "$AAA,%c,%f,%f,%f*%d\r\n", //這里就是報文的格式
                               &flag,
                               &PDOP,
                               &HDOP,
                               &VDOP,
                               &crc))
        {

            //這里其實可以看看校驗crc到底對不對
            return 0;
        }
        return -1;
   }
};

二、像純Hex字節方式傳輸的,一般會采用一個結構體來描述報文(注意字節對齊),然后通過結構體指針和字符指針之間的強制轉型的方式進行,比如報文起始就是16進制表示的4字節ID號、2字節報文長度、4字節時戳的,就可如下的解析:

#pragma pack(1)  //單字節對齊
typedef struct
{
     uint32_t id;
     uint16_t lenth;
     uint32_t timestamp;
} FrameHeader;

int handleRecvData(const unsigned char* uch)
{
    int i = 0;
    FrameHeader header = *((FrameHeader*)&uch[0]);
    if (header.id != 0x35)
    {
           printf("#### frame's ID error.\n");
           return -1;
    }
    if (header.lenth > 1400)
    {
           printf("#### frame's Lenth error.\n");
           return -2;
    }
     //****
     return 0;
}

三、混合方式的,可靈活采用上述兩種方式;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM