Modbus本身是一种信息交换的规范,Modbus Ascii则是透过串口来实现Modbus 的一种方式,因此所有的信息都是通过串口来传输;Modbus协议属于 C/S 架构,Modbus Master可以读写AsciiSlave的地址,实现数据交互;
使用场景
设备间数据采集和监控(如PLC与传感器、HMI的连接)。
过程自动化中的数据传输。
远程监控和控制系统。
整体架构


注: 本手册中用到的中科时代的软件包,均可以从官网的子页面获取。官网提供的版本可能比本手册中提到的版本更高,一般情况下这不会影响您按照本手册的例子执行相应的操作
Modbus Ascii是透过串口来实现Modbus的一种方式,因此所有讯息是透过串口来传输的,Modbus Master可以对AsciiSlave发送读或者写的指令,AsciiSlave收到指令后会回复确认信息,整个Modbus的沟通建立在一来一回的讯息交换上;
下表概述了各个产品组件
| 产品组件 | 描述说明 | |
|---|---|---|
| 主站 | modbusmaster_1.1.8_amd64.deb | Modbus tcp Master RTE组件 |
| SF4100_ModbusMaster_1.0.0.3.library | Modbus tcp Master Metafacture 库文件 |
中科时代出厂的工智机;
安装DeviceManager.exe (0.0.2.6)软件
1、工智机端安装Modbus Master RTE组件
运行DeviceManager.exe 软件
安装ACP 服务(以工智机(192.168.1.200)为例),选择“在线安装”;

选择工智机(192.168.1.200),点击“本地”,进入本地安装界面;

进入工智机设备管理器界面,点击"软件”下拉选择“组件管理”,进入“浏览页面”,选择"modbusmaster"查看安装版本并点击“安装”;

传输完成,弹窗选择确定安装;安装完成后,选择确认重启组件;
安装完成后,本地新增"modbusmaster"组件,

2、Metafacture安装library
打开Metafacture,点击“工具” -- “库存储”

点击“安装” -- 选中modbus master的库文件,点击“打开”

工程中点击“库管理器” -- “添加库” -- 选中modbus库点击“确定”

(*注: 工智机端安装ModbusSlave RTE组件以及Library 安装步骤同上)
1、工智机端升级ModbusMaster RTE组件
运行DeviceManager.exe 软件
安装ACP 服务(以工智机(192.168.1.200)为例),选择“在线安装”;

选择工智机(192.168.1.200),点击“本地”,进入本地安装界面;

进入工智机设备管理器界面,点击"软件”下拉选择“组件管理”,进入“本地”,选择"modbusmaster"查看安装版本,选择更新版本并点击“更新”;
传输完成,弹窗选择确定安装;安装完成后,选择确认重启组件;
安装完成后,本地"modbusmaster"为最新版本的组件,
2、Metafacture升级library
打开Metafacture,点击“工具” -- “库存储”

点击“安装” -- 选中新的modbus master的库文件,点击“打开”

工程中点击“库管理器” -- “添加库” -- 选中新的modbus master库点击“确定”

1、工智机端卸载Modbus Master RTE组件
工智机上执行命令卸载modbusmaster
进入工智机设备管理器->“组件管理界面”->"本地”,选择组件"modbusmaster" 点击“卸载”;

确认卸载组件且确定重新加载;

加载完成后,"modbusmaster" 组件被删除;
2、卸载MetaFacture侧的Modbus Master library
MetaFacture界面点击“工具” -- “库存储”

对话框中选中安装的modbus master的库,点击“卸载”

本例软、硬件配置
硬件:
1.SX5100工智机 MetaOS V24.08.15_SX5
2.Win10 PC
软件:
1.MetaFacutre V1.0.7.1
2.Modbus slave从站工具
实验原理

Metafacture Modbus Ascii站通过串口连接向第三方Modbus Ascii从站发送请求,主要包含:功能码、目标寄存器的地址和数量、写操作时的数据;从站收到请求后先检查数据的合法性,然后执行请求的操作,响应主站请求;
上位机和工智机使用EtherNet连接;
上位机上,MetaFacture下装工程到工智机。工程中会包含下面的试验操作步骤中的配置;
工智机与第三方TCPIP客户端通过串口连接;
1. 主站配置
1.1主站初始化串口实验步骤如下
Fb_serialInit : FB_MBAsciiSerialPortInit;
bhandle: UINT;
Shell
Fb_serialInit(Execute:=bTEST,
PortName := '/dev/ttyS6', //串口号
BaudRate := 115200, //串口波特率
DataBits := 8,
StopBits := 1,
Parity := 'N',
Timeout:= ,
BUSY=>,
Error=>,
ErrorId=>
handle=> bhandle);
1.2 读多线圈的实验步骤如下:
bTEST : BOOL ;
Fb_readCoils : FB_MBAsciiReadCoils;
arrReadCoils : ARRAY [1..10] OF BOOL;
Shell
Fb_readCoils(
handle:= bhandle,
Execute:=bTEST,
Quantity:= 10, //读取线圈长度
pMemoryAddr := ADR(arrReadCoils),
cbLength := SIZEOF(arrReadCoils),
MBAddr:=0, //读取线圈的起始位置
Timeout:= ,
UnitID:=1,
BUSY=>,
Error=>,
ErrorId=>);
1.3 读取离散输入的实验步骤如下:
bTEST : BOOL ;
Fb_readInputs : FB_MBAsciiReadInputs;
arrReadInputs : ARRAY [1..10] OF BOOL;
Fb_readInputs(
handle:= bhandle,
Execute:=bTEST,
Quantity:=10, //读取的离散输入长度
pMemoryAddr := ADR(arrReadInputs),
cbLength := SIZEOF(arrReadInputs),
MBAddr:=0, //读取离散输入起始位置
Timeout:= ,
UnitID:=1,
BUSY=>,
Error=>,
ErrorId=>);
1.4 读取保持寄存器的实验步骤如下:
bTEST : BOOL ;
Fb_readRegs : FB_MBAsciiReadRegs;
arrReadRegs : ARRAY [1..10] OF WORD;
Shell
Fb_readRegs(
handle:= bhandle,
Execute:=bTEST,
Quantity:= 10, //读取的保持寄存器长度
pMemoryAddr := ADR(arrReadRegs),
cbLength := SIZEOF(arrReadRegs),
MBAddr:=0, //读取的保持寄存器起始位置
Timeout:= ,
UnitID:=1,
BUSY=>,
Error=>,
ErrorId=>);
1.5 读取输入寄存器的实验步骤如下:
Fb_readInputRegs(
handle:= bhandle,
Execute:=bTEST,
Quantity:= 10, //读取的保持寄存器长度
pMemoryAddr := ADR(arrReadInputRegs),
cbLength := SIZEOF(arrReadInputRegs),
MBAddr:=0, //读取的保持寄存器起始位置
Timeout:= ,
UnitID:=1,
BUSY=>,
Error=>,
ErrorId=>);
| Shell Fb_readInputRegs(handle:= bhandle,Execute:=bTEST, Quantity:= 10, //读取的保持寄存器长度 pMemoryAddr := ADR(arrReadInputRegs), cbLength := SIZEOF(arrReadInputRegs), MBAddr:=0, //读取的保持寄存器起始位置 Timeout:= , UnitID:=1, BUSY=>, Error=>, ErrorId=>); |
|---|
1.6 写多线圈的实验步骤如下:
bTEST : BOOL ;
Fb_writeCoils : FB_MBAsciiWriteCoils;
arrWriteCoils : ARRAY [1..10] OF BOOL;
Fb_writeCoils(
handle:= bhandle,
Execute:=bTEST,
Quantity:= 10, //要写入线圈的长度
pMemoryAddr := ADR(arrWriteCoils),
cbLength := SIZEOF(arrWriteCoils),
MBAddr:=10, //要写入的线圈的起始位置
Timeout:= ,
UnitID:=1, //从站的ID
BUSY=>,
Error=>,
ErrorId=>);
1.7 写多保持寄存器的实验步骤如下:
bTEST : BOOL ;
Fb_writeRegs : FB_MBAsciiWriteRegs;
arrWriteRegs : ARRAY [1..10] OF WORD;
Fb_writeRegs(
handle:= bhandle,
Execute:=bTEST,
Quantity:= 10, //要写入的保持寄存器长度
pMemoryAddr := ADR(arrWriteRegs),
cbLength := SIZEOF(arrWriteRegs),
MBAddr:=10, //要写入的保持寄存器的起始位置
Timeout:= ,
UnitID:=1,
BUSY=>,
Error=>,
ErrorId=>);
1.8 写单线圈的实验步骤如下:
bTEST : BOOL ;
Fb_writeSingleCoil : FB_MBAsciiWriteSingleCoil;
writeSinglecoil : BOOL:=True;
Fb_writeSingleCoil(
handle:= bhandle,
Execute:=bTEST,
Value := writeSinglecoil,
MBAddr:=20, //写入单线圈的位置
Timeout:= ,
UnitID:=1,
Busy=>,
Error=>,
ErrorId=>);
1.9 写单个保持寄存器的实验步骤如下:
Shell
bTEST : BOOL ;
Fb_writeSingleReg : MBAsciiWriteSingleReg;
writeSingleReg : WORD:=20;
Fb_writeSingleReg(
handle:= bhandle,
Execute:=bTEST,
Value := writeSingleReg,
MBAddr:=20, //写入保持寄存器的位置
Timeout:= ,
UnitID:=1,
Busy=>,
Error=>,
ErrorId=>);
1、实验中用到的从站COM口以实际为准;
2、实验中使用的从站案例如下:
Modbus Slave中的从站COM口及串口波特率等配置以实际为准:

线圈配置21位

离散输入配置10位

保持寄存器配置21位

输入寄存器配置10位

1. 功能块FB_MBAsciiSerialPortInit介绍

2. 参数介绍
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| PortName | STRING | 串口号 |
| BaudRate | UINT | 波特率设置,常用的波特率类型如9600、38400、115200均支持 |
| DataBits | UINT | 数据位 |
| StopBits | UINT | 停止位 |
| Parity | STRING | 校验位 |
| Execute | BOOL | 触发执行 |
| Timeout | TIME | 超时 |
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| BUSY | BOOL | 功能块激活时设置,直到确认接收 |
| Error | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
| ErrorId | UINT | 当bError输出被设置,提供错误号 |
| handle | UINT | 句柄 |
1. 功能块FB_MBAsciiReadCoils介绍

2. 参数介绍
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| handle | UINT | 连接句柄 |
| UnitID | UINT | 从站的ID |
| Quantity | UINT | 读取的线圈位数 |
| MBAddr | WORD | 读取的线圈起始位置 |
| cbLength | UINT | 存储读取的字节大小 |
| pMemoryAddr | POINTER TO BYTE | 要读的存放数据的存放地址 |
| Execute | BOOL | 触发读取动作 |
| tTimeout | Time | 超时 |
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| BUSY | BOOL | 功能块激活时设置,直到确认接收 |
| Error | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
| ErrorId | UINT | 当bError输出被设置,提供错误号 |
1. 功能块FB_MBAsciiReadInputRegs介绍

2. 参数介绍
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| handle | UINT | 连接句柄 |
| UnitID | UINT | 从站的ID |
| Quantity | UINT | 读取的输入寄存器位数,一次最多读取125位 |
| MBAddr | UINT | 读取的输入寄存器起始位置 |
| cbLength | UINT | 存储读取的字节大小 |
| pMemoryAddr | POINTER TO BYTE | 要读的存放数据的存放地址 |
| Execute | BOOL | 触发读取动作 |
| tTimeout | Time | 超时 |
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| BUSY | BOOL | 功能块激活时设置,直到确认接收 |
| Error | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
| ErrorId | UINT | 当bError输出被设置,提供错误号 |
1. 功能块FB_MBAsciiReadInputs介绍

2. 参数介绍
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| handle | UINT | 连接句柄 |
| UnitID | UINT | 从站的ID |
| Quantity | UINT | 读取的离散输入位数 |
| MBAddr | UINT | 读取的离散输入起始位置 |
| cbLength | UINT | 存储读取的字节大小 |
| pMemoryAddr | POINTER TO BYTE | 要读的存放数据的存放地址 |
| Execute | BOOL | 触发读取动作 |
| tTimeout | Time | 超时 |
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| BUSY | BOOL | 功能块激活时设置,直到确认接收 |
| Error | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
| ErrorId | UINT | 当bError输出被设置,提供错误号 |

2. 参数介绍
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| handle | UINT | 连接句柄 |
| UnitID | UINT | 从站的ID |
| Quantity | UINT | 读取的保持寄存器位数,一次最多读取125位 |
| MBAddr | UINT | 读取的保持寄存器起始位置 |
| cbLength | UINT | 存储读取的字节大小 |
| pMemoryAddr | POINTER TO BYTE | 要读的存放数据的存放地址 |
| Execute | BOOL | 触发读取动作 |
| tTimeout | Time | 超时 |
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| BUSY | BOOL | 功能块激活时设置,直到确认接收 |
| Error | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
| ErrorId | UINT | 当bError输出被设置,提供错误号 |
1. 功能块FB_MBAsciiWriteCoils介绍

2. 参数介绍
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| handle | UINT | 连接句柄 |
| UnitID | UINT | 从站的ID |
| Quantity | WORD | 要写入的线圈位数 |
| MBAddr | WORD | 要写入的线圈起始位置 |
| cbLength | UINT | 存储写入的字节大小 |
| pMemoryAddr | POINTER TO BYTE | 要写入的数据的地址 |
| Execute | BOOL | 触发写入动作 |
| tTimeout | Time | 超时 |
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| BUSY | BOOL | 功能块激活时设置,直到确认接收 |
| Error | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
| ErrorId | UINT | 当bError输出被设置,提供错误号 |
1. 功能块FB_MBAsciiWriteRegs介绍

2. 参数介绍
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| handle | UINT | 连接句柄 |
| UnitID | UINT | 从站的ID |
| Quantity | UINT | 要写入的保持寄存器位数 |
| MBAddr | UINT | 要写入的保持寄存器的起始位置 |
| pMemoryAddr | POINTER TO WORD | 要写入的数据的地址 |
| Execute | BOOL | 触发写入动作 |
| tTimeout | Time | 超时 |
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| BUSY | BOOL | 功能块激活时设置,直到确认接收 |
| Error | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
| ErrorId | UINT | 当bError输出被设置,提供错误号 |
1. 功能块FB_MBAsciiWriteSingleCoil介绍

2. 参数介绍
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| handle | UINT | 连接句柄 |
| UnitID | UINT | 从站的ID |
| MBAddr | WORD | 要写入的线圈位置 |
| Value | BOOL | 要写入的线圈值 |
| Execute | BOOL | 触发写入动作 |
| tTimeout | Time | 超时 |
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| BUSY | BOOL | 功能块激活时设置,直到确认接收 |
| Error | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
| ErrorId | UINT | 当bError输出被设置,提供错误号 |
1. 功能块FB_MBAsciiWriteSingleReg介绍

2. 参数介绍
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| handle | UINT | 连接句柄 |
| UnitID | UINT | 从站的ID |
| MBAddr | WORD | 要写入的保持寄存器位置 |
| Value | WORD | 要写入的保持寄存器值 |
| Execute | BOOL | 触发写入动作 |
| tTimeout | Time | 超时 |
| 参数名称 | 参数类型 | 描述 |
|---|---|---|
| BUSY | BOOL | 功能块激活时设置,直到确认接收 |
| Error | BOOL | 如果命令在传输过程中出现错误,则设置true直到bBusy输出被重置 |
| ErrorId | UINT | 当bError输出被设置,提供错误号 |
使用模拟软件配置32个Ascii从站(各个从站ID配置不一样),参考如下:

主站工程中配置连接32个从站进行读写操作,测试读写正常