2026/1/19 6:53:09
网站建设
项目流程
如何让单位网站做防护,题库网站开发,淘客手机网站源码,桂林北站到象鼻山多远要在 C# 中实现与小华 HC32L130 MCU 匹配的 CRC16 校验#xff0c;需先明确HC32L130 的 CRC16 参数规则#xff0c;再基于该规则编写 C# 代码。一、HC32L130 的 CRC16 参数解析从你提供的文档和 MCU 代码可提取核心参数#xff1a;参数项具体值 / 规则多项式\(x^{16}x^{12}x…要在 C# 中实现与小华 HC32L130 MCU 匹配的 CRC16 校验需先明确HC32L130 的 CRC16 参数规则再基于该规则编写 C# 代码。一、HC32L130 的 CRC16 参数解析从你提供的文档和 MCU 代码可提取核心参数参数项具体值 / 规则多项式\(x^{16}x^{12}x^51\) → 十六进制0x1021初始值0xFFFF对应代码中M0P_CRC-RESULT 0xFFFF输入数据处理8 位字节无反射按字节的bit7→bit0顺序处理输出结果处理无反射、无最终异或代码直接返回RESULT寄存器值对应标准 CRC 类型CRC-16/CCITT-FALSE与该标准参数完全一致二、C# 实现 HC32L130 的 CRC16 算法基于上述参数C# 代码需模拟 HC32L130 硬件的 CRC 运算逻辑逐字节处理、左移 多项式异或csharp运行using System; public static class Hc32L130Crc16 { /// summary /// 计算与HC32L130匹配的CRC168位字节输入 /// /summary /// param namedata待计算的字节数组/param /// returnsCRC16校验值16位无符号整数/returns public static ushort Calculate(byte[] data) { // 1. 初始化CRC寄存器与MCU一致0xFFFF ushort crc 0xFFFF; // 2. CRC多项式与文档一致0x1021 const ushort polynomial 0x1021; // 3. 逐字节处理输入数据 foreach (byte b in data) { // 将当前字节扩展为16位左移8位与CRC寄存器异或模拟MCU写入8位DATA的硬件逻辑 crc ^ (ushort)(b 8); // 4. 对当前字节处理8位逐位左移多项式异或 for (int i 0; i 8; i) { // 若CRC最高位bit15为1左移后异或多项式否则仅左移 crc (crc 0x8000) ! 0 ? (ushort)((crc 1) ^ polynomial) : (ushort)(crc 1); } } // 5. 直接返回结果无最终异或与MCU代码一致 return crc; } }三、代码验证确保与 MCU 结果一致可通过标准测试数据验证 C# 代码与 HC32L130 的一致性测试数据ASCII 字符串123456789字节数组0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39CRC16/CCITT-FALSE 标准结果0x29B1C# 测试代码csharp运行byte[] testData System.Text.Encoding.ASCII.GetBytes(123456789); ushort crcResult Hc32L130Crc16.Calculate(testData); Console.WriteLine($CRC16结果0x{crcResult:X4}); // 输出应为 0x29B1若 MCU 中调用CRC16_Get8计算该数据结果也会是0x29B1说明代码匹配。四、与 C# 串口通信结合使用在之前的串口收发代码中可直接调用该 CRC 工具类实现 “数据 CRC” 的收发校验示例串口发送时附加 CRCcsharp运行// 待发送的原始数据 string originalData Hello HC32L130; byte[] dataBytes System.Text.Encoding.UTF8.GetBytes(originalData); // 计算CRC16 ushort crc Hc32L130Crc16.Calculate(dataBytes); // 将CRC转换为2字节注意字节序与MCU一致通常是高位在前/低位在前需和硬件约定 byte[] crcBytes BitConverter.GetBytes(crc); if (BitConverter.IsLittleEndian) { Array.Reverse(crcBytes); // 若系统是小端转为大端匹配MCU的字节序 } // 拼接“数据CRC” byte[] sendBytes new byte[dataBytes.Length crcBytes.Length]; Buffer.BlockCopy(dataBytes, 0, sendBytes, 0, dataBytes.Length); Buffer.BlockCopy(crcBytes, 0, sendBytes, dataBytes.Length, crcBytes.Length); // 串口发送参考之前的串口代码 serialPort.Write(sendBytes, 0, sendBytes.Length);示例串口接收时验证 CRC// 假设接收的字节数组是recvBytes包含“数据2字节CRC” byte[] dataPart new byte[recvBytes.Length - 2]; Buffer.BlockCopy(recvBytes, 0, dataPart, 0, dataPart.Length); // 提取接收到的CRC byte[] recvCrcBytes new byte[2]; Buffer.BlockCopy(recvBytes, dataPart.Length, recvCrcBytes, 0, 2); if (BitConverter.IsLittleEndian) { Array.Reverse(recvCrcBytes); // 转为系统端序 } ushort recvCrc BitConverter.ToUInt16(recvCrcBytes, 0); // 计算数据部分的CRC并验证 ushort calcCrc Hc32L130Crc16.Calculate(dataPart); if (calcCrc recvCrc) { Console.WriteLine(CRC验证通过数据完整); } else { Console.WriteLine(CRC验证失败数据可能损坏); }五、注意事项字节序一致性CRC 结果的字节序高位在前 / 低位在前需与 MCU 约定一致否则会出现校验失败。编码一致性串口收发的字符串编码如 UTF8/GBK需与 MCU 侧保持一致避免数据字节错误。数据完整性若串口接收的是长数据需先拼接完整报文再提取 “数据 CRC” 进行校验。