关于贝加莱Modbus通讯的总结

关于贝加莱Modbus通讯的总结
1.Modbus通讯格式
上篇文章已将介绍了Modbus通讯协议发送指令和回应的格式,这里再回顾一下。modbus指令由从站地址,功能码,数据起始地址,数据长度和CRC校验和组成,如:

01 02 0000 0003 380B

其中:

01:从站地址

02:功能码,读输入触点

0000:起始地址

0003:数据长度

380B:CRC校验和

这条指令的作用就是读取从站01的输入触点寄存器0000到0002里面的数据。

2.贝加莱Modbus通讯功能块介绍
打开贝加莱的帮助文档,搜索DRV_mbus,可以找到DRV_mbus库。

在上图中,可看到与Modbus通讯相关的功能块,与主站相关的功能块有4个,与从站相关的功能块有3个。
贝加莱作为主站时主要用到以下功能块。

a.MBMOpen()
MBMOpen()功能块打开(激活)主站通讯接口。参数如下

I/O    参数    含义
I    enable    功能块使能
I    pDevice    通讯接口的名称
I    pMode    通讯接口参数设置
I    pConfig    数据块的名称
I    timeout    通讯超时参数
I    ascii    MODBUS模式,(0=RTU/1=ASCII)
O    status    错误代码,0表示无错误
O    ident    提供给MBMaster(),MBMCmd(),MBMClose()用的句柄
b.MBMaster()
I/O    参数    含义
I    enable    功能块使能
I    ident    从MBMOpen()返回的句柄指针
O    status    错误代码,0表示无错误
O    execute    命令是否执行
O    recordnum    当前数据交换的次数
c.MBMCmd()
I/O    参数    含义
I    enable    功能块使能
I    ident    从MBMOpen()返回的句柄指针
I    mfc    Modbus功能码
I    node    从站站点号,0为广播
I    data    数据区域首地址
I    offset    偏移量
I    len    数据长度
O    status    错误代码,0表示无错误
d.MBMClose()
关闭主站通讯接口

I/O    参数    含义
I    enable    功能块使能
I    ident    从MBMOpen()返回的句柄指针
O    status    错误代码,0表示无错误
3.硬件连接
要实现PLC与电脑的Modbus通讯,需要一根USB转485的串口线,如下图

打开贝加莱的帮助文档,搜索cs1030,打开通讯模块cs1030的帮助文档,查看cs1030的引脚定义如下,我采用的是RS485模式,cs1030同时支持RS422模式。

将DATA连接T/R+
DATA/连接T/R-
GND连接VCC

4.贝加莱PLC作为主站的配置过程
a.建立一个通讯变量配置模块(dataobject)
新建工程,添加一个dataobject,在dataobject中添加以下内容。

"EventPV1 ", 01, $01, "LocalPV1 ", 0000, 0005
"EventPV2 ", 02, $01, "LocalPV2 ", 0000, 0003
"EventPV3 ", 03, $01, "LocalPV3 ", 0000, 0005
"EventPV4 ", 04, $01, "LocalPV4 ", 0000, 0005
1
2
3
4
注:
“EventPV1 “, 01, $01, “LocalPV1 “, 0000, 0005这条语句当中,01为功能码,读取线圈继电器的状态,$01为从站站点号,”LocalPV1”表示读取的数据存放地址为LocalPV1,0000为读取的线圈继电器首地址,0005为读取长度。EventPV1是发出指令的使能信号,为1时,主站向从站发出指令。因此,整条语句的含义就是,在通讯过程中,当EventPV1等于1时,主站向从站01发出指令读取继电器线圈0000到0004的状态并存储到LocalPV1当中。此时发出的报文为010100000005FC09,FC09是校验和。
其他几条指令与此含义类似。

b.全局变量定义
在上一步通讯变量配置过程中,用到了EventPV1~EventPV4和LocalPV1~LocalPV4等变量。这几个变量必须定义为全局变量。我曾在此犯过错误,折腾了很长时间。定义如下:

Name    Data Type    Scope
EventPV1    bool    global
EventPV2    bool    global
EventPV3    bool    global
EventPV4    bool    global
LocalPV1    bool[5]    global
LocalPV2    bool[3]    global
LocalPV3    int[5]    global
LocalPV4    int[5]    global
c.通讯功能块配置
新建一个program,改名为master.st,定义变量和功能块如下:

Name    Data Type    Scope
MBMOpen_xx    MBMOpen    local
MBMaster_xx    MBMaster    local
MBMCmd_xx    MBMCmd    local
MBMClose_xx    MBMClose    local
S1    bool    local
S2    bool    local
打开init.st,初始化并配置MBMOpen_xx()功能块

PROGRAM _INIT
    (* Insert code here *)
    S1:=0;
    S2:=1;

    EventPV1 := 1;
    EventPV2 := 1;
    EventPV3 := 1;
    EventPV4 := 1;

    LocalPV1[0] := 0;
    LocalPV1[1] := 0;
    LocalPV1[2] := 0;
    LocalPV1[3] := 0;
    LocalPV1[4] := 0;

    LocalPV2[0] := 0;
    LocalPV2[1] := 0;
    LocalPV2[2] := 0;


    LocalPV3[0] := 0;
    LocalPV3[1] := 0;
    LocalPV3[2] := 0;
    LocalPV3[3] := 0;
    LocalPV3[4] := 0;

    LocalPV4[0] := 0;
    LocalPV4[1] := 0;
    LocalPV4[2] := 0;
    LocalPV4[3] := 0;
    LocalPV4[4] := 0;   

    MBMOpen_xx.enable:=1;
    MBMOpen_xx.pDevice:=ADR('IF6.ST4.IF1');
    MBMOpen_xx.pMode:=ADR('/PHY=RS485 /PA=E /DB=8 /SB=1 /BD=19200');
    MBMOpen_xx.pConfig:=ADR('dataobject');
    MBMOpen_xx.timeout:=2000;
    MBMOpen_xx.ascii:=0;
    MBMOpen_xx();    
END_PROGRAM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
注:

MBMOpen_xx.pDevice:=ADR(‘IF6.ST4.IF1’):IF6.ST4.IF1是通讯模块的接口名称。接口名称可以在Physical View里面查到。我用的通讯模块是cs1030,可以看到名称为:IF6.ST4.IF1

MBMOpen_xx.pMode:=ADR(‘/PHY=RS485 /PA=E /DB=8 /SB=1 /BD=19200’):设置通讯模式为RS485,偶校验,数据位为8为,1个停止位,波特率为19200.
MBMOpen_xx.pConfig:=ADR(‘dataobject’):数据块的名称,即前面定义的dataobject
打开Cyclic.st,配置MBMaster_xx,MBMCmd_xx,MBMClose_xx等功能块。

PROGRAM _CYCLIC
    (* Insert code here *)
    (*EventPV1:=1;
    EventPV2:=1;*)
    EventPV1 := 1;
    EventPV3 := 1;

    IF(S1=0)THEN
        MBMaster_xx.enable:=1;
        MBMaster_xx.ident:=MBMOpen_xx.ident;
        MBMaster_xx();
    ELSE
        MBMCmd_xx.enable:=1;
        MBMCmd_xx.ident:=MBMOpen_xx.ident;
        MBMCmd_xx.mfc:=1;
        MBMCmd_xx.node:=1;
        MBMCmd_xx.data:=ADR(LocalPV1);
        MBMCmd_xx.offset:=0;
        MBMCmd_xx.len:=4;
        MBMCmd_xx();
    END_IF
    IF(S2=0)THEN
        MBMClose_xx.enable:=1;
        MBMClose_xx.ident:=MBMOpen_xx.ident;
        MBMClose_xx();
    END_IF
END_PROGRAM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
5.调试
a.程序编写完成后,即可编译下载到PLC中运行,打开电脑上Modbus Slave软件。


注意工具栏上有connect和disconcert的图标,第一次使用不要直接点击connect的图标连接,因为我们需要先配置模式,我曾经在这里犯过错误,直接按照默认的模式connect,结果死活连接不成功,在这里纠结了好久。这种低级错误实在是不该犯,浪费时间。

b.点击connection->connect进入connection配置界面


选择相应的串口(在设备管理器中查看,此处为port6)

设置波特率为:19200

数据位:8位

校验:偶校验(之前连接不成功的原因就是校验方式选为了NONE)

停止位:1位

mode:RTU

设置完成后,点击OK即可连上。

c.从站定义
点击setup->slave definition进入从站定义界面

salve:输入1,这是从站站点号

Function:选择要操作的寄存器

代码    寄存器
01    coil status
02    input status
03    holding register
04    input register
adddress:首地址

length:长度
在这里我们先将做如下设置

salve:1

Function:03 holding register

Address:1

Length:10

d.通讯检测
在AS中打开watch窗口(CTRL+M).添加变量EventPV1~EventPV4,MBMOpen(),MBMCmd(),MBMClose(),MBMaster(),LocalPV1~LocalPV4,S1,S2.
在Modbus Slave中双击40001打开Edit Register界面

在value中写1,同时勾选Auto increment,点击OK

在AS的watch窗口将EventPV3的值改为1

可以看到localPV3[0]的值随着salve中40001的值在递增,说明通讯正常。

6.利用串口调试助手分析报文。
在调试过程中,如果碰到问题,可以先用串口助手先测试下PLC指令发送是否正常.具体操作如下:

打开串口调试助手,设置模式与程序中的模式相同。


分析一下接收到的报文,01 03 00 00 00 05 85 C9,由前面的说明可以知道:

“EventPV3 “, 03, $01, “LocalPV3 “, 0000, 0005

当EventPV3设置为true的时候,PLC应该向salve读取holding register0000到0004的值并存入LocalPV3当中,因此plc向salve发送的报文应该为010300000005+CRC校验和,前面的部分都能对上,经过计算,CRC校验和也能对上。说明报文发送没有问题。

CRC校验和计算器
————————————————
版权声明:本文为优快云博主「Vincents Blog」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/ww1473345713/article/details/49096891

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值