《嵌入式通讯协议栈实战》 3 通讯帧设计

第 3 篇:UART 协议设计------定义你自己的通讯协议


1. 帧格式设计

复制代码
┌──────┬──────┬──────┬──────┬──────┬──────┬──────┐
│ 帧头  │ 地址 │ 命令  │ 长度  │ 数据  │ CRC16 │ 帧尾  │
│ 2字节 │ 1字节│ 1字节 │ 1字节 │ N字节 │ 2字节 │ 1字节 │
│ 0xA5 │      │      │      │      │       │ 0x5A │
│ 0x5A │      │      │      │      │       │       │
└──────┴──────┴──────┴──────┴──────┴──────┴──────┘

2. 转义机制(SLIP 协议)

如果数据中恰好出现了 0xA5 或 0x5A,需要转义:

c 复制代码
#define FRAME_START  0xA5
#define FRAME_END    0x5A
#define ESCAPE_CHAR  0x7D

void slip_encode(uint8_t *in, int len, uint8_t *out, int *out_len) {
    for (int i = 0; i < len; i++) {
        if (in[i] == FRAME_START || in[i] == FRAME_END || in[i] == ESCAPE_CHAR) {
            out[(*out_len)++] = ESCAPE_CHAR;
        }
        out[(*out_len)++] = in[i];
    }
}

3. CRC16 校验

c 复制代码
uint16_t crc16_modbus(const uint8_t *data, int len) {
    uint16_t crc = 0xFFFF;
    for (int i = 0; i < len; i++) {
        crc ^= data[i];
        for (int j = 0; j < 8; j++) {
            if (crc & 1) crc = (crc >> 1) ^ 0xA001;
            else         crc >>= 1;
        }
    }
    return crc;
}

4. 逐字节解析状态机

c 复制代码
typedef enum { STATE_IDLE, STATE_HEAD1, STATE_HEAD2, STATE_ADDR,
               STATE_CMD, STATE_LEN, STATE_DATA, STATE_CRC1,
               STATE_CRC2, STATE_TAIL } proto_state_t;

void proto_parse_byte(proto_state_t *s, uint8_t byte) {
    switch (*s) {
        case STATE_IDLE:
            if (byte == 0xA5) *s = STATE_HEAD2; break;
        case STATE_HEAD2:
            *s = (byte == 0x5A) ? STATE_ADDR : STATE_IDLE; break;
        case STATE_ADDR:  frame.addr = byte; *s = STATE_CMD; break;
        // ... 依此类推
    }
}

状态机逐字节解析,不依赖于 DMA 缓冲区的起始位置------即使帧丢失也能自动恢复同步。


下一篇:I2C------主从模式的硬件与软件实现

相关推荐
考研保研资料分享7 小时前
211公共管理保研北航行政管理:五校考核、论文追问与择校复盘
面试
考研保研资料分享7 小时前
985工科跨保上财应用统计:数学笔试、匿名面试与机试复盘
面试·职场和发展
Aurora1110 小时前
Jane Street OA 真题解析:Mastermind 猜密码与候选集筛选
面试
skytier11 小时前
昇思大模型推理:输出 logits
面试
丑陋小蚊子12 小时前
简历电脑上清楚,手机上字太小,先改哪里?
面试·求职招聘·大学生·简历·简历下载
pipixia2003312 小时前
C++继承面试四连问:内存叠加、私有继承、sizeof、权限重映射
c++·面试·嵌入式·继承·面向对象·对象模型
加洛斯13 小时前
万字推演Elasticsearch修炼方法,从炼气到元婴
后端·elasticsearch·面试
zhippt_101414 小时前
图转PPT实测:截图和课件图片怎么变成可编辑幻灯片
人工智能·面试·powerpoint
devilnumber14 小时前
Redis 数据类型 + 项目落地场景(面试版,全面、实用,后端常用)
数据库·redis·面试
萧瑟余晖16 小时前
Spring Data Redis详解
spring·面试