我前后翻过几遍西门子AF框架的文档,第五章是我个人觉得最容易读歪的一章。前面几章给你铺垫了各种功能块和数据结构,看到第五章,你会以为终于到了实操环节,但真正把它看完就会发现,第五章写的不是某一个具体程序,而是整套框架的装配逻辑。说直白点,它教你的不是“怎么写一个阀门控制块”,而是“怎么把一堆阀门控制块、电机控制块、诊断块、安全逻辑块有序地塞进一台S7-1500,并且让它们协同工作、出错可查、停机可恢复”。
这篇文章是我翻译第五章过程中的理解笔记,也是写给正在学西门子1500编程、想做标准化程序、或者被设备维护折磨过的工程师的一份导读。如果你已经在搜“西门子阀门FB块”“C#连接西门子OPC”“威纶通触摸屏导入西门子S7-1200标签”这类关键词,说明你已经有明确的落地需求,只是缺一套把零散功能串起来的思路——这正是AF框架第五章想解决的事。文章里所有程序结构和工程方法,都来自AF框架给出的通用范式,我会尽量用我能查到的真实项目经验把它讲透。
1. 第五章到底在讲什么:AF框架的装配逻辑
1.1 前四章铺完底子,第五章要求你“装起来”
我接触到的AF框架文档,通常第一章讲框架的背景和定位,第二章梳理硬件平台与软件版本,第三章开始定义程序结构,第四章逐个给出功能块的接口和内部逻辑。到了第五章,内容会突然变得“工程化”:循环中断OB怎么分配,启动、停止、故障三种状态怎么切换,通信资源怎么预留,HMI和诊断数据从哪里统一取。
很多工程师读到这里会不适应,因为前四章像说明书,第五章像施工图。一个典型的错误是把第五章当成“可选内容”,跳过它直接按自己习惯把功能块往OB1里拖。程序确实能跑,但后续维护时问题全出来了:某个阀门的反馈丢了,不知道是硬件问题还是逻辑被别的块改过;设备急停后再启动,工艺状态没有统一复位路径,操作员得手动把所有画面都点一遍。AF框架第五章存在的意义,就是把这些“事后麻烦”在装配阶段解决掉。
如果你正在翻译或阅读这一章,我的建议是不要只盯着单个块的代码,先在纸上画出你整台设备运行时的“生命周期”:上电后先做什么、按下启动后做什么、故障发生后做什么、急停复位后重新启动又从哪里走。第五章节的装配顺序,本质就是在回答这些问题。
1.2 为什么装配逻辑比单个功能块更值钱
单独看AF框架里的每个功能块,你会觉得“这我也能写”。一个阀门控制块无非是开命令、关命令、反馈、超时、报警,逻辑上并不复杂。但当你面对一台有几十个阀门、十几台电机、多段加热、多路模拟量控制的设备时,麻烦就不在单个功能块,而在块与块之间的衔接规则。
第五章给我的最大启发是三层分离:
- 物理层:只管传感器和执行机构的信号采集与输出,不掺合工艺判断。
- 逻辑层:工艺联锁、顺序控制、PID运算都在这一层,不直接读I/O地址。
- 管理层:HMI显示、报警归档、配方管理、数据记录统一走一套接口,不散落在各处。
这个思路放到生活里特别好理解。你装修房子,水电工只负责把水管和电线铺到位,木工只负责柜子和吊顶,最后你拿到的是整体协调的居住空间。如果让水电工顺手把柜子打了,木工又把电线改了,房子大概率不能住。程序装配也是这个道理,各层职责清晰,才能保证现场调试时不用翻遍整个CPU找问题。
2. AF框架的复用单元:从阀门FB块到工艺状态机
2.1 输入输出都走“镜面块”,逻辑层不碰硬件地址
AF框架里几乎第一条硬规矩就是:逻辑层不直接访问I/O地址。所有DI、DO、AI、AO信号,先统一采集到专门的“I/O映象DB”里,然后由一组标准的IO处理FB把数据“搬运”到逻辑层能用的中间变量。反过来,逻辑层的输出命令也不是直接写硬件输出,而是先写到映象DB,由输出处理块统一刷新到物理输出点。
这套做法看起来多绕了一圈,实际解决了我踩过的一个大坑。早年在做一台加热设备时,我在三个FG(功能组)里直接读了同一个温度传感器的地址,后来接线端子氧化导致信号跳动,我排查了半天才发现三个块对同一个通道做了不同的滤波处理,读数互相打架。如果当时用了AF框架的IO映象方案,信号只在采集块里处理一次,后面所有人拿到的是同一份“干净数据”,就不会出现这种低级又难查的问题。
具体实现上,IO处理块的接口设计可以参考这样一个结构:每个数字量输入通道对应一个BOOL变量,带名字、带注释、带上电默认值;模拟量输入通道在采集块里完成量程换算,输出值直接是工程单位,比如温度就是摄氏度,压力就是千帕。逻辑层的工程师永远不用关心硬件上是4-20毫安还是0-10伏,那属于物理层的职责。
2.2 阀门FB块的联锁、允许与超时:一个能抄的状态机
AF框架文档里对工艺功能块的处理非常统一,几乎每个控制块都围绕“状态机”展开。以最常见的开关阀控制为例,我根据翻译第五章时整理出来的套路,总结出一个可以直接落地的状态模型:
| 状态 | 含义 | 进入条件 | 退出条件 |
|---|---|---|---|
| IDLE | 空闲 | 上电初始化 | 收到打开命令 |
| OPENING | 正在打开 | 允许条件满足且收到开命令 | 开反馈到位 |
| OPEN | 已打开 | 开反馈到位 | 收到关闭命令 |
| CLOSING | 正在关闭 | 允许条件满足且收到关命令 | 关反馈到位 |
| CLOSED | 已关闭 | 关反馈到位 | 收到打开命令 |
| FAULT | 故障 | 超时未到位或反馈异常 | 手动复位且故障消失 |
这个状态表看着朴素,但执行时有几个细节非常关键。第一个是“允许条件”(Permissive)和“联锁条件”(Interlock)要分开:允许条件满足才允许块启动,联锁条件不满足时块必须立刻停。对应到程序里,我会把联锁信号接到状态机的执行路径上,而不是简单地在输出端串一个BOOL。第二个是超时定时器,打开命令发出后开始计时,如果超过设定时间反馈还没到位,直接进FAULT并把故障代码写到诊断DB里,方便操作员在HMI上看到底是“超时”还是“反馈丢失”还是“命令冲突”。
下面这个SCL接口声明我直接从项目里整理出来的,可以作为功能块的“模板”:
FUNCTION_BLOCK "FB_ValveOpenClose" { S7_Optimized_Access := 'FALSE' } VERSION : 0.1 VAR_INPUT bEnable : BOOL := FALSE; // 总使能 bOpenCmd : BOOL := FALSE; // 打开命令 bCloseCmd : BOOL := FALSE; // 关闭命令 bOpenFeedback : BOOL := FALSE; // 开到位反馈 bCloseFeedback : BOOL := FALSE; // 关到位反馈 bPermissive : BOOL := FALSE; // 允许条件 tTimeout : TIME := T#10S; // 动作超时 END_VAR VAR_OUTPUT bOpenOut : BOOL := FALSE; // 打开执行输出 bCloseOut : BOOL := FALSE; // 关闭执行输出 bDone : BOOL := FALSE; // 动作完成 bError : BOOL := FALSE; // 故障标志 diErrorCode : DINT := 0; // 故障代码 END_VAR注意我把数据块访问方式设成了非优化访问(S7_Optimized_Access := 'FALSE'),这主要是为了后面HMI和上位机通信方便,这个坑后面第四章会单独讲。状态机的实际代码用CASE语句实现,每个状态分支里有“进入动作、执行动作、退出条件”三段结构,调用者只需要填命令和反馈,不用关心内部怎么跳转。
2.3 把PID和变频器封装进工艺块,别让公式散落在程序里
AF框架里除了设备控制块,还有一类“工艺块”。工艺块不管阀门的开关,管的是“这锅温度怎么升、这罐压力怎么调”。我见过太多程序把PID指令直接拖在主程序里,参数改起来麻烦不说,每个PID的设定值、反馈值、手动自动切换逻辑都散布在FB中间,找一圈都找不全。
更麻烦的是PID参数风格不统一。有人用增益、积分时间、微分时间,有人用比例带、积分系数、微分系数。搜索热词里有“西门子和三菱的PID参数可以换算吗”,我专门试过,答案是可以换算,但必须统一量纲,不能把三菱的Kp等于多少直接填到西门子PID_Compact里。西门子基于百分比系统:输入偏差用百分比表示,输出也用百分比表示,增益无量纲;三菱则常常用工程单位直接计算,比例项数值受温度范围影响很大。你直接抄一个参数过去,大概率系统剧烈振荡。
我的做法是在AF框架的工艺块里做一层“参数桥”:工艺块内部使用西门子标准PID_Compact,把来自HMI的设定值、工艺反馈值先做归一化处理,再送进PID_Compact。这样无论是触摸屏还是上位机,面对的都是工程单位,不会看到PID内部的百分比,将来换PLC平台时,设备层程序可以整体迁移,只有工艺块内部需要重写。
3. 安全逻辑怎么放进框架:急停、安全光栅与F程序
3.1 标准PLC和安全PLC的边界划分
搜索热词里有“西门子安全PLC 安全光栅程序编写”“西门子安全程序 急停块”,这说明大家开始关注安全电路的程序化处理了。AF框架在第五章对这一块的描述非常克制,但边界画得很清楚:安全功能永远由安全PLC(F-CPU)或者安全继电器承担,标准PLC只在必要时接收安全系统给出的状态。
注意这句话很重要。很多人写程序时习惯把急停信号直接接到普通输入模块上,然后在OB1里写“如果急停按下就停止输出”。这种做法在非安全应用里能用,在安全应用里是不合规的,因为普通CPU是没法通过TÜV安全认证的。F-CPU里的F程序跑在专门的安全OB里,数据会经过安全协议完整的完整性检查,与标准OB有严格的隔离机制。
如果你的项目使用了F-CPU,AF框架的装配方式通常是这样的:F程序里建立安全输入DB和安全输出DB,急停、安全光栅、安全门开关这些F信号先进F-I/O,由F程序把状态复制到安全DB里的BOOL变量;标准程序不能直接写这些F变量,只能读取一个“安全状态镜像”。工艺控制FB从“安全状态镜像”拿到的不是原始急停信号,而是PLC安全程序给出的“允许运行”信号。这个信号丢了,工艺块就停下来;但工艺块内部为什么不运行、哪一步停的,属于标准程序自己的诊断范畴。
3.2 安全状态如何通知工艺层:只给条件,不给数据
我自己在带安全项目的过程中总结出一个经验:安全系统和工艺系统的交互,只传递“条件”,不传递“数据”。意思是安全侧告诉标准侧“现在是否安全”,但不告诉标准侧“温度是多少、压力是多少、阀开到了什么位置”。反过来说,工艺侧永远不能通过写安全DB的方式去复位一个安全条件。
在程序结构上,我会在标准OB1的最前面调用一个“安全状态读取块”,把所有安全条件汇总成一个字(WORD)的位图,比如BIT0是急停未按下、BIT1是安全门关闭、BIT2是光栅未被遮挡。工艺块里用一个统一的“全局安全允许字”去联锁。这样维护安全I/O时,只需要改安全读取块内部的一句话,后面所有工艺块的联锁逻辑都不用动。
还有一个容易被忽略的地方:安全光栅在光路被遮挡再恢复时,很多设备要求必须“确认”才能重新启动,不能自动运行。这个“确认”逻辑放在F程序里做是合规的做法,千万不要图方便在标准PLC里做一个“光栅复位”按钮去覆盖安全条件。安全回路里的复位和标准程序里的复位都要有独立的HMI操作记录,这是安全审计的重点检查项。
3.3 博途防火墙与安全通信组态
现在很多S7-1500支持PROFINET安全通信和安全组态功能,搜索词里的“西门子博途防火墙设置”指的就是这方面的配置。AF框架对网络话题着墨不多,但从工程部署的角度看,通信安全是第五章装配逻辑里必不可少的一环。
给1500做防火墙规则时,我会先明确设备对外服务的方向。如果CPU只跟HMI和上层SCADA通信,那么对外开放的端口越少越好;如果下面挂着ET200远程站和变频器,PROFINET IO通信必须保证在规定时间内完成,防火墙规则就不能把这些连接的优先级降得太低。博途里配置防火墙时有一件事很容易忽略:做了访问规则之后,要重新生成并下载组态,PLC会短暂停一下机,现场调试时要选在设备停运窗口去做,不要对着正在跑产线的CPU贸然动网络组态。
我吃过一次亏:在某项目里改了防火墙规则后没有做离线仿真就直接下载,结果一台变频器的PROFINET连接断了,现场设备直接报“机架故障”。从那以后我再动安全通信组态,一定先在仿真软件里跑一轮IO设备在线状态的测试,确认所有从站刷新正常再下现场。
4. 集成与排查实战:HMI标签、OPC通信、PID换算和授权
4.1 威纶通导入S7-1200标签最常见的三个“对不上”
搜索词里“威纶通触摸屏导入西门子S7-1200标签”出现频率很高。我做过的不少项目用的确实是威纶通屏配1200/1500,这种组合性价比高,但标签导入时的坑非常固定。
第一个坑是数据块访问方式不一致。S7-1200默认的DB是优化访问,符号名称存在CPU里,外部系统通过符号访问。威纶通老版本的驱动对优化访问支持不好,导入时能看到变量但地址是空的。解决办法就是像我在2.2节代码里写的那样,给HMI通信专用的DB块设置非优化访问,或者建立“HMI镜像DB”,把需要显示和操作的变量统一拷贝到非优化DB里。
第二个坑是变量类型兼容性。PLC里的REAL、DINT、TIME,在触摸屏驱动里不一定都支持直接读写。比如TIME类型在威纶通里经常被当成DWORD处理,你读出来的是毫秒数而不是“T#5S”这样的时长格式。我的做法是画面所需的时间值全部在PLC侧转成REAL(单位秒),HMI只负责显示数字。
第三个坑是标签名称里的特殊字符。布尔变量取名叫“急停-6#炉”这类名字,导入威纶通时大概率出错。框架级的命名规范里,变量名只允许字母、数字、下划线,含义用注释和画面文本去表达,不要用中文变量名,也不要带杠号和井号。这条规矩我是在一次半夜调试时用血泪换来的,从那以后所有给HMI用的标签都过一遍命名过滤器。
4.2 C#读OPC和Intouch连1500:数据块访问方式决定一切
“C#连接西门子OPC”和“Intouch跟西门子1500通讯”是两套不同的技术栈,但它们踩的坑几乎一样:地址对不上。C#走OPC DA或者OPC UA时,变量地址一般写成“S7:[DB号]DBW[偏移]”这种绝对地址格式;Intouch接S7-1500,可以用S7协议直接读DB。
问题出在优化访问上。一旦DB开了优化访问(默认状态),符号名对应的物理偏移地址是重新排列过的,你按Block_1.DBW0的绝对地址去读,读到的是完全不是你想的那个变量。我在一个MES项目里吃过这个亏:MES系统要求PLC侧把20个温度值连续排列在一个DB里,我用优化访问建的DB,上位机那边死活读不到正确的数据。
解决思路有两个。一个是PLC侧建专用的“通信DB”,固定偏置、非优化访问、所有变量按数据长度排好,上位机直接按偏移地址读,简单粗暴且稳定。另一个是走符号寻址,在OPC UA服务器里加载GSD文件和符号表,上位机用变量名去读。我个人的建议是:如果上位机是C#二次开发,尽量走符号寻址,少跟偏移量打交道;如果是现成的SCADA软件搭数据点,建固定偏移的通信DB更快。两种方式在AF框架里都属于“管理层”的接口规范,把数据字典和维护记录做好,换人接手时不会抓瞎。
4.3 西门子与三菱的PID参数能不能换算?能,先统一量纲
很多从三菱PLC转过来的工程师,面对西门子PID_Compact的第一反应是“参数怎么填都不对”。我在热词里看到这条时特别有共鸣,因为我也被这个问题困扰过。
三菱PID常见的是PID指令里的P、I、D三个系数,但每个品牌的实现方式差异很大:有的直接填写增益、积分时间、微分时间,有的填写采样周期相关的计算系数,甚至有的填的是带作用百分比。西门子PID_Compact的参数体系是《标准PID功能块》那套:增益(Gain)、积分时间(Ti)、微分时间(Td),全部基于百分比标准。
直接换算的思路是先做归一化测试。把被控对象手动打到50%输出,记录稳态下的偏差百分比,增益大概等于“输出变化百分比/偏差变化百分比”。积分时间可以先给一个保守值,比如120秒,然后现场整定。你从三菱抄来的那个Kp,如果原来控制的是一个0到100度的加热对象,直接填进西门子PID_Compact大概率偏大,因为西门子把温度百分比的偏差除以100后再乘增益,增益含义和三菱的“每偏差1度输出多少”完全不是一个量纲。
我在AF框架的工艺块里做了一个设计:PID参数不进块内部,而是放在一个单独的工艺参数DB里,并且在HMI画面提供“在线整定模式”。现场调试时不用打开博途改程序,直接在触摸屏上就能调增益和积分时间,调完一键保存到配方区。这个细节让现场调试效率提升明显,客户以后换料调工艺时也不需要叫厂家来改程序。
4.4 博途软件报错与授权异常的应急排查
搜索词里有“西门子博图软件报错‘step 7 basic‘”“西门子授权提示密钥容器损坏”,这类问题看着吓人,实际大部分能很快恢复。我总结了一套应急排查顺序。
先看Automation License Manager服务是否还在运行。Windows更新或者杀毒软件清理之后,授权服务常被停掉,表现为博途启动时提示找不到授权或者密钥异常。打开服务管理器,找到Automation License Manager Service,确认状态是“正在运行”。
如果服务正常但提示“密钥容器损坏”,先别急着重装整个博途。密钥容器通常对应操作系统的证书存储,我会先把License Manager里的授权信息备份(导出为文件),然后尝试修复证书存储。更简单的一种方式是把计算机时间改成标准时间,再打开License Manager让它重新验证授权。我有一次遇到密钥容器损坏,最后发现是系统时间被调到了明年,License过期校验直接出问题。
最后才考虑重装。注意重装博途之前,一定要把项目文件完整备份出来,顺手把全局库和自定义功能块也打包带走。很多人只备份项目文件,忘了备份库,装完新系统后发现自定义AF框架函数块全没了,那才叫欲哭无泪。
5. 翻译第五章时我做的术语表:也是给程序命名用的规范
5.1 12个高频词的翻译与注释
翻译AF框架文档时,术语统一是一件比翻译本身更费心的事。同一个英文词,不同工程师写的块命名完全不一样,后面维护的人根本猜不出原意。我把第五章里反复出现的术语整理成了一张对照表,这既是翻译用的字表,也可以直接当程序命名和注释的规范来用。
| 英文术语 | 中文翻译 | 备注与程序命名建议 |
|---|---|---|
| Interlock | 联锁 | 触发后设备必须停机的条件,通常取反后参与逻辑 |
| Permissive | 允许条件 | 允许设备启动的条件,不满足时设备无法启动 |
| Enable | 使能 | 总开关,一般为工艺模式或操作员授权 |
| Acknowledge | 确认/复位 | 故障消除后的人工确认动作 |
| Feedback | 反馈 | 执行机构实际状态的检测信号 |
| Command | 命令 | 操作员或上层系统下发的动作指令 |
| Monitoring | 监控 | 对运行状态和故障状态的实时跟踪 |
| Diagnostic | 诊断 | 故障代码、时间戳、触发记录的总称 |
| Runtime | 运行时间 | 设备累计运行时间,常用于维护提醒 |
| Interlock Chain | 联锁链 | 一组按顺序排列的联锁条件,常用于安全回路 |
| Setpoint | 设定值 | 工艺目标值,由配方或操作员给出 |
| Actual Value | 实际值 | 当前工艺反馈值,参与闭环控制 |
翻译时我刻意保留了“联锁”而不是“互锁”。“互锁”常被理解为两个设备不允许同时运行,而“联锁”强调基于条件的禁止与允许,语义更贴合框架本意。同样,“Permissive”我坚持译成“允许条件”,而不是“许可”,因为它不是授权体系里的概念,是纯工艺逻辑里的“放行条件”。
5.2 写程序时怎么让注释和块名保持“同一个调调”
第五章读完之后,我做了一个很重要的决定:把所有项目里自定义功能块的命名和注释风格统一到一套体系上。块名前缀按类型区分,FB和控制逻辑、FC和计算转换、DB和存储参数、OB和中断组织。变量名前缀约定好:b开头是BOOL,r开头是REAL,di开头是DINT,t开头是TIME。这个习惯看起来简单,但能救命的时刻是你半年后回来看一个别人写的块,光看变量名前缀就能猜出大概含义。
比如我在写一个加热段的工艺块时,块名是FB_HeatZone_Control,输入变量是rSetTemp、rActTemp,输出是bHeatOut、bFault。打开块的第一行注释写着“加热段控制:支持手动/自动切换,PID输出经限幅后送SSR”,后面任何人接手,五分钟内就能明白这个块是干什么的、怎么用。
AF框架第五章有一句话我记得特别牢:真正复杂的不是程序本身,而是程序长期运行过程中人和人的交接。设备调试时你可以靠脑子记住所有变量和逻辑,但三年后操作工换了一轮、电气主管换了一任,程序还能不能被人读懂,取决于基础打得规不规范。
我在实际翻译和落地AF框架的过程中最大的体会是:先理解章节的装配意图,再动手写任何一行代码。很多人一上来就奔着阀门控制块去,写完之后发现跟系统里已有的块风格冲突、跟HMI通信对不上、安全逻辑没地方挂,这就是没读第五章的代价。框架存在的意义不是捆住你的手,而是让整个团队写出来的程序在别人看来像是一个人写的。这个道理放在做设备的行业里,比任何一段代码都值钱。