▎西门子博途 LGF 库详解 · 10:CRC 校验(下)——CRC16/CRC32 及奇偶校验
接上一篇 CRC8,这篇把 CRC16 和 CRC32 讲完,外加两个奇偶校验工具。上一篇讲清楚了标准版和高级版的区别——两个都支持自定义多项式,高级版多了 finalXorValue 和 reflect 参数。
一、5 个块一览
| 块名 | 类型 | 版本 | 功能 | 典型应用 |
|------|------|------|------|---------|
| LGF_CalcCRC16 | FC | V3.1.0 | CRC16 标准版 | 通用 16 位 CRC |
| LGF_CalcCRC16Advanced | FC | V3.1.0 | CRC16 高级版(含反射和最终异或) | Modbus RTU |
| LGF_CalcCRC32 | FC | V3.1.0 | CRC32 标准版 | 通用 32 位 CRC |
| LGF_CalcCRC32Advanced | FC | V3.1.0 | CRC32 高级版 | Ethernet FCS |
| LGF_IsParityEven | FC | V3.0.1 | DWord 中 1 的个数是否为偶数 | 串口通信奇偶校验 |
| LGF_IsParityOdd | FC | V3.0.1 | DWord 中 1 的个数是否为奇数 | 同上 |
二、引脚详解
#### LGF_CalcCRC16
接口与上一篇的 CalcCRC8 完全一致,仅数据类型从 Byte 升级到 Word。
| 引脚 | 类型 | 方向 | 说明 |
| initValue | Word | IN | CRC 初始值 |
| mask | Word | IN | 生成多项式 |
| noOfElements | UInt | IN | 要计算的元素数量(0=全部) |
| array | Array of Byte | INOUT | 待计算的字节数组 |
| Ret_Val | Word | OUT | CRC16 值 |
| error | Bool | OUT | 错误标志 |
| status | Word | OUT | 状态码 |
#### LGF_CalcCRC16Advanced
| 引脚 | 类型 | 方向 | 说明 |
| initValue | Word | IN | 初始值 |
| mask | Word | IN | 生成多项式 |
| finalXorValue | Word | IN | 最终异或值 |
| reflectInput | Bool | IN | 输入字节按位反射 |
| reflectResult | Bool | IN | 输出结果按位反射 |
| noOfElements | UInt | IN | 元素数量 |
| array | Array of Byte | INOUT | 数据数组 |
| Ret_Val | Word | OUT | CRC16 值 |
| error | Bool | OUT | 错误标志 |
| status | Word | OUT | 状态码 |
#### LGF_CalcCRC32 / CRC32Advanced
接口与 CRC16 版本一致,仅数据类型升级为 DWord。
#### LGF_IsParityEven / IsParityOdd
| 引脚 | 类型 | 方向 | 说明 |
| doubleWord | DWord | IN | 要判断奇偶性的 DWord 值 |
| Ret_Val | Bool | OUT | Even: TRUE=1的个数为偶数;Odd: TRUE=1的个数为奇数 |
三、实战案例
#### 案例 1:Modbus RTU 报文校验
Modbus RTU 使用 CRC16,完整参数:多项式 0x8005,初始值 0xFFFF,最终异或 0x0000,输入和输出都做位反射。
Modbus RTU CRC16
LGF_CalcCRC16Advanced(initValue := 16#FFFF, mask := 16#8005,
finalXorValue := 16#0000, reflectInput := TRUE, reflectResult := TRUE,
noOfElements := msgLength, array := message, Ret_Val => modbusCRC);
算出来的 CRC 值追加在报文末尾,Modbus 从站收到后会用同样的方法验证——一致则报文有效。
#### 案例 2:Ethernet 帧的 CRC32(FCS)
Ethernet 使用 CRC32,多项式 0x04C11DB7,初始值 0xFFFFFFFF,输出反射:
Ethernet FCS CRC32
LGF_CalcCRC32Advanced(initValue := 16#FFFFFFFF, mask := 16#04C11DB7,
finalXorValue := 16#FFFFFFFF, reflectInput := TRUE, reflectResult := TRUE,
noOfElements := 0, array := ethernetFrame, Ret_Val => fcs);
#### 案例 3:串口通信的奇偶校验
在发送前计算数据字的奇偶性,接收后验证:
奇偶校验
IF LGF_IsParityEven(dataWord) <> expectedParity THEN commError := TRUE; END_IF;
四、常见协议 CRC 参数速查
工业协议 CRC 参数一览
| 协议 | CRC 类型 | 多项式 | 初始值 | 最终异或 | 输入反射 | 输出反射 |
|------|---------|--------|--------|---------|---------|---------|
| Modbus RTU | CRC16 | 0x8005 | 0xFFFF | 0x0000 | TRUE | TRUE |
| Dallas 1-Wire | CRC8 | 0x31 | 0x00 | — | — | — |
| SMBus | CRC8 | 0x07 | 0x00 | — | — | — |
| Ethernet FCS | CRC32 | 0x04C11DB7 | 0xFFFFFFFF | 0xFFFFFFFF | TRUE | TRUE |
CRC16 最后两个字节的写入顺序
Modbus 协议规定 CRC 值以小端序(Little-Endian)追加在报文末尾——即先写 CRC 低字节,再写高字节。不要把 CalcCRC16Advanced 算出的 Word 直接 COPY 进报文,要手动交换两个字节的顺序,或者用 LGF_SwapBlockWord(第 13 篇会讲)转换。
五、总结与下载
SIOS-ID 109479728 | V5.1.1 | 中文站:www.ad.siemens.com.cn/download/documentdetail_12471.html | 全球站另有 V5.2.1
下篇预告:LGF 库详解 · 11——FIFO 队列、移位寄存器、数据文件与排序。从先进先出数据缓冲到 ShellSort 数组排序,再到 FileRead/FileWrite——8 个块覆盖数据管理的方方面面。
欢迎点赞、在看、转发。