通信校验CRC15使用过程示例

张开发
2026/4/22 19:06:25 15 分钟阅读

分享文章

通信校验CRC15使用过程示例
一、先明确CAN CRC15 标准参数多项式0x4599初始值0x0000输入不反转、输出不反转最终异或0x0000结果只取低 15 位crc 0x7FFF二、示例数据模拟 CAN 一段数据用最简单的 1 字节数据演示方便手算待计算数据0x11三、手动计算完整过程逐行详解初始crc 0x0000第一步异或 移位CAN CRC15 处理一个字节时crc crc ^ (data 7)0x11 7 0x880所以crc 0x0000 ^ 0x880 0x880第二步循环 8 次逐位处理规则若 crc最高位第 15 位0x4000 1→crc (crc 1) ^ 0x4599否则→crc crc 1当前 crc 0x880二进制0000100010000000最高位 0x4000? →否开始 8 轮第 1 次0x880 1 0x1100第 2 次0x1100 1 0x2200第 3 次0x2200 1 0x4400现在最高位 0x4000 1→ 0x4400 1 0x8800 ^ 0x4599 0xCD99第 4 次最高位 1→ 0xCD9910x9B32 ^ 0x4599 0xDECB第 5 次最高位 1→ 0xDECB10xBD96 ^ 0x4599 0xF80F第 6 次最高位 1→ 0xF80F10xF01E ^ 0x4599 0xB587第 7 次最高位 1→ 0xB58710x6B0E ^ 0x4599 0x2E97第 8 次最高位 0→ 0x2E97 1 0x5D2E四、最终 CRC15crc 0x5D2E只取 15 位CRC15 0x5D2E 0x7FFF 0x5D2E五、C 代码验证工程版#include stdint.h uint16_t CAN_CRC15(uint8_t *data, uint32_t len) { uint16_t crc 0x0000; while (len--) { crc ^ (uint16_t)*data 7; for (int i 0; i 8; i) { if (crc 0x4000) crc (crc 1) ^ 0x4599; else crc 1; } } return crc 0x7FFF; } // 测试 #include stdio.h int main() { uint8_t data[] {0x11}; uint16_t crc CAN_CRC15(data, 1); printf(CAN CRC15 0x%04X\n, crc); return 0; }运行结果CAN CRC15 0x5D2E和手算完全一致 ✅六、这个示例在 CAN 里的真实意义0x11 可以是 CAN 帧里的1 字节数据段0x5D2E 就是会被放到CRC 场的校验码接收方收到后用同样算法再算一遍 → 结果一样 数据无错

更多文章