西门子初步了解
西门子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_area
和write_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("写入失败"));
}
}
其他程序
参考博客: