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个从站进行读写操作,测试读写正常