如何做品牌推广网站,网页设计图标素材,做私人没有备案的网站,htm5网站Arduino#xff0c;stm32的crc16校验计算源码#xff0c;支持crc16/modbus#xff0c;自定义等功能。撸代码的兄弟肯定都遇到过数据校验的问题#xff0c;尤其是玩嵌入式开发的时候。今天咱们来聊聊CRC16校验在Arduino和STM32上的花式操作。别被那些复杂的数学公式吓到stm32的crc16校验计算源码支持crc16/modbus自定义等功能。撸代码的兄弟肯定都遇到过数据校验的问题尤其是玩嵌入式开发的时候。今天咱们来聊聊CRC16校验在Arduino和STM32上的花式操作。别被那些复杂的数学公式吓到直接上能跑的真代码。先扔个查表法的实现镇场子const uint16_t crc16_table[] { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, //...完整表太长自己生成或找现成的 }; uint16_t crc16_calculate(uint8_t *data, uint16_t len) { uint16_t crc 0xFFFF; while(len--) { crc (crc 8) ^ crc16_table[(crc ^ *data) 0xFF]; } return crc; }这段代码的精髓在查表加速。注意那个异或操作——初始值0xFFFF是Modbus的特色要是玩别的协议记得改初始值。每次处理一个字节直接查表比硬算快十倍不止。想要支持Modbus协议加点料uint16_t crc16_modbus(uint8_t *data, uint16_t len) { uint16_t crc 0xFFFF; for(uint16_t i0; ilen; i){ crc ^ data[i]; for(int j0; j8; j){ if(crc 0x0001) { crc (crc 1) ^ 0xA001; // 0x8005反转后的多项式 } else { crc 1; } } } return crc; }这里用了逐位计算的方式注意多项式被反转了Modbus标准操作。那个0xA001其实是0x8005按位反转后的结果别傻乎乎直接用标准多项式会翻车。玩STM32的兄弟可以试试硬件CRC外设uint16_t stm32_crc16(uint8_t *data, uint32_t len) { CRC-CR | CRC_CR_RESET; // 复位寄存器 for(uint32_t i0; ilen; i){ *((__IO uint8_t *)CRC-DR) data[i]; // 字节写入 } return (CRC-DR 0xFFFF) ^ 0xFFFF; // Modbus需要异或 }F4系列实测能用但注意硬件CRC的多项式可能和标准不同。这里最后那个异或0xFFFF就是用来适配Modbus的特殊处理不用硬件加速的话可以删掉。自定义参数才是真需求typedef struct { uint16_t poly; uint16_t init; bool refin; bool refout; uint16_t xorout; } CRC16_Config; uint16_t custom_crc16(uint8_t *data, uint16_t len, CRC16_Config cfg) { uint16_t crc cfg.init; while(len--) { uint8_t c *data; if(cfg.refin) c __RBIT(c) 24; // 位反转 crc ^ (c 8); for(int i0; i8; i){ crc (crc 0x8000) ? (crc 1) ^ cfg.poly : (crc 1); } } if(cfg.refout) crc (crc 8) | (crc 8); // 字节反转 return crc ^ cfg.xorout; }这个模板够你玩转各种魔改CRC了。RBIT是STM32的指令级位反转其他平台可以自己实现。注意多项式方向——左移还是右移决定了计算方向。实测数据验证很重要void test() { uint8_t test_data[] {0x01, 0x03, 0x00, 0x00, 0x00, 0x02}; // Modbus CRC16应该返回0xC40B uint16_t crc crc16_modbus(test_data, sizeof(test_data)); Serial.print(CRC16: 0x); Serial.println(crc, HEX); }跑这个测试用例如果串口打印出C40B恭喜你算法写对了。要是出问题先检查字节顺序——Modbus是低位在前高位在后别搞反了。最后提醒查表法在STM32上能起飞但Arduino空间吃紧的话还是用逐位计算。遇到校验失败别慌八成是多项式方向或初始值没设对。收藏这几个代码片段够应付大多数嵌入式项目的校验需求了。