西门子初了解和snap7编程

西门子初步了解

西门子plc 中存储区分类有I、Q、M、SM、T、C、V、S、L、AI、AQ

1、I存储区(输入映像寄存器)

2、Q存储区(输出映像寄存器)

3、M存储区(位存储器)

4、 V存储区(变量存储器)

5、DB数据块

6、L存储区(临时存储区)

数据格式

1、二进制的位(Bit--bool)--->1位(0/1)

2、字节(Byte)---->8位(B)

3、字(Word)---->16位(W)

4、双字(DWord)--->32位(D)

字节存储:IB、QB、VB

字存储:IW、QW、VW、

位存储:ID、QD、VD

PLC读写的思路及部分函数:

PLC的读写主要是通过read_areawrite_area两个函数实现,个人理解的思路就是read_area(读出来)--- 修改 ---write_area(写进去)

cpp 复制代码
ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData);

WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData);

//Area表示内存区。取值0x84:V区  0x83:M区  0x82:O区  0x81:I区  0x1C:C区  0x1D:T区
//DBNumber表示区域号,只有在对DB块使用时才有用,默认设置为0
//start表示起始地址。当函数功能为写bit时,int addr =Start/8; int bit = Start%8;
//此时表示第addr地址的第Bit位。如Start = 8;则表示第1号地址的第0位,即addr.Bit(1.0);
//Amount表示要读或写的数据长度,当函数类型为写bit时,只能为1
//WordLen决定函数的功能,函数功能有写位,字节,字,。取值: 0x1:Bit  0x2:Byte  
// 0x4:Word  0x6:DW  0x8 : Real 0x1c : C区(16Bit)  0x1D:T区(16Bit)
//注意:读Word和DWord功能有问题,高位字节在前,低位字节在后(跟我们的程序反过来)
//*pUsrData表示数据缓冲区,写入PLC的数据存入该缓冲区
cpp 复制代码
MBWrite(int Start, int Size, void *pUsrData)
MBRead(int Start, int Size, void *pUsrData)

//MBWrite和MBRead是ReadArea和WriteArea的精简函数,参数Area = S7AreaMK. WordLen = S7WLBytes.
//Start是整数类型,开始的偏移地址
//Size写入的位大小
//如果需要大量的数据传输,您可以考虑使用异步对应的AsMBWrite函数。
cpp 复制代码
//area用于区分I、Q、M、DB区域,具体选择如下
areas = ADict({
  'PE': 0x81,  #input 输入区
  'PA': 0x82,  #output 输出区
  'MK': 0x83,  #bit memory 中间存储区(M区)
  'DB': 0x84,  #DB区
  'CT': 0x1C,  #counters
  'TM': 0x1D,  #Timers
})


自己用的地址。

cpp 复制代码
typedef unsigned char      uint8_t;
typedef uint8_t    byte;
//unsigned char 一个字节长度,8个位
typedef uint16_t   word;
typedef uint32_t   longword;

西门子数据存储

西门子数存储到二进制时方式是大端模式(BIG-Endian),而我们的普通电脑常常为小端模式(Liitle-Endian)。

大端模式是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中.

小端模式是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。

在PLC中双字0x4c 21112F 存储

PC端相同双字0x4c 21112F 存储

在PLC中字0x113F存储

PC端相同字0x113F存储

西门子通讯

西门子S7系列PLC采用以下两种通讯方式:

开放式的TCP\IP,可以用于连接PLC与其他非西门子硬件

西门子自己开发的S7 Protocol以太网通讯协议,用于西门子内部硬件通讯

Snap7 theatre

Snap7的目的是将您的PC端完全集成到PLC网络中,不产生区别。Snap7 theatre和西门子一样有相同的actors.snap7的库包含三个对象,客户端,服务器和合作伙伴。这三个对象可以在同一应用程序中同时使用。许多相同类型的对象可以同时实例化。许多应用程序可以同时使用Snap7。

客户端只能查询,服务端只能回复,合作伙伴可以主动发言。左边的所有三个组件都是客户端,它们连接到的内部服务器通信处理器(CP),并进行S7请求。服务器用S7应答电报进行应答。服务器端不需要配置。服务器服务由自动处理CP的固件。CP可以是诸如CP343/CP443之类的外部CPU或3XX-PN或4XX-PN CPU中的内部CPU,但是,以同样的方式工作。

合作伙伴可以交换未经请求的数据,双方都可以向另一方发送数据。西门子在其手册中经常将这种通信称为"客户-客户"。请求连接的对等方被命名为Active Partner,该对等方接受的连接被命名为被动伙伴。通过FB12/FB13(S7300)或SFB12/SFB13(S7400)执行通信,它们的符号名称是BSend/BRef(块发送/块接收)。一个重要的注释是:当PLC A调用BSend时,必须在PLC B中调用BRecv同时,完成交易。

对于两个合作伙伴,必须使用NetPro创建S7连接。活动伙伴必须在中选中"建立活动连接"选项连接属性(您可以在Snap7Partner描述中找到更多详细信息)。提供这种通信模型主要是为了将PLC相互连接,然而,Snap7Partner允许您的软件在PLC中充当主动或被动合作伙伴网络。Snap7Client公开了三个有趣的特性:PDU独立性,SmartConnect和异步数据传输。
PDU独立性:所有Snap7功能都完全隐藏了这个概念,你可以单个调用中的传输仅取决于可用数据的大小。
smart connect :SmartConnect功能依赖于这一原理,以避免PLC关闭或网络电缆断开时TCP连接超时。ConnectTo()
异步数据传输:同步函数在调用方的同一线程中执行,即仅退出当它的工作完成时。同步函数通常称为阻塞函数,因为它们会阻止调用程序的执行。相反,异步函数由两部分组成,第一部分在执行中调用方的同一线程准备数据(如果有的话),触发第二个部分并立即退出。

第二个在单独的线程中执行,并且在执行调用程序的同时执行所请求的作业的主体。

案例

1、读取模拟输出的值。
cpp 复制代码
void MainWindow::on_readMK_clicked()
{
    byte l_byData[16];
    float l_fSpeed = {0};
    int tmp = client->ReadArea(S7AreaMK, 0, ui->lineEdit_10->text().toInt(), 4, S7WLReal, &l_byData);

    if(tmp==0)
    {
        QMessageBox::information(this,tr("success"),tr("读取成功"));
        //字节转换
        *((byte*)&l_fSpeed + 0) = l_byData[3];
        *((byte*)&l_fSpeed + 1) = l_byData[2];
        *((byte*)&l_fSpeed + 2) = l_byData[1];
        *((byte*)&l_fSpeed + 3) = l_byData[0];
        ui->lineEdit_12->setText(QString("%1").arg(l_fSpeed));
//        ui->lineEdit_12->setText(QString("%1").arg(l_byData[0]));
        qDebug()<<l_byData[0];
        qDebug()<<l_byData[1];
        qDebug()<<l_byData[2];
        qDebug()<<l_byData[3];

    }
    else
    {
        QMessageBox::critical(this,tr("error"),tr("读取失败"));
    }

}

2、数据写入plc中

cpp 复制代码
void MainWindow::on_writeMB_clicked()
{
    byte l_byData[1] = {0};
    int l_fSpeed = ui->lineEdit_17->text().toInt();;

    l_byData[0] = *((byte*)&l_fSpeed + 0);

    int tmp = client->MBWrite(ui->lineEdit_16->text().toInt(), 1, &l_byData);

    if(tmp==0)
    {
        QMessageBox::information(this,tr("success"),tr("写入成功"));

    }
    else
    {
        QMessageBox::critical(this,tr("error"),tr("写入失败"));
    }
}

其他程序


参考博客:

http://www.dzkfw.com.cn/Article/plc/8142.html

相关推荐
QuantumStack5 分钟前
【C++ 真题】B2037 奇偶数判断
数据结构·c++·算法
结衣结衣.1 小时前
C++ 类和对象的初步介绍
java·开发语言·数据结构·c++·笔记·学习·算法
学习使我变快乐1 小时前
C++:静态成员
开发语言·c++
心怀花木1 小时前
【C++】多态
c++·多态
风清扬_jd1 小时前
Chromium 添加书签功能浅析c++
c++·chrome
吃椰子不吐壳1 小时前
c++类与对象二
c++
zaim13 小时前
计算机的错误计算(一百一十四)
java·c++·python·rust·go·c·多项式
学习使我变快乐3 小时前
C++:const成员
开发语言·c++
一律清风6 小时前
QT-文件创建时间修改器
c++·qt
不知所云,6 小时前
qt cmake自定义资源目录,手动加载资源(图片, qss文件)
开发语言·qt