Modbus:中国工业界里的“接地气”明星
大家好!欢迎来到这次的专栏。今天,我们来聊聊那个在中国的工业自动化界里如同周杰伦一样无处不在的明星——没错,就是 Modbus!
1、前言:Modbus在中国有多火?
如果 Modbus 是一名明星,那它在中国的知名度绝对能与成龙或者李连杰媲美。不信?去问问任何一名工控工程师,他们对 Modbus 的了解就像大家熟知的《不能说的秘密》旋律一样。
2、“接地气”的起源
Modbus 早在 1979 年就诞生了,由 Modicon 公司设计。这比“小龙女”刘亦菲都要年长,但它的魅力依旧不减。特别是在中国的制造业和工业控制系统中,Modbus 如同茶一样,渗透在各个角落。
3、地址规则和约定
-
数据模型
Modbus协议定义了四种不同类型的数据表,每种都有自己的地址空间:离散量输入(Discrete Inputs):只读,用于感知开关状态等,通常表示为0xxxx。
线圈(Coils):可读写,用来控制执行器等,通常表示为1xxxx。
输入寄存器(Input Registers):只读,通常用于将模拟信号(如温度读数)数字化后读取,通常表示为3xxxx。
保持寄存器(Holding Registers):可读写,用来读取或设置参数值等,通常表示为4xxxx。 -
地址编号
Modbus地址从0开始编号,但是在许多情况下,人们在谈论这些地址时会加1。因此,如果某个设备文档中提到的是地址40001,它实际上指的是Modbus地址空间中的第一个保持寄存器,它的实际地址是40000。
在Modbus RTU和ASCII模式下,每个设备都会有一个1到247的唯一设备地址(或ID)。地址0是广播地址,发送到这个地址的消息将被网络上所有设备接收,但不会有响应。
Modbus TCP使用IP地址进行设备定位,不依赖于Modbus设备地址,但是在Modbus TCP协议数据单元(PDU)中仍然保留了设备地址字段。 -
功能码
功能码指示了要执行的操作,如读取线圈或寄存器的值,或是写入线圈或寄存器的值。每个功能码都有其唯一的操作和响应结构。 -
地址映射
在实际的应用程序中,Modbus地址通常需要映射到设备的物理或逻辑地址。这种映射是由设备制造商定义的,应在设备的用户手册中清楚地描述。 -
寻址范围
线圈和离散输入的地址范围通常是0-9999。
寄存器的地址范围通常是0-9999,有时可以更高,这取决于设备的寻址能力。 -
例外响应
如果请求中包含无效的地址,设备通常会返回一个异常响应,该响应将包含一个特定的异常代码,表明发生了地址错误。 -
地址使用约定
在实际应用中,通常会遵循某些约定,如使用连续的地址来提高数据处理效率,或避免使用某些可能导致通讯问题的地址。
4、语言风格:普通话和方言?
Modbus 的通信模型很像中国的方言和普通话。有一种“主设备”(就像普通话,全国通用)和多种“从设备”(就像各种方言)。主设备发出指令(就好像说,“来,给大爷唱一首歌!”),从设备就会回应(“好的大爷,这首 ‘月亮代表我的心’ 怎么样?”)。
5、服装风格:旗袍还是牛仔裤?
- Modbus RTU:这就像旗袍,经典而高效。
- Modbus ASCII:这更像是西装革履,正式但稍显繁琐。
- Modbus TCP/IP:这就是Modbus的“潮人”形象,走在时代前沿。
6、示例代码:Modbus版“吃鸡”攻略?
如果 Modbus 是一名游戏玩家,它一定会喜欢下面这样的“吃鸡”攻略代码:
csharpCopy code// C# 版
ModbusClient modbusClient = new ModbusClient("我是Modbus,准备好了吗?", 502);
modbusClient.Connect();
int[] readHoldingRegisters = modbusClient.ReadHoldingRegisters(0, 10);
modbusClient.Disconnect();
cCopy code// C/C++ 版
modbus_t *ctx = modbus_new_tcp("我是Modbus,干就完了", 502);
uint16_t tab_reg[32];
modbus_connect(ctx);
modbus_read_registers(ctx, 0, 10, tab_reg);
modbus_close(ctx);
modbus_free(ctx);