前言
欧姆龙PLC有CRC校验指令AryCRC16,而西门子PLC未找到类似指令,根据CRC计算算法写以下程序
CRC计算算法
Modbus使用的CRC校验采用以下标准算法:
- 初始化16位寄存器(称为CRC寄存器)为0xFFFF。
- 对数据帧中的每个字节(从地址开始到最后一个数据字节)进行以下操作:
将数据字节与CRC寄存器的低8位进行异或操作。
对结果执行8次循环:
如果最低位为1,右移一位后与多项式0xA001异或;
如果最低位为0,只右移一位。
- 最终得到的CRC寄存器内容即为16位CRC校验码。
多项式
Modbus协议使用的生成多项式是 0xA001(即标准的CRC-16反转多项式)。这个多项式的多项式形式为: X^16+X^15+X^2+1
CRC校验码的顺序
计算出的16位CRC校验码以低字节在前(LSB)和高字节在后的顺序附加到数据帧。
程序
新建以下变量
Input
pData Array[0..99] of Byte 输入数据
nLength Int 数据长度
Output
CRC16_Modbus Word
Temp
i Int 数据帧字节计数
j Int 位循环计数
CRC Word CRC寄存器
byteData Byte 当前字节
tempCRC Word 临时CRC值,用于模拟右移
Constant
计算程序
// 初始化CRC寄存器为0xFFFF
CRC := W16FFFF;
// 遍历数据帧的每个字节
FOR i := 0 TO nLength - 1 DO
// 读取当前字节
byteData := pData[i];
// 当前字节与CRC低字节异或
CRC := CRC XOR BYTE_TO_WORD(byteData);
// 循环处理8位
FOR j := 1 TO 8 DO
IF (CRC AND W160001) <> 0 THEN
tempCRC := CRC / 2;//模拟右移操作
CRC := tempCRC XOR W16A001; // 多项式异或
ELSE
CRC := CRC / 2; // 直接右移
END_IF;
END_FOR;
END_FOR;
// 返回最终的CRC校验值
CRC16_Modbus := CRC;