利用C#和Snap7工具模拟S7通讯(包含DB地址讲解)
之前写过一篇用KepServerEx做模拟S7的通讯数据,参考链接:通过C#和KepServer完成模拟S7协议通讯_c# 与kepserver-CSDN博客
但KepServerEx是收费的,而且模拟的DB块凌驾64就不行了,当然Snap7在本文中也是只能模拟DB1、DB2和DB3的数据,但Snap7提供了C#版的运行程序,完全可以根据需要修改源码完成要模拟的DB块(由于有一个项目需要,我已经实验过修改源码成功模拟DB100、DB101、DB102和DB103的数据,背面有空再把代码分享出来)
本文中Snap7工具下载链接:https://download.csdn.net/download/zxy13826134783/89451661
如果失效了也可以从官网下载:Snap7 Homepage
https://img-blog.csdnimg.cn/direct/60a9462cd0f4410c94399604a4abc75c.png
下载1.4.1版本
https://img-blog.csdnimg.cn/direct/ba3710bb9e044766b7aa39d123af4907.png
里面有许多东西,本文只用到clientdemo.exe和serverdemo.exe,通过搜索文件夹就能找到
https://img-blog.csdnimg.cn/direct/0a0a169e46e94d1685fa2172fdcf345f.png
准备工作完毕,正式开始本文的内容,步骤如下:
1 打开serverdemo.exe程序,然后点击start,如下图:
https://img-blog.csdnimg.cn/direct/7556e34edea74169b05d441afa43e586.png
可以看到下面输出"Server started"的字样,表示启动成功了,但我在假造机中点击Start会报没有权限的错误,防火墙也关了,具体原因不明,如下图:
https://img-blog.csdnimg.cn/direct/475af735afdf4432a526e179cebb717e.png
先来熟悉一下serverdemo.exe中的DB块,可以看到可以模拟DB1、DB2和DB3的数据
https://img-blog.csdnimg.cn/direct/ba0d7203dc934efb93195a6c28e9a608.png
上图中第1个赤色方框的十六进制地址为0000,第2个赤色方框十六进制的地址为000F,第3个赤色方框十六进制的地址为0012,地址排布信赖你能看得懂
2 接着打开客户端工具clientdemo.exe,验证serverdemo.exe是不是好使,输入本机ip: 127.0.0.1,然后点击Connect按钮,如下图:
https://img-blog.csdnimg.cn/direct/d0c1ac7968bf4208aa64d6375423f0e8.png
接着往erverdemo.exe端的DB1中的地址0000写入4,在clientdemo中的具体操作如下:
https://img-blog.csdnimg.cn/direct/5c56f19646b84f7e82a120fcfb7ef9b7.png
3 打开visual studio
3.1 新建名为S7Demo的控制台项目,.net framework选择4.8
3.2 通过nuget安装S7netplus,版本选择最新,如下图:
https://img-blog.csdnimg.cn/direct/9a8e1e757ecc4f48bd33b291c4fe3f95.png
3.3 新增测试代码如下:
class Program
{
static void Main(string[] args)
{
Plc plc = new Plc(CpuType.S7400, "127.0.0.1", 0, 0);
plc.Open();
if (plc.IsConnected)
{
Console.WriteLine("连接成功");
byte b = 22;
plc.Write("DB1.DBB0", b);
Console.WriteLine("修改后的值为:" + plc.Read("DB1.DBB0"));
}
else
{
Console.WriteLine("连接失败");
}
Console.ReadLine();
}
} 代码中的地址"DB1.DBB0"代表的含有如下:
表明:
DB1:表示编号为1的数据块
DBB:是“Data Block Byte”的缩写,表示数据块中的字节
0:是字节的偏移地址。在数据块中,每个字节都有一个唯一的偏移地址,从0开始
注意:1个字节等于8个bit(位)
对应到的地址是DB1地址块的十六进制地址0000,erverdemo工具是这个位置:
https://img-blog.csdnimg.cn/direct/def5afb26c53470f8cb8423a7d12b3a6.png
运行C#程序,运行结果如下:
https://img-blog.csdnimg.cn/direct/e0c6bf8bb97744e9b4ae054a867876de.png
https://img-blog.csdnimg.cn/direct/ca5c88f077774c54802aa2be53cfb7b4.png
erverdemo工具的16是十六进制的,对应到的10机制数是22
当然咯,换成如下的代码,结果也是一样的
class Program
{
static void Main(string[] args)
{
Plc plc = new Plc(CpuType.S7400, "127.0.0.1", 0, 0);
plc.Open();
if (plc.IsConnected)
{
Console.WriteLine("连接成功");
byte b = 22;
//plc.Write("DB1.DBB0", b);
//Console.WriteLine("修改后的值为:" + plc.Read("DB1.DBB0"));
plc.WriteBytes(DataType.DataBlock, 1, 0, new byte[] { b });
}
else
{
Console.WriteLine("连接失败");
}
Console.ReadLine();
}
}
4 把前面的变量b的范例从bool 修改为int,再来观察一下结果,先把serverdemo中的数据还原为0,代码如下:
static void Main(string[] args)
{
Plc plc = new Plc(CpuType.S7400, "127.0.0.1", 0, 0);
plc.Open();
if (plc.IsConnected)
{
Console.WriteLine("连接成功");
int b = 22;
plc.Write("DB1.DBB0", b);
Console.WriteLine("修改后的值为:" + plc.Read("DB1.DBB0"));
}
else
{
Console.WriteLine("连接失败");
}
Console.ReadLine();
}运行结果如下:
https://img-blog.csdnimg.cn/direct/a886327d5d53417584cb1a8976db9c68.png
https://img-blog.csdnimg.cn/direct/669fdd7ff6f84059b0b44052ff17ea1e.png
从上图中可以看出,十进制值22已经写到DB1块中的地址0003了,为什么呢?因为C#中的int范例的数据是占4个字节的,S7netplus库会自动识别对应的数据范例,然后进行写入。
5 往地址DB1.DBX1.1写入数据
DB1.DBX1.1地址表明:
DB1 是数据块的编号
DBX 表示数据块中的位(Data Block Bit),第一个1 是字节的偏移地址,而第二个 1 是该字节中的位偏移,即为地址DB1.DBB1的第二位(由于1个字节有8位)
(大白话表明为操作DB1数据块的第2个字节中的第2位)
C#代码如下:
class Program
{
static void Main(string[] args)
{
Plc plc = new Plc(CpuType.S7400, "127.0.0.1", 0, 0);
plc.Open();
if (plc.IsConnected)
{
Console.WriteLine("连接成功");
bool b =true;
plc.Write("DB1.DBX1.1", b);
Console.WriteLine("修改后的值为:" + plc.Read("DB1.DBX1.1"));
}
else
{
Console.WriteLine("连接失败");
}
Console.ReadLine();
}
} 程序运行结果如下:
https://img-blog.csdnimg.cn/direct/65550fee35ab42479688ab2a7900f930.png
https://img-blog.csdnimg.cn/direct/7a3b068ec1264eccba78331fe55d5370.png
图中的十六进制02转换为二进制为00000010,刚好是DB1数据块的第2个字节中的第2位为1。
由于是对二进制的位进行操作,修改的值只能是true大概false值,如果把上面的b变量的bool范例修改为int范例则代码会报错
好了,本文的内容到此结束。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]