做工控这些年,"收到一套旧平台的程序"是常事。前阵子一位做化工自控的朋友丢给我一套西门子S7-300系统甲醛生产线博途控制系统程序案例,压缩包打开一看,程序清一色在博途TIA STEP7里写的,组态目标是不算新的CPU315-2PN/DP。说实话,第一反应是"都什么时候了,怎么还在用S7-300",但把工艺和程序从头捋完,反倒觉得这套案例太典型了——老设备、危化工艺、新软件平台,三个要素叠到一起,正是现在大量存量产线改造和维保项目的真实写照。
这篇文章不打算给你复述项目报告,而是按我拆这套程序的顺序,把甲醛产线该有哪些控制点、S7-300在博途里的程序骨架怎么搭、PID和联锁怎么写、现场调试容易栽在哪里,串成一份能"抄作业"的经验记录。适合手里正好有S7-300老线项目、想学博途编程但缺一个完整案例、或者正准备把STEP7经典项目往博途上迁的工程师。
1. 案例里藏着一个现实坐标:S7-300搭配博途的必然性
1.1 老CPU为什么还能和博途搭伙
西门子S7-300这代产品,生命周期之长是有目共睹的。很多化工厂的甲醛线、树脂线、制酸装置,都是十几年前的成套设备,PLC至今稳定运行,业主不会轻易换整套系统。问题在于:老项目当年用STEP7 V5.5甚至V5.4维护,而现在新来的工程师多数只接触过博途TIA,编程习惯、指令库、数据格式都不太一样。于是就有了"S7-300老硬件+博途新软件"的混搭局面。
这套案例里的PLC是CPU315-2PN/DP,在博途V16里能正常组态、下载、在线监控,说明西门子对S7-300的支持一直没有断。我的判断是,S7-300再服役十年都不稀奇。对工程师而言,"会博途但不熟S7-300"和"会S7-300但不熟博途"都是缺一条腿,真正值钱的,恰恰是在博途环境下把S7-300玩熟。
1.2 硬件组态里最不该翻车的四个细节
拿到这套程序后,我先看的不是FB和FC,而是硬件组态。原因很简单:S7-300的硬件组态错了,程序写得再漂亮也跑不起来。结合这个案例的硬件配置,我把现场最常见的四个坑列出来。
| 组态要素 | 常见错误 | 后果 | 正确做法 |
|---|---|---|---|
| CPU型号 | 订货号后缀选错 | I/O地址与端子对不上 | 对照CPU面板铭牌逐位核对订货号 |
| SM331模拟量模块 | 博途组态量程和模块侧面量程卡不一致 | AI值飘、满量程不对 | 组态选4-20mA,模块侧面拨码也要拨到对应位置 |
| 机架电源 | 背板电流估算不足 | 模块随机复位、SF灯亮 | 按所有模块的背板耗流总和选PS电源 |
| DP从站 | GSD文件版本不匹配 | 通讯灯闪、从站诊断报错 | 用和从站版本一致的GSD文件重新安装 |
尤其量程卡这个坑,几乎每个项目都会遇到。博途组态里选的"4-20mA",一定要和SM331模块侧面那个小小的物理拨码开关一致,这一步错了,后面FC105、SCALE指令的参数再怎么调都没用。另外,S7-300的I/O地址是组态自动分配的,但很多老线的端子接线是按旧地址走的,组态完务必对照旧图纸逐点核对I/O地址表,否则到现场调试时会发现"程序里的地址和端子排上的线对不上"。
2. 动手前先把甲醛工艺的"测点地图"画出来
2.1 银法甲醛线的主流程与测点分布
不懂工艺就写程序,是工控工程师最大的忌讳。甲醛生产最常见的是银催化法:甲醇蒸发成蒸汽,和空气、尾气按比例混合,进入反应器在银催化剂表面氧化脱氢,生成甲醛反应气,然后急冷、吸收,得到甲醛水溶液。一句话概括:甲醇进料、蒸发、配气、反应、急冷、吸收、尾气处理。
把这套流程映射到PLC上,核心控制就四个字——温度、配比。我把这套案例里典型的测点和控制对象梳理成了一个表,具体数值每个厂有自己的工艺包,不能照抄,但测点逻辑是通用的。
| 工段 | 典型测点 | 控制/调节对象 | 关联的联锁方向 |
|---|---|---|---|
| 甲醇蒸发 | 蒸发器温度、液位 | 蒸汽调节阀、甲醇进料阀 | 液位低低/温度高高停进料 |
| 配气混合 | 混合气温度、甲醇与空气流量 | 空气流量阀、循环风机 | 比值越限、气体检测报警 |
| 氧化反应 | 反应器热点温度 | 空气通入量、冷却调节 | 温度高高紧急停车 |
| 急冷吸收 | 冷却器出口温度、吸收塔液位/温度 | 循环液泵、补水阀 | 液位高高/低低、循环泵故障 |
| 尾气处理 | 尾气温度、风机状态 | 引风机 | 风机故障联锁 |
有一点要特别强调:甲醇和甲醛都是易燃易爆物质,工业装置上配气工序会让甲醇浓度保持在爆炸极限之上运行,避开危险的爆炸区间。这是工艺安全的基本逻辑,程序里的比值控制和联锁都是围绕这个来的。你写程序前必须把这一层安全背景读懂,否则根本不知道联锁条件为什么要那么设计。
2.2 从P&ID到I/O映射:点位表怎么排才能后期不爆炸
拿到工艺流程图和P&ID,不要急着开博途,先把P&ID上的测点编号逐条转成I/O清单。这套甲醛线案例的点位规模大概是:AI二十几路、AO六七路、DI接近三十路、DO十几路,比较标准的化工小中规模装置。
按什么顺序排点位,直接影响后期调试效率。我的习惯:
- AI按工艺顺序排列,比如蒸发工段的温度、液位排一起,反应工段排一起,方便查线;
- 每个模拟量通道预留备用通道,至少留20%,别把SM331的所有通道都用满;
- DI按电机、阀门、仪表报警分类集中,不要混排;
- DO和DI尽量一一对应,电机启动命令和运行反馈放在同一地址段,调试时看变量表一目了然;
- 每个I/O点建立符号表,符号名用拼音、英文都可以,但必须统一,比如FIC_1001、M_101_RUN这种格式。
这套案例程序里,地址分配表做得相当规范,所有符号在PLC变量表里都有完整注释,连通道对应的端子号都写进去了。这一点看着不起眼,到现场却是救命的东西。前期乱排点位,后面调试两礼拜全耗在"找这个点在哪"上。
3. 程序骨架拆解:OB、FB、FC、DB的模块化设计思路
3.1 OB1、OB35、OB100:扫描节拍怎么定
从程序结构上看,这套案例的块组织相当标准:
- OB1:主循环,放公共逻辑和泵、阀的扫描调用;
- OB35:循环中断,案例里设置的是100ms,专门跑PID回路;
- OB100:暖启动,做数据初始化和联锁复位标志清理。
为什么PID必须在OB35里跑,而不是放OB1?因为OB1的扫描周期会被程序长短、通讯任务扰动,PID的采样周期忽长忽短,现场表现出来的就是调节阀抖动、温度来回摆。OB35按固定时间中断,相当于给PID一个不变的"节拍器",采样周期稳定,控制曲线才稳定。
S7-300对循环中断的最小间隔是有硬件限制的,不同CPU不一样,315系列一般能做到毫秒级,100ms足够了。设置方法是在博途里双击OB35,在属性对话框的"循环执行"里填100ms,单位是ms。这个参数要和后面FB41的CYCLE参数保持一致,否则就是自己给自己挖坑。
3.2 电机、阀门、联锁、报警:功能块怎么划分
打开这套程序的块目录,主要形式是"FB+背景DB",很少有大段裸逻辑散落在FC里。典型的功能块划分如下:
- FB_MOTOR:电机控制,包括启停、运行反馈、过载故障、保护逻辑;
- FB_VALVE:调节阀/开关阀控制,包括手自动切换、阀门反馈;
- FB_PID:对FB41的标准封装,把温度、液位回路统一参数接口;
- FB_ALARM:报警汇总,把分散的报警条件收拢到一个块里;
- FB_INTERLOCK:联锁逻辑,集中管理所有安全联锁条件。
这样设计的好处不只是"看起来规范"。每个FB有自己的背景DB,数据天然隔离,不会出现多个电机抢同一个M点的情况;后期增删设备只需要增加一个背景DB实例,不需要大段复制粘贴。很多刚从STEP7经典版转过来的同事不习惯带背景DB编程,总觉得调用FB还要填背景DB很麻烦,但实际上这才是S7-300/400乃至1500系列的正路。
这里顺便回应一个网上高频问题:调用FB时填不了DB块。通常不是你操作错误,而是FB的调用方式设成了"多重背景"却还想手填背景DB,两者冲突;或者当前项目里没有可用的DB编号。解决办法是在项目树里手动新建一个背景DB,然后在调用指令处右键选择生成背景DB,或者把FB块的调用接口改成单实例再填。博途里这个交互和经典STEP7略不一样,卡住很正常。
3.3 DB与UDT:数据和类型的复用
案例里用过不少UDT,这是这套程序里最值得学的地方。比如电机UDT里定义了启动、停止、运行反馈、故障、联锁复位、手自动切换这一组变量。定义一次UDT,生成电机DB时直接选这个UDT类型,所有电机的地址结构和注释完全一致。
这个对后期维护的意义非常大。维护工程师只要弄懂了一个电机的数据结构,所有电机都会看了。反过来,如果每个电机都手工建变量,五个电机五种命名风格,联锁里查一个"跳车"条件能翻半小时变量表。
全局DB也不是垃圾桶。案例里有个专门的联锁DB,里面只放联锁条件和联锁状态;模拟量处理有单独的DB,存放标准化之后的工程值。数据按功能分区,而不是"哪个块方便就塞哪个块",这也是模块化编程的底层逻辑。
4. 模拟量标定与PID闭环:博途里S7-300的控制回路落地
4.1 SCALE/UNSCALE:模拟量从原始值到工程值的标准做法
S7-300的模拟量模块把4-20mA映射成整数范围,常见的是0~27648,程序里必须把它线性转换成工程值,比如0-100%液位、0-300℃温度。博途对S7-300保留了经典FC105的升级版指令SCALE,在指令面板"基本指令>转换操作"里能找到,参数和习惯里的FC105基本一致:
- IN:AIW原始值,比如AIW256;
- HI_LIM / LO_LIM:工程量上下限;
- BIPOLAR:单极性选FALSE,双极性信号才选TRUE;
- OUT:转换后的工程值(REAL)。
一个最常用的"抄作业"模板:温度变送器量程0-300℃,输出4-20mA,接入SM331后,SCALE的IN填AIW地址,HI_LIM填300.0,LO_LIM填0.0,BIPOLAR选FALSE,OUT就是0.0到300.0摄氏度的REAL值。反过来,要把工程值输出成4-20mA给阀门,用UNSCALE指令,AO模块组态成4-20mA,IN填0-100的REAL工程量,OUT填AQW地址。
这里有几个坑要重点说。第一,模块测量范围选了4-20mA时,SM331内部输出是0~27648,但有人组态成了0-20mA,4mA以下仍有内部值,导致液位上飘。第二,上溢和下溢分别会到32511和负值这种"非正常值",程序里要用比较指令把超限值拉回来,最好直接送报警。第三,信号线接触不良时数值会突变,联锁程序里要能识别这种突变,这就是后面要讲的AI品质判断。
4.2 FB41的温度/液位PID回路
S7-300在博途里写PID,经典方案还是调用FB41"CONT_C"。这套案例里有蒸发器温度控制和吸收塔液位控制两个典型回路,都是FB41。
调用FB41必须建一个背景DB,比如DB_PID_Temp,然后在OB35里每个周期调用。关键参数整理如下:
| 参数 | 作用 | 案例里的常见值 |
|---|---|---|
| CYCLE | PID采样周期 | 必须等于OB35中断时间,0.1s |
| GAIN | 比例增益 | 先给0.5-2,看响应曲线再调 |
| TI | 积分时间 | 先给30-60s,温度回路普遍大滞后 |
| TD | 微分时间 | 常规给0,温度回路慎用微分 |
| MAN_ON | 手动/自动切换 | 手动时TRUE,切自动前先手动逼近 |
| PVPER_ON | 过程值是否直接读外围I/O | 一般FALSE,用PV_IN |
手动/自动切换是无扰动切换的关键。FB41内部自带一些切换逻辑,但现场出过一个问题:手动输出和自动输出偏差很大时,切换瞬间阀门猛跳。后来我的做法是在HMI上让操作员先把手动输出调到和自动计算值接近,再切自动。也可以在FB41前加一个斜坡功能,限制输出变化率。
蒸发器温度回路的整定套路,我一般这样走:先纯比例,GAIN从0.5开始,观察温度阶跃响应;系统振荡就减小GAIN,余差大就加积分TI;微分尽量不上,化工温度回路本身滞后大,TD整不好就是噪声放大器。另外,阀门是气开还是气关,决定FB41输出极性是正作用还是反作用,这个一定在组态时确认清楚,不要想当然。
4.3 SCL里的TON:定时器在博途中的正确用法
热词里有人问"博途SCL中TON怎么用",第一次从LAD转SCL的朋友最容易卡在这:LAD里拖一个TON盒子出来填参数就行,SCL里得先保证有TON类型的定时器实例。
两种常见写法。如果要封装在FB里,先在FB的静态变量区声明一个TON类型的变量:
// 静态变量区声明 // DelayTimer : TON; DelayTimer(IN := #Trigger, PT := T#5S, Q => #ErrorDelay, ET => #CurrentTime);如果是在FC里临时用,可以建一个全局DB,在DB里声明一个TON类型的成员,再调用:
"GlobalTimerDB".DelayTimer(IN := #StartSignal, PT := T#3S, Q => #Q_Out);注意博途的TON指令,输入输出参数前要加#号访问局部变量,定时器实例本身可以放在DB或FB静态区。别再想着用S5定时器那种"SD T1"的老写法了,S7-300在博途下用S5定时器也不是不行,但IEC定时器每个实例数据独立,不占系统定时器资源,封装进FB更干净。
定时器在联锁逻辑里最常见的用途是"延时确认",比如液位低低信号持续3秒再触发联锁,防止瞬间扰动造成误动作。这个设计在甲醛这类危化工艺里非常关键。
5. 联锁与故障安全逻辑:甲醛线程序的"最后一道防线"
5.1 联锁设计的优先级、冗余和首出记录
化工装置讲安全,PLC联锁虽然不完全等同于独立的SIS安全仪表系统,但在没有独立SIS的小型产线上,它就是主要保护功能。这套案例里的联锁逻辑单独放在FB_INTERLOCK里,设计上有几个原则值得一说。
第一,常闭逻辑优先。急停按钮、现场安全开关,信号回路用常闭点,断线时按"故障停车"处理,而不是"假正常"。这个和很多电工的习惯是反着的,但安全联锁必须这样。
第二,冗余表决。关键的温度高、压力高信号,可以做二选二或三选二逻辑。具体怎么选由HAZOP分析和工艺包决定,程序只是把表决逻辑落地。这套甲醛程序里,反应器超温就采用了两个独立测温点"二选二"确认,避免单个测温元件误报停车。
第三,首出锁定。联锁触发后,必须记录第一个触发原因并保持。这部分在程序里体现为一组BOOL变量和保持逻辑:第一个扫描周期里谁先为TRUE,谁被锁存,同时记录触发时的时钟值。复位按钮和联锁状态一起管理。
首出记录对事故分析的价值极大。现场出过这样的情况:联锁跳车了,操作员第一件事就是按复位,然后所有报警消失,分析原因无从下手。有了首出锁定,至少能知道"第一个触发条件是蒸发器液位低低",排查范围一下就缩小了。
5.2 联锁停车序列怎么写
以甲醛反应器超温为例,程序里的动作不是简单"停机"两个字,而是按顺序执行:
- 立即断开甲醇进料泵,切断原料来源;
- 关闭配气相关电磁阀,终止甲醇与空气的继续混合;
- 延时确认后停风机,避免在没有原料的情况下继续鼓入空气;
- 打开放空/紧急排放阀,让反应气走安全回路;
- 置位联锁保持标志,触发声光报警。
这套顺序不是我拍脑袋编的,而是从"消除点火源-切断反应物-泄放压力"这条安全逻辑推出来的。具体执行机构、阀门动作时间,每个产线都有自己的安全措施要求,程序逻辑层面的要点是"顺序要用延时或反馈确认",不能所有输出瞬间全切,否则可能产生新的危险工况。
程序实现上,联锁停车经常用手写状态字配合步进逻辑。状态字里定义正常运行、准备停车、联锁停车、复位检查等状态,每个状态允许的动作不一样。这样比一大堆置位复位互相纠缠清晰得多。
5.3 信号断线联锁:AI品质判断不能省
很多程序漏了这一点。模拟量信号断线、超限时,回路还在"自动控制",可能导致阀门全开或全关的极端动作。这套案例里专门有一段AI品质判断逻辑。
S7-300没有像S7-1500那样自带Quality Code,所以用数值范围判断:AIW原始值超过上溢值,或者等于7FFF这类非法值,就按"信号故障"处理。处理动作包括:对应PID回路强制切手动,保持当前输出;联锁条件里把这个点位视为"不满足/故障"而非"正常";报警提示操作员检查变送器。
这章我特意拿出来讲,是因为现场出过AI板卡通道掉线导致调节阀全开的教训。信号故障时的阀门动作方向,其实是FEMA分析里该定的事,但程序至少要做到"故障了别假装正常"。
5.4 PLCSIM里怎么验证联锁逻辑
博途PLCSIM对S7-300的支持是有限的,常见315、317系列可以仿真,但通信指令、部分高速计数和位置模块特性会和实机有差异。用PLCSIM验证这套甲醛程序的功能逻辑没问题,I/O轮询和通讯诊断这类行为还是要上真机确认。
仿真时建议把输入输出用变量表的强制功能代替实际接线。验证联锁时,先给一个"虚假正常"的输入集合,然后逐个改变联锁条件的输入值,观察输出顺序和首出记录是否正确。这样一遍跑下来,基本能把联锁逻辑的bug清掉大半,到现场再压缩到只做"真实信号测试"。
6. 博途安装、虚拟机连接与现场调试避坑清单
6.1 博途装不上的环境级原因
热词里"博途v16安装教程"常年有人搜。安装这事难点不在安装包本身,而在环境。Windows 10专业版或企业版是首选,家庭版经常被警告;旧版博途或其它软件自带的SQL Server实例会占端口,装新版前最好把无关SQL服务停掉;杀毒软件的实时防护先关闭,不然.NET组件和权限文件可能被误删;安装路径不要带中文,Windows用户名也不要用中文。
很多"装不上"其实是路径和权限问题。重装前把注册表里的TIA Portal残留项和安装目录清理干净,再试一次,成功率能提高一大截。另外,博途版本之间不能混装,想保留V15又装V16,最好用虚拟机隔离,不然最容易出现各种莫名其妙的环境冲突。
6.2 VMware里的博途怎么连真机PLC
热词里"用vmware连plc用什么网络连接模式"问得特别多。虚拟机上跑博途连实体PLC,关键在网络模式:优先选"桥接模式",并且让虚拟网卡绑定到实际的以太网卡;不要用NAT,NAT相当于虚拟机躲在路由器后面,PLC根本找不到它。
如果PLC走的是Profibus DP,需要CP5611/CP5711这类通讯卡做USB或PCI透传,VMware对USB直通要单独选中正确的设备。连接前在控制面板的"设置PG/PC接口"里,把S7ONLINE的网卡选项指定到桥接出来的虚拟网卡,然后到博途在线访问里扫描"可访问的节点",基本就能搜到PLC。
6.3 PG/PC接口看不到网卡与仿真边界
"PG/PC接口无网卡选项"这个热词,基本是两种原因:要么没装SIMATIC NET或不带通讯驱动,要么权限不够。先把通讯驱动装全,再用管理员身份打开"设置PG/PC接口",就能看到网卡选项了。
PLCSIM仿真的边界刚才提到了,再补充一点:仿真时把变量表强制功能用起来,验证联锁尤其方便。但下载程序时要注意,仿真环境下下载的地址和实机如果有差异,在线监控会显示红色叉号,这时候优先检查项目组态里的CPU型号和固件版本。
6.4 现场IO调试的零散但重要提醒
最后把前面零散提到的现场经验归拢一下:
- SM331量程卡物理拨码和博途组态必须一致,这是AI调试第一坑;
- 屏蔽层单端接地,模拟量信号线不要和动力线同走一根槽;
- 4-20mA信号用信号发生器从端子处加信号,比在中控室短接快得多;
- 联锁试验前和工艺人员确认隔离要求,不要直接短接现场仪表信号;
- 下载程序前做一次完整备份,S7-300的老卡有时候下载中途掉站,会让人心态崩溃。
这套甲醛产线S7-300博途案例看完以后,我最有感触的一点是:一套程序能不能在产线上安稳跑十年,靠的不是某条指令用得花哨,而是结构、注释和联锁逻辑是否经得起维护工程师翻看。无论你是在抄这个案例的PID,还是在照猫画虎搭FB,都建议先打开变量表,把每个点的物理含义盯一眼,再去看程序块。
最后说个个人习惯:现在我做S7-300项目,哪怕工艺再简单,也一定单独建一个版本说明页,或者放一段文本块,记录V1.0、V1.1改了哪些联锁条件、为什么改。半年后再调这条线的时候,你会感谢自己留下的这几百字。