当前位置:文档之家› Modbus通讯协议学习

Modbus通讯协议学习

Modbus通讯协议学习

了解了它,会使你对串口通信有一个清晰的认识!通用消息帧ASCII消息帧(在消息中的每个8Bit 字节都作为两个ASCII字符发送) 十六进制,ASCII字符0...9,A...F 消息中的每个ASCII字符都是一个十六进制字符组成每个字节的位1个起始位n个数据位,最小的有效位先发送1个奇偶校验位,无校验则无1个停止位(有校验时),2个Bit(无校验时)错误检测域LRC(纵向冗长检测) RTU 消息帧8位二进制,十六进制数0...9,A...F 消息中的每个8位域都是一个两个十六进制字符组成每个字节的位1个起始位8个数据位,最小的有效位先发送1个奇偶校验位,无校验则无1个停止位(有校验时),2个Bit(无校验时)错误检测域CRC(循环冗长检测) CRC校验

(/view/1664507.htm) public static string CRCCheck(string val)

{

val = val.TrimEnd(' ');

string[] spva = val.Split(' ');

byte[] bufData = new byte[spva.Length + 2];

bufData = ToBytesCRC(val);

ushort CRC = 0xffff;

ushort POLYNOMIAL = 0xa001;

for (int i = 0; i < bufData.Length - 2; i++)

{

CRC ^= bufData[i];

for (int j = 0; j < 8; j++)

{

if ((CRC & 0x0001) != 0)

{

CRC >>= 1;

CRC ^= POLYNOMIAL;

}

else

{

CRC >>= 1;

}

}

}

return

Maticsoft.DBUtility.HLConvert.ToHex(System.BitConverter .GetBytes(CRC));

}

/// <summary>

/// 例如把如下字符串转换成字节数组

/// AA AA AA AA 0A 00 68 00 06 03 04 54 21 28 22 E5 F3 16 BB BB BB BB 转换为字节数组

/// </summary>

/// <param name="hex">十六进制字符串

</param>

/// <returns></returns>

public static byte[] ToBytesCRC(string hex)

{

string[] temp = hex.Split(' ');

byte[] b = new byte[temp.Length + 2];

for (int i = 0; i < temp.Length; i++)

{

b[i] = Convert.ToByte(temp[i], 16);

}

return b;

}

/// <summary>

/// 将字节数据转换为十六进制字符串,中间用“ ”分割如:AA AA AA AA 0A 00 68 00 06 03 04 54 21 28 22

E5 F3 16 BB BB BB BB

/// </summary>

/// <param name="vars">要转换的字节数组</param>

/// <returns></returns>

public static String ToHex(byte[] vars)

{

return

BitConverter.ToString(vars).Replace('-', ' ').Trim();

}

CS校验(累加和)

public static string CSCheck(string str)

{

if (str.Length == 0) return "";

else str = str.Trim();

byte[] sss = ToBytes(str);

int n = 0;

for (int i = 0; i < sss.Length; i++)

{

n += sss[i];

}

return ToHex(n);

}

/// <summary>

/// AB CD 12 3B 转换为字节数组

/// </summary>

/// <param name="hex">十六进制字符串

</param>

/// <returns></returns>

public static byte[] ToBytes(string hex)

{

string[] temp = hex.Split(' ');

byte[] b = new byte[temp.Length];

for (int i = 0; i < temp.Length; i++)

{

if (temp[i].Length > 0)

b[i] = Convert.ToByte(temp[i], 16);

}

return b;

}

/// <summary>

/// 转换为符合本程序的十六进制格式

/// </summary>

/// <param name="var">1 2 3 等。

</param>

/// <returns>返回十六进制字符串,如果是1-9的话,前面带零</returns>

/// <example>例如: 5 ="05" 12 ="0C" 无论何时,都是两位数。</example>

public static string ToHex(int var)

{

int cs = var;

string tmp = "";

if (cs == 0) { tmp = "00"; }

while (cs > 0)

{

int ys;

cs = Math.DivRem(cs, 256, out ys);

tmp = tmp.Insert(0, string.Format(" {0}", Right("00" + Convert.ToString(ys, 16), 2).ToUpper()));

}

return tmp.Trim();

}

public static string Right(string str, int Length)

{

if ((Length <= 0) || (str == null))

{

return "";

}

int length = str.Length;

if (Length >= length)

{

return str;

}

return str.Substring(length - Length, Length);

}

LRC校验(LRC错误校验用于ASCII模式)

/// <summary>

/// 取模FF(255)

/// 取反+1

/// </summary>

/// <param

name="writeUncheck"></param>

/// <returns></returns>

public static string LRCheck(string writeUncheck)

{

char[] hexArray = new

char[writeUncheck.Length];

hexArray = writeUncheck.ToCharArray();

int decNum = 0, decNumMSB = 0, decNumLSB = 0;

int decByte, decByteTotal = 0;

bool msb = true;

for (int t = 0; t <=

hexArray.GetUpperBound(0); t++)

{

if ((hexArray[t] >= 48) && (hexArray[t] <= 57))

decNum = (hexArray[t] - 48);

else if ((hexArray[t] >= 65) &

(hexArray[t] <= 70))

decNum = 10 + (hexArray[t] - 65);

if (msb)

{

decNumMSB = decNum * 16;

msb = false;

}

else

{

decNumLSB = decNum;

msb = true;

}

if (msb)

{

decByte = decNumMSB + decNumLSB;

decByteTotal += decByte;

}

}

decByteTotal = (255 - decByteTotal) + 1;

decByteTotal = decByteTotal & 255;

int a, b = 0;

string hexByte = "", hexTotal = "";

double i;

for (i = 0; decByteTotal > 0; i++)

{

b =

Convert.ToInt32(System.Math.Pow(16.0, i));

a = decByteTotal % 16;

decByteTotal /= 16;

if (a <= 9)

hexByte = a.ToString();

else

{

switch (a)

{

case 10:

hexByte = "A";

break;

case 11:

hexByte = "B";

break;

case 12:

hexByte = "C";

break;

case 13:

hexByte = "D";

break;

case 14:

hexByte = "E";

break;

case 15:

hexByte = "F";

break;

}

}

hexTotal = String.Concat(hexByte, hexTotal);

}

return hexTotal;

}

public void LRCheck(byte[] code)

{

int sum = 0;

foreach (byte b in code)

{

sum += b;

}

sum = sum % 255;//取模FF(255)

sum = ~sum + 1;//取反+1

string lrc = Convert.ToString(sum, 16);

return lrc;

}

相关主题