《嵌入式通讯协议栈实战》 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------主从模式的硬件与软件实现

相关推荐
尾善爱看海8 小时前
Vue 面试收官篇:SSR、性能优化落地、30 道高频面试题精讲(附标准答案)
前端·javascript·vue.js·面试·vue
DeepAgent13 小时前
AI Agent 面试篇(02):面试路线总览——每一关考什么、题什么样、要准备什么
面试·agent
颜挺锐14 小时前
如何轻松通过性能测试面试之第十一篇:如何判断应用的最大处理能力
面试·职场和发展
DeepAgent15 小时前
AI Agent 面试篇(01):AI 岗位面试到底怎么走——从网申到 Offer 的完整流程
人工智能·面试·职场和发展
林太白15 小时前
js-var和let以及const区别
前端·面试
智购科技自动售货机工厂17 小时前
2026自动售货机端侧AI降本逻辑:从云端API到本地推理的成本重构~YH
人工智能·python·ui·面试·交互
野生技术架构师17 小时前
1000+ Java面试题知识图谱:从基础语法到分布式架构的完整拓扑
java·面试
流浪00118 小时前
Linux系统篇34——信号(六):信号处理期间又来了怎么办?——sigaction、sa_mask、可重入函数与 volatile
linux·运维·面试·操作系统·信号处理·信号
ssshooter19 小时前
Node.js 天生就是异步的,为什么还要消息队列?
javascript·后端·面试
金虹桥程序员19 小时前
【动画】 📚 CSS 动画与 GPU 合成层优化全链路指南
前端·面试