串口通信實際包含了物理層、數據鏈路層、應用層三方面的功能。這里的解包和打包指的是在應用層的操作,因為應用數據是在這一層由開發人員自行編寫的;
如果應用數據采用的純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;
}
三、混合方式的,可靈活采用上述兩種方式;
