Modbus协议支持两种传输方式,命令结构:
ASCII模式
: 地址 功能代码 数据数量 数据1
... 数据n LRC高字节 LRC低字节 回车 换行
RTU模式
地址 功能代码 数据数量 数据1 ...
数据n CRC高字节 CRC低字节
ASCII为LRC效验方式,C#代码如下:
public string getLRC(string
str)
{
int
d_lrc = 0;
string h_lrc =
"";
int k
=
str.Length;
for (int i = 0; i < k; i = i +
2)
{
string i_data = str.Substring(i,
2);
d_lrc = d_lrc +
Convert.ToInt32(i_data);
}
if
(d_lrc >=
16)
d_lrc = d_lrc %
16;
h_lrc
= Convert.ToInt32(~d_lrc +
1).ToString("X");
if (h_lrc.Length >
2)
h_lrc = h_lrc.Substring(h_lrc.Length - 2,
2);
return
h_lrc;
}
RTU为CRC效验方式,C#代码如下:
private static void CalculateCRC(byte[] pByte,
int nNumberOfBytes, out byte hi, out byte
lo)
{
ushort
sum;
CalculateCRC(pByte, nNumberOfBytes, out
sum);
lo =
(byte)(sum &
0xFF);
hi
= (byte)((sum & 0xFF00) >>
8);
}
private static void CalculateCRC(byte[] pByte,
int nNumberOfBytes, out ushort
pChecksum)
{
int
nBit;
ushort
nShiftedBit;
pChecksum = 0xFFFF;
for (int nByte = 0; nByte < nNumberOfBytes;
nByte++)
{
pChecksum ^=
pByte[nByte];
for (nBit = 0; nBit < 8;
nBit++)
{
if ((pChecksum & 0x1) ==
1)
{
nShiftedBit =
1;
}
else
{
nShiftedBit =
0;
}
pChecksum >>=
1;
if (nShiftedBit !=
0)
{
pChecksum ^=
0xA001;
}
}
}
}