时间:2021-07-01 10:21:17 帮助过:22人阅读
---------------------------------
Modbus协议,常规485通讯的信息发送形式如下:
地址 功能码 数据信息 校验码
1byte 1byte nbyte 2byte
CRC校验是前面几段数据内容的校验值,为一个16位数据,发送时,低8位在前,高8为最后。
例如:信息字段代码为: 1011001,校验字段为:1010。
发送方:发出的传输字段为: 1 0 1 1 0 0 1 1 0 10
参考文档:
https://www.jianshu.com/p/676744381473
https://www.jianshu.com/p/c0d93c2e89ce
VB对应的算法
Public Function CRC16(Data() As Byte, ByRef bLow As Byte, ByRef bHigh As Byte) As String Dim CRC16Lo As Byte, CRC16Hi As Byte ‘CRC寄存器 Dim CL As Byte, ch As Byte ‘多项式码&HA001 Dim SaveHi As Byte, SaveLo As Byte Dim i As Integer Dim flag As Integer CRC16Lo = &HFF CRC16Hi = &HFF CL = 1 ch = &HA0 For i = LBound(Data) To UBound(Data) - 2 CRC16Lo = CRC16Lo Xor Data(i) ‘每一个数据与CRC寄存器的低8位进行异或 ‘右移8次 For flag = 0 To 7 ‘记录一下,用来判断移出位是0还是1 SaveHi = CRC16Hi SaveLo = CRC16Lo CRC16Hi = CRC16Hi \ 2 ‘高位右移一位 CRC16Lo = CRC16Lo \ 2 ‘低位右移一位 If ((SaveHi And &H1) = &H1) Then ‘如果高位字节最后一位为1 CRC16Lo = CRC16Lo Or &H80 ‘则低位字节右移后前面补1 End If ‘否则自动补0 If ((SaveLo And &H1) = &H1) Then ‘如果移出位为1,则与多项式码进行异或 CRC16Hi = CRC16Hi Xor ch CRC16Lo = CRC16Lo Xor CL End If Next flag Next i Dim ReturnData(1) As Byte ReturnData(0) = CRC16Hi ‘CRC高位 ReturnData(1) = CRC16Lo ‘CRC低位 Dim Value As Double Value = CLng(CRC16Hi * 256) + CRC16Lo CRC16 = ReturnData bHigh = CRC16Hi bLow = CRC16Lo End Function
C# 对应的算法
public static byte[] CRC16(byte[] data) { int len = data.Length; if (len > 0) { ushort crc = 0xFFFF; for (int i = 0; i < len; i++) { crc = (ushort)(crc ^ (data[i])); for (int j = 0; j < 8; j++) { crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1); } System.Diagnostics.Debug.WriteLine("i=" + i.ToString() + ","+ crc.ToString()); } byte hi = (byte)((crc & 0xFF00) >> 8); //高位置 byte lo = (byte)(crc & 0x00FF); //低位置 return new byte[] { hi, lo }; } return new byte[] { 0, 0 }; }
Modbus协议 CRC 校验码
标签:div 信息 com crc校验 传输 and data modbus 数据信息