Siemens S7

按地址通过 S7comm,或按变量名通过 S7CommPlus 连接 Siemens S7 PLC:“访问”字段、机架和槽位、存储区、定型的字节/位寻址、变量名、HMI 设置,以及那些原生数据类型。

以 Markdown 查看

Siemens S7 驱动通过 S7comm 和 Siemens S7 PLC 对话,也就是承载在 ISO-on-TCP 上的那个经典 Step 7 协议。它用的是绝对寻址,即存储区、数据块号、字节和位,所以不需要从工程项目里导出任何符号表就能工作。在 Connector 里的 Siemens S7 驱动下面添加一台设备,把下面这些字段填上;面板只显示这个协议用得到的那些字段。

以上是按地址访问。每台设备选择自己的访问方式:上面说的按地址,或者按名称,走 S7CommPlus,也就是 TIA Portal 和 Siemens HMI 使用的协议;按名称时,每个点位按 TIA Portal 的写法写出它的变量,类型由 CPU 告知。

访问

方面 按地址 按名称
协议 ISO-on-TCP 上的 S7comm,端口 102 ISO-on-TCP 中 TLS 1.3 上的 S7CommPlus,端口 102
CPU S7-300、S7-400、S7-1200、S7-1500 固件 V2.9 或更新的 S7-1500、固件 V4.5 或更新的 S7-1200,并且在 TIA Portal V17 或更新版本中组态
设备的字段 主机、机架 / 槽位 主机、用户名和密码,两者都可不填
点位写的是什么 存储区、DB 号、字节和位,以及它的数据类型 变量的名称,例如 GanterOpt.Real_;类型由 CPU 告知
CPU 这边 允许 PUT/GET,并且数据块不用优化访问(准备 CPU) 什么都不用改:优化的数据块也能读,也不需要 PUT/GET
设备发现 没有 CPU 的变量(设备发现)

现在新建的设备从按名称开始。在有这个选项之前保存的设备,照旧按地址读取。切换访问方式时,点位的定型地址和变量名都会保留,所以切回去时一切都在原处。按名称时,设备标题显示的端点不带机架和槽位,例如 s7://192.168.0.2?access=name。不响应按名称访问的 CPU,会在设备页面上说明这一点(没有按名称访问的 CPU)。

连接

字段 含义 默认值
主机 CPU(或者挡在它前面的那块 CP 模块)的 IP 地址或主机名。 空
访问 按地址或按名称(访问)。 按名称
机架 / 槽位 仅按地址时。CPU 的机架号和槽位号,按 Siemens 硬件组态里配置的填。同一行上两个数字框:先机架,后槽位。 0 / 0
用户名 / 密码 仅按名称时,两者都可不填:密码是 CPU 保护的密码,在它的访问级别要求时填写;用户名只用于管理用户的 CPU。在这台电脑上受保护地保存。 空
轮询间隔(ms) 整台设备的读取周期,供没有自己另作规定的点位使用。 1000

TCP 端口固定为 102(ISO-on-TCP),所以没有端口字段。设备标题栏显示拼好的 endpoint,例如 s7://192.168.0.2:0:1(主机、机架、槽位)。

机架和槽位必须和硬件对上:S7-1200 和 S7-1500 的 CPU 在机架 0、槽位 0 或 1 上应答;典型的 S7-300 CPU 坐在机架 0、槽位 2;S7-400 的机架随组态而变。槽位填错会让连接失败,而不是读到错的数据。

每个点位都可以设自己的轮询间隔(ms);点位填 0 就退回设备的间隔。

按名称读取

按名称读取的设备,其点位在“信号源”卡片的变量名字段里按 TIA Portal 的写法写出变量:数据块和变量,成员前面加点,数组元素放在方括号里。TIA Portal 的双引号可以照样输入("GanterOpt".Real_),会被去掉。

TIA Portal 中的变量 变量名
数据块 GanterOpt 中的 Real_ GanterOpt.Real_
UDT 实例 Udt_ 的 Valor GanterOpt.Udt_.Valor
数组 Vetor 的元素 0 GanterOpt.Vetor[0]
DTL DataHora GanterOpt.DataHora:一个点位,一个日期时间

不用填存储区、DB 号或字节:变量在哪里、是什么类型,都由 CPU 告知,驱动把它读成点位的数据类型:

CPU 中的类型 数据类型 说明
Bool Boolean
Byte、USInt;SInt Byte;SByte 无符号;有符号
Word、UInt;Int UInt16;Int16 无符号;有符号
DWord、UDInt;DInt UInt32;Int32 无符号;有符号
LWord、ULInt;LInt UInt64;Int64 全部 64 位,精确
Real;LReal Float;Double
Char、String String Windows-1252,和按地址时一样
WChar、WString String UTF-16,任何文字
Time、S5Time Int32 毫秒
LTime Int64 纳秒
Time_Of_Day UInt32 从午夜起的毫秒数,小于 24 h
Date、Date_And_Time、DTL、LDT DateTime 仅日期;日期和时间

设备发现给每个点位带上它的变量的数据类型和单位(ms、ns)。手工建的点位用您选的数据类型,CPU 的值会换算成它。

String 或 WString 按块中声明的长度整体写入,驱动在第一次写入前从变量读出这个长度:更长的文本会连同两个长度一起被拒绝,什么也不发送;String 拒绝 Windows-1252 以外的字符。DTL 作为一个日期时间整体读写;它的八个字段从不单独提供,因为单独写一个字段会接受任何值(包括月份 90)。超出类型范围的值(24 h 或以上的 Time_Of_Day,给 Int 的 40000)会连同范围一起被拒绝,什么也不发送。CPU 里没有的名称就是这个点位的错误,并会这样说明;单独写出 DTL 的某个字段,会得到改写 DTL 本身的建议。

HMI 设置

TIA Portal 为数据块的每个变量保存三项设置,在块的列里。站点像 Siemens 自己的 HMI 和 OPC UA 服务器一样遵守它们,不管 CPU 放行什么:

TIA Portal 中的设置 未勾选时
Accessible from HMI/OPC UA/Web API 这个变量既不读也不写:点位的错误会写出这项设置的名称,设备发现也不列出它。
Visible in HMI engineering 设备发现不列出这个变量;手工写出它的点位照常读取。
Writable from HMI/OPC UA/Web API 这个变量只读:写入会被拒绝并写出这项设置的名称,点位的访问提供只读并说明原因,设备发现把它作为只读提供。

没有按名称访问的 CPU

接受连接却不响应按名称访问的 CPU(固件 V2.9 之前的 S7-1500、V4.5 之前的 S7-1200、在 V17 之前的 TIA Portal 中组态的项目,或只会 S7comm 的 CPU)会让设备保持离线。设备页面用一条提示代替错误来说明这一点:CPU 需要什么,TIA Portal 在哪里显示固件(CPU 正在运行的在 Online & diagnostics,项目写的版本在 CPU 属性的 General > Catalog information),以及三条出路:

  1. 升级 CPU 固件,在 TIA Portal 项目中为 CPU 设置相同的版本,并下载硬件组态。只升级固件是不够的。
  2. 把访问设为按地址,允许 PUT/GET,并让数据块不用优化访问(准备 CPU)。
  3. 通过 CPU 自己的 OPC UA 服务器(S7-1500,或固件 V4.4 起的 S7-1200)用 OPC UA 驱动读取。

设备的每个点位在自己的页面上也带着同一条提示,CPU 一按名称响应,提示就自动消失。诊断日志和智能体在设备的错误里读到同样的步骤。

准备 CPU

这一节讲的是按地址访问;按名称读取的设备一项设置都不需要。

S7-1200 或 S7-1500 只有在它自己的两项设置都到位时,才响应 S7comm 的绝对寻址。两项都在 TIA Portal 中设置,并下载到 CPU。S7-300 或 S7-400 两项都不需要。

设置 在 TIA Portal 中的位置 没有它时
勾选 Permit access with PUT/GET communication from remote partner 打开 CPU 的设备组态,选中该 CPU,然后打开 Properties > General > Protection & Security > Connection mechanisms。下载硬件组态(Download to device > Hardware configuration):只下载程序不会带上它。 CPU 接受连接,但拒绝每一次读和写。设备保持连接,它的点位读作质量不可用。
在工作站读取的每一个数据块上,取消勾选 Optimized block access 在项目树的 Program blocks 下右键单击该数据块,然后打开 Properties > General > Attributes。编译该块并下载。之后该块的 Offset 列会显示每个变量的起始位置,也就是点位的起始字节要填的值。 CPU 不按地址提供该块的任何字节。它的点位读作质量不可用,设备的其他点位照常读取。

更改 Optimized block access 会在下载时重新初始化该数据块:其变量回到起始值。标志位存储区(M)、输入(I)和输出(Q)始终可以寻址,无需更改。必须保持优化的数据块可以换一种方式读取:由 PLC 程序把工作站要读的值复制到一个未优化的数据块或标志位存储区,点位指向那里;或者由工作站通过 PLC 自带的 OPC UA 服务器(S7-1500;固件 4.4 起的 S7-1200),用 OPC UA 驱动来读。

当 CPU 因为其中任何一项设置而拒绝时,设备页面会用一条提示说明是哪一项,并附上这些步骤;CPU 一接受,这条提示就会自行消失。对于数据块,提示会列出该块以及因此读不到值的点位。诊断日志和代理读到的是同样的步骤。CPU 中没有的数据块,以及超出数据块末尾的地址,会在指向它们的点位上照实说明。

寻址

这一节和后面两节(数据类型、写入)讲的是按地址访问;按名称访问见按名称读取。

S7 点位是靠定型字段寻址的,不是靠一串自由文本。面板把它们放在点位的“信号源”卡片里:

字段 含义 接受的取值 默认值
存储区 要读的存储区。 DataBlock、Merker、ProcessInput、ProcessOutput、Timer、Counter DataBlock
DB 编号 哪一个数据块,只在“区域”是 DataBlock 时显示。 0 及以上 1
起始字节 值在这个区域里从哪个字节偏移开始。在 Timer 和 Counter 区域里,这个框改标为定时器编号或计数器编号,问的是那个定时器或计数器的编号。 0 及以上 0
位号(0–7) 起始字节里的位位置。只对布尔点位显示。 0–7 0
最大长度(留空为 254) 一个 S7 STRING 或 WSTRING 声明的最大长度,按字符计。只对 Timer 和 Counter 之外的文本点位显示。 STRING 为 1–254,WSTRING 为 1–16382,或留空 留空
PLC 中的字符串类型 文本在块里声明的类型,与长度并列:STRING(每个字符一个字节,Windows-1252)或 WSTRING(每个字符两个字节,UTF-16,任何文字都能容纳)。只在显示最大长度的地方显示。 STRING、WSTRING STRING

这些区域对应到 Siemens 常用的记法:Merker 是标志位存储区(M),ProcessInput 是过程映像输入(I/E),ProcessOutput 是过程映像输出(Q/A),Timer/Counter 是 S7-300 和 S7-400 CPU 的定时器和计数器区。定时器和计数器按编号寻址,不按字节:Timer 填编号 5 读的是 T5,Counter 填编号 3 读的是 C3。把经典的绝对地址翻过来是这样:

经典地址 数据类型 要填的字段
存着 REAL 的 DB5.DBD12 Float 区域 DataBlock,DB 号 5,起始字节 12
DB1.DBX3.4 Boolean 区域 DataBlock,DB 号 1,起始字节 3,位 4
存着 INT 的 DB2.DBW20 Int16 区域 DataBlock,DB 号 2,起始字节 20
MW10 Int16 区域 Merker,起始字节 10
M10.3 Boolean 区域 Merker,起始字节 10,位 3
IB2 Byte 区域 ProcessInput,起始字节 2
Q4.1 Boolean 区域 ProcessOutput,起始字节 4,位 1
T5 Int16 区域 Timer,定时器号 5
C3 Int16 区域 Counter,计数器号 3

布尔点位在总线上恰好读写一个位;它绝不会把周围那个字节重写一遍。其余每一种类型都从起始字节开始按字节寻址,宽度就是它数据类型的确切宽度。“信号源”卡片里那行只读的源地址(总线)会随着你编辑显示拼好的地址。

数据类型

点位的数据类型决定总线上那个 S7 原生类型。十三种 S7 原生宽度全都可用:

数据类型 S7 类型 总线上的大小
Boolean BOOL 1 位
SByte SINT 1 字节
Byte USINT 1 字节
Int16 INT 2 字节
UInt16 UINT 2 字节
Int32 DINT 4 字节
UInt32 UDINT 4 字节
Int64 LINT 8 字节
UInt64 ULINT 8 字节
Float REAL 4 字节
Double LREAL 8 字节
String STRING 或 WSTRING 最大长度 + 2 字节(STRING),最大长度 × 2 + 4 字节(WSTRING)
DateTime DTL 12 字节

多字节的值自动采用 S7 原生的大端字节序;没有字节序选项,因为根本用不着。

文本点位读的是标准的 S7 STRING 布局:一个字节的声明最大长度,一个字节的当前长度,然后是字符,每个字符一个字节,采用 Windows-1252,也就是 TIA Portal 和 Siemens HMI 显示 STRING 时用的代码页。所以工作站写入的内容就是 TIA Portal 和 HMI 显示的内容("Peça 12" 仍是 "Peça 12"),工作站读回来的也一样。最大长度按字符数计,必须和块里的 STRING 声明对上(留空表示 S7 的最大值 254);驱动每次读传输的是最大长度 + 2 个字节。日期时间点位映射到 S7-1200/1500 系列的 DTL 结构(从年一直到纳秒);较老的 8 字节 DATE_AND_TIME 不提供。

PLC 中的字符串类型为 WSTRING 的文本点位改读 S7 WSTRING 布局:一个字的声明最大长度,一个字的当前长度,然后是字符,每个字符两个字节,采用 UTF-16,所以任何文字都能容纳("中" 写进去,读回来仍是 "中")。最大长度仍按字符数计,从 1 到 16382,必须和块里的 WString 声明对上(留空表示 254,即 TIA Portal 给不带长度声明的 WString 的长度);驱动每次读传输的是最大长度 × 2 + 4 个字节。S7comm 无法从 CPU 读出类型,所以它必须和变量一致:对着 WString 变量却仍设为 STRING 的点位,会按错误的布局读写。这个字段出现之前保存的点位都是 STRING。

写入

访问为读写或只写的点位可以被写。写入寻的是和读一样的区域、字节和位:布尔写入置它那一个位,其余一切都写它类型确切的那些字节。新点位一开始是只读。

文本写入如果需要的字节数超过最大长度,就会被拒绝,什么也不会发送,绝不会被截短到合适的大小:诊断日志和智能体读到的是,例如 "The DB1 byte 44 write was not sent: the text takes 21 bytes, and the STRING holds 20."。长度正好等于最大长度的文本会被完整写入。

含有 Windows-1252 之外字符(例如汉字)的文本写入也会这样被拒绝,绝不会用问号代替该字符写进去:诊断日志和智能体读到的是,例如 "The DB1 byte 44 write was not sent: the STRING holds Windows-1252 characters only, and '中' (U+4E2D) is not one of them; it fits once the tag's text type in the PLC and the PLC variable are both WSTRING."。点位的面板会用工作站的语言给出同样的原因。

要写这样的文本,请在块里把变量声明为 WString,并把点位的PLC 中的字符串类型设为 WSTRING。WSTRING 每个字符按两个字节计,所以超过其最大长度的文本同样会被拒绝,什么也不会发送:例如 "The DB1 byte 94 write was not sent: the text takes 42 bytes, and the WSTRING holds 40 (20 characters of two bytes)."。

设备发现

按名称读取的 CPU 会列出它的变量;S7comm 什么都不列,广播也找不到 CPU。在驱动页面上,扫描范围卡片里的要扫描的 CPU指定是哪台 CPU:本驱动下按名称读取其 CPU 的一台 Siemens 设备(在这台设备的主机上扫描,并用它的密码登录,受密码保护的 CPU 就是这样列出变量的),或者在此输入的地址,CPU 的地址填在 CPU 地址里。

发现设备把这台 CPU 作为一台设备提供,变量作为点位:提供的是 CPU 标为可从 HMI 访问且可见的变量,全部已勾选,带着 CPU 告知的类型,CPU 标为不可从 HMI 写入的是只读。列表是按每个名称的路径排成的树:数据块,然后是每个结构体或 UDT 实例和每个数组,然后是变量,每个以名称中不与其他变量重复的最短结尾命名(Real_、Valor、Vetor[0])。勾选一个分支会勾选或取消勾选它下面的全部内容,分支上显示它的变量中有几个已勾选;一个 DTL 就是一个变量。添加设备用勾选的点位新建一台按名称读取的设备。

本站点已有 Siemens 设备按名称读取的 CPU,不管扫描是怎么指定的,就是那台设备:扫描用那台设备的密码登录,添加所选点位添加它还没有点位的变量。在按名称读取的设备页面上,点位卡片里的发现点位用同样的树只对这台设备做同样的事(见设备发现)。按地址读取的设备不提供发现点位:它的点位请手工添加。

需要知道的事

  • 定时器和计数器区只存在于 S7-300 和 S7-400 的 CPU 上。S7-1200 没有这两个区,S7-1500 即使允许了 PUT/GET,也会以“Address out of range”拒绝通过 S7comm 读写这两个区;这时请在 PLC 程序里把定时器或计数器的值复制到一个数据块或标志位存储区,再从那里读。在有这两个区的 CPU 上,它们按编号寻址,不按字节偏移:那个框问的是定时器或计数器本身(T0、T1、T2 和 C0、C1、C2)。每个值是一个 16 位字,所以要配 Int16;更宽或更窄的数据类型会被拒绝,点位名写进诊断日志,而这台设备其他的点位照读不误。
  • 一台够不着的 PLC 在启动时不花什么代价:设备在后台一直重试,在连接接上之前它的点位读作质量不可用。
  • 设备上线之后被拔掉的线缆,在下一次读取时被发现:设备转为离线,它的点位转为质量不可用,等网络回来它自己重新连上。CPU 拒绝的一个地址不会造成这种局面,所以一个打错的点位绝不会把这台设备其余部分一起拖垮。读取时发现链路已断的点位,用工作站的语言说明与设备的连接已断开,Sharp7 的原话留在事件页面。