| 字段 | 长度(字节) | 说明 |
| STX | 1 | 开始控制字符 0x02 |
| 数据长度 | 2 | 传输时需要转换成INTEL序(高字节在前)数据体部分长度。最大允许值为:4096 |
| 数据体 | 不定 | 由数据长度决定 |
| 校验字节 | 1 | 校验字节是报文中除通信控制字符之外所有数据的校验和 |
| ETX | 1 | 结束控制字符 0x03 |
通过宏BROKEN_FRAME可以控制断帧测试或是连帧测试 ,代码中有详细注释说明
- #include
- #include
- #include
-
- //最大缓存区
- #define MAX_BUFFER_SIZE 4096
-
- //帧格式
- typedef struct {
- unsigned char start;
- unsigned short length;
- unsigned char data[MAX_BUFFER_SIZE/4];
- unsigned char checksum;
- unsigned char end;
- } Frame;
-
- //定义缓存区和缓存区当前索引
- unsigned char buffer[MAX_BUFFER_SIZE];
- int bufferIndex = 0;
-
- //打印hex数据
- void print_mesg(char *head, unsigned char *data, int len)
- {
- printf("%s", head);
- for(int i=0; i
- {
- printf("%02X ",data[i]);
- }
- printf("\n");
- }
-
- /**
- * 返回单字节校验和
- */
- unsigned char GetCheckSum(unsigned char *data, uint32_t data_size)
- {
- int i = 0;
- uint32_t temp = 0;
- uint8_t sum = 0;
- for(i = 0;i
- {
- temp += *(data+i);
- }
- sum = temp&0xff;
- return sum;
- }
-
- //接收数据处理
- void processFrame(Frame frame) {
- // 在这里处理接收到的帧数据
- // 可以根据具体需求对数据进行解密、校验等操作
- // 例如,可以打印数据体内容
- print_mesg("Received data:", frame.data, frame.length);
- }
-
- //接收数据放到缓存区
- void addToBuffer(unsigned char *data, int data_len) {
- // 将帧数据添加到缓存区
- if((bufferIndex+data_len) > MAX_BUFFER_SIZE)
- {
- bufferIndex = 0;
- memset(buffer, 0, MAX_BUFFER_SIZE);
- return;
- }
- memcpy(&buffer[bufferIndex],data, data_len);
- bufferIndex += data_len;
- }
-
- //解析帧
- void parseFrame(unsigned char* data, int length) {
- printf("length=%d\n",length);
- print_mesg("Received:", data, length);
- Frame frame;
- memset(&frame, 0, sizeof(Frame));
- addToBuffer(data, length);
-
- int dataIndex = 0;
- while (bufferIndex > 5) {
- if (buffer[dataIndex] != 0x02) {
- // 数据起始标志错误,丢弃当前帧
- dataIndex++;
- continue;
- }
- printf("dataIndex=%d\n",dataIndex);
-
- if (bufferIndex - dataIndex < 5) {
- // 数据长度不足,无法解析帧
- break;
- }
-
- frame.start = buffer[dataIndex];
- frame.length = (buffer[dataIndex + 1] << 8) | buffer[dataIndex + 2];
-
- if (bufferIndex - dataIndex < frame.length + 5) {
- // 数据长度不足,无法解析帧
- break;
- }
-
- memcpy(frame.data, buffer + dataIndex + 3, frame.length);
- frame.checksum = buffer[dataIndex + frame.length + 3];
- frame.end = buffer[dataIndex + frame.length + 4];
-
- // 检查校验和
- unsigned char checksum = GetCheckSum(&buffer[dataIndex+1], frame.length+2);
- printf("checksum:%02X\n",checksum);
- printf("frame.checksum:%02X\n",frame.checksum);
- printf("frame.end:%02X\n",frame.end);
- print_mesg("data:", frame.data, frame.length);
-
- if (checksum != frame.checksum || frame.end != 0x03) {
- // 校验和或控制字符错误,丢弃帧
- dataIndex++;
- continue;
- }
-
- processFrame(frame);
-
- dataIndex += frame.length + 5;
- bufferIndex -= dataIndex;
- memmove(buffer,buffer+dataIndex,bufferIndex);
- dataIndex=0;
- }
- }
-
- //是否断帧
- #define BROKEN_FRAME 1
-
- int main() {
- //0xFF为干扰字符
- unsigned char receivedData1[] = {0xFF,0x02, 0x00, 0x13, 0x10, 0x02, 0x00, 0x01, 0x32, 0x30, 0x32, 0x33, 0x31, 0x31, 0x30, 0x32, 0x31, 0x39, 0x35, 0x38, 0x30, 0x33, 0x02, 0xED, 0x03};
- //0xFF为干扰字符
- unsigned char receivedData2[] = {0x02, 0x00, 0x13, 0x10, 0x02, 0x00, 0x01, 0x32, 0x30, 0x32, 0x33, 0x31, 0x31, 0x30, 0x32, 0x31, 0x39, 0x35, 0x38, 0x30, 0x33, 0x02, 0xED, 0x03, 0xFF, 0x02, 0x00, 0x13, 0x50, 0x01, 0x00, 0x01, 0x62, 0x77, 0x74, 0x32, 0x31, 0x30, 0x38, 0x38, 0x32, 0x30, 0x34, 0x30, 0x31, 0x01, 0x00, 0xad, 0x03, 0x02, 0x00, 0x13, 0x50, 0x01, 0x00, 0x01, 0x62, 0x77, 0x74, 0x32, 0x31, 0x30, 0x38, 0x38, 0x32, 0x30, 0x34, 0x30, 0x31, 0x01, 0x00, 0xad, 0x03};
-
- int receivedLength1 = sizeof(receivedData1) / sizeof(receivedData1[0]);
- int receivedLength2 = sizeof(receivedData2) / sizeof(receivedData2[0]);
- #if BROKEN_FRAME //断帧处理
- parseFrame(receivedData1, receivedLength1-10);
- parseFrame(receivedData1+receivedLength1-10, 5);
- parseFrame(receivedData1+receivedLength1-5, 5);
- #else //连帧处理
- parseFrame(receivedData2, receivedLength2);
- #endif
- return 0;
- }
如果不需要连帧处理,仅仅简单的断帧处理可参考下面博文
-
相关阅读:
RealSense D435 的开发日记(pyrealsense小实战项目)
WPS 换行后缩进、加粗等自定义样式的清除
JavaScript 进阶03
php 日期
渗透测试-文件上传/下载/包含
如何保障需求质量(下):你应该做到的
【创建型模式】抽象工厂模式
Spring Security 中重要对象汇总
期货开户需要具备⼀定的条件
嵌入式4-24
-
原文地址:https://blog.csdn.net/lu_linux/article/details/134269954