转自:http://www.cnblogs.com/luomingui/archive/2013/06/14/Modbus.html

什么是Modbus?

Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。Modbus 协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。

Modbus 是一个请求/应答协议

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校验 (http://baike.baidu.com/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;
}

自定义Modbus数据表

自定义Modbus数据表例子:

设备相关读取信息:

命令报文信息解析:

自定义Modbus数据表定义注意

串口调试工具

串口调试工具的使用.

串口调试工具 + RS485  就可以读取硬件上的数据,和向硬件请求了,如何使用请看“调试篇”会有详细的说明。

 

网络调试助手:

调试助手主要还是TCP协议通讯的一个调试工具

Modbus通讯协议学习 - 认识篇的更多相关文章

  1. Modbus通讯协议学习 - 串口调试

    概述 我们在做任何事情之前都需要获取很多 调试步骤: 1:485转换器连接硬件 2:485转换器上的USB接口连接电脑. 3:打开设备管理器 ->查看端口 4:打开串口调试工具,在串口配置的地方 ...

  2. 串口屏Modbus协议,串口屏的modbus协议资料,串口屏modbus通讯协议开发,串口屏之modbus协议使用技巧

    串口屏Modbus协议,串口屏的modbus协议资料,串口屏modbus通讯协议开发,串口屏之modbus协议使用技巧 本例程中用51单片机作为Modbus从机,从机的设备地址为2,从机有4个寄存器, ...

  3. Modbus通讯协议

    <ignore_js_op> O1CN01P1wxTI1dCdw5nAeMO_!!85243700.jpg (287.43 KB, 下载次数: 0) 下载附件  保存到相册 2019-6- ...

  4. 如何快速掌握plc或工控机与其他设备的modbus通讯协议?包括格式与实际过程 RT,本人从事工控行业多年,对于PLC与触摸屏也算比较熟悉,唯独对这个通讯协议比较难理解,请教高人指导,从什么地方开始下手,或者是说如何正确理解报文格式或正确写入

    Modbus协议是OSI模型的第七层的应用层通讯协议,定义了不同类型设备间交换信息方式,以及信息的格式. Modbus的工作方式是请求/应答,每次通讯都是主站先发送指令,可以是广播,或是向特定从站的单 ...

  5. Modbus通讯协议简介

    Modbus协议简介 Modbus协议最初由Modicon公司开发出来,此协议支持传统的RS-232.RS-422.RS-485和以太网设备,许多工业设备,包括PLC,DCS,智能仪表等都在使用Mod ...

  6. Modbus 通讯协议

    摘要 工业控制已从单机控制走向集中监控.集散控制,如今已进入网络时代,工业控制器连网也为网络管理提供了方便.Modbus就是工业控制器的网络协议中的一种. 关键词 Modbus协议,串行通信,LRC校 ...

  7. Modbus协议学习笔记

    之前也有写过基于 Modbus 通讯协议的控制远程监控程序,但是由于当时时间赶.人手少(软硬件前后台都是在下一人

  8. C#ModBus Tcp的学习及Master的实现

    Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式. 所以这也是我们工控领域软件开发的所必懂的通讯协议,我也是初次学习,先贴上我的学习笔记 一 ...

  9. http协议学习系列

    深入理解HTTP协议(转)  http://www.blogjava.net/zjusuyong/articles/304788.html http协议学习系列   1. 基础概念篇 1.1 介绍 H ...

随机推荐

  1. nginx教程2:日志

    主要有两种:access_log(访问日志) 和 error_log(错误日志). access_log 访问日志 access_log 主要记录客户端访问 Nginx 的每一个请求,格式可以自定义. ...

  2. [python学习] 简单爬取图片站点图库中图片

    近期老师让学习Python与维基百科相关的知识,无聊之中用Python简单做了个爬取"游讯网图库"中的图片,由于每次点击下一张感觉很浪费时间又繁琐.主要分享的是怎样爬取HTML的知 ...

  3. 【BZOJ3864】Hero meet devil DP套DP

    [BZOJ3864]Hero meet devil Description There is an old country and the king fell in love with a devil ...

  4. 基于Flume的美团日志收集系统 架构和设计 改进和优化

    3种解决办法 https://tech.meituan.com/mt-log-system-arch.html 基于Flume的美团日志收集系统(一)架构和设计 - https://tech.meit ...

  5. Java异步编程第2篇

    假如如今有一个Buttonbutton,Buttonbutton上有click和doubleclick事件. 两个不同的事件须要进行不同的处理.这时候就须要为对应的事件注冊Listener了.改动后的 ...

  6. Other Linker flags 添加 -Objc导致包冲突

    Other Linker flags 添加 -Objc导致包冲突 先尝试不添加-Objc,不行的话尝试下面的方法. 第三方冲突解决办法: https://www.jianshu.com/p/02846 ...

  7. Java互斥语义的实现

    锁 对象头(Object Header) HotSpot 虚拟机的对象头包括两部分信息:Mark Word(标记字段)和 Klass Pointer(类型指针)   Mark Word 用于存储对象自 ...

  8. Android OpenGL 播放视频学习

    1, 初步接触Open GL: http://www.cnblogs.com/TerryBlog/archive/2010/07/09/1774475.html 使用GLSurfaceView和Ren ...

  9. BZOJ1833 数位DP

    数位DP随便搞搞. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstrin ...

  10. centos6.3 安装python2.7.3

    现在比较流行python2.7版本,centos6.3的默认版本是2.6.6,所以需要安装下2.7版本 1.下载安装python2.7 #wget http://www.python.org/ftp/ ...