
简介西门子S300系列可编程控制器水处理程序源码包是一份面向工业自动化工程师和PLC编程学习者的完整项目示例程序围绕水质监测、过滤消毒、pH值调节、流量控制等工艺环节展示从I/O配置、梯形图逻辑到定时计数、故障报警的整套控制思路。压缩包共344个文件大小约518KB内部以S7项目源文件、数据库表、工程配置和说明文档为主同时包含索引、临时文件与锁存记录基本还原了Step7项目目录全貌。代码覆盖输入输出地址分配、控制逻辑、定时与计数、故障诊断与报警、上位机通信及关键参数存储等模块便于逐段对照学习也有助于理解实际水处理系统的自动控制流程。工程带有实际运行痕迹并保留了历史数据库与趋势记录读者既可学到标准编程习惯与排错思路也可直接作为同类项目二次开发或教学演示的参考蓝本。目前已有156人学习浏览适合需要从完整实例入手、快速掌握西门子S300水处理程序架构与控制逻辑的工程师和学员。1. 一份S7-300水处理源码的核心价值不在梯形图里先说结论这类 S300 水处理源码包解压后直接灌进 PLC 跑的概率几乎为零。硬件型号、模块地址、量程单位全跟你现场不一样轻则输入映射错乱重则加药泵和反洗阀在错时间动作。值得复用的是三样东西程序骨架、泵阀对象封装方式、DB 里的工艺时序参数。水处理的特点是模拟量密度高、泵阀连锁多、时间程序长一个液位回差写错就能让两台提升泵频繁切换。S7-300 旧项目多用 STEP 7 V5.x 编写由 OB、FB、FC、DB 构成与 S7-1500 的工程结构不同但工艺逻辑可以迁移。下文按读包顺序走程序组织、软件还原、点表重映射、参数调整与验证。适合同行看包移植也适合刚接触西门子PLC编程的人理解一个真实项目该怎么拆。2. S7-300水处理程序的骨架OB调度、DB数据与泵阀封装S7-300 没有 main 函数程序入口是 OB1其它逻辑靠事件触发。理解一个旧水处理项目不要先翻梯形图而是先把组织块和背景 DB 清单拉出来。OB 分布能直接看出工艺被切成几段、哪些逻辑按固定周期跑、哪些按日历时间跑这是和老项目建立对话的第一张地图。2.1 先拉 OB 清单循环扫描之外水处理靠中断块定节奏水处理程序里时间相关逻辑占大头定时加药、间歇反洗、沉淀延时。全塞进 OB1 里扫描周期一变所有定时全漂。常见做法是让 OB1 只做模式切换和状态机推进把固定周期的调节放进 OB35把跨天跨周的时序放进 OB10~OB17 日期时间中断。OB号触发方式水处理中的典型用途OB1循环扫描主状态机、泵阀连锁、自动/手动模式选择OB35固定循环中断默认100msPID调节、模拟量采样与滤波OB10~OB17日期时间中断定时加药、滤池轮换、夜间低水位切泵OB82诊断中断I/O 模块故障登记OB86机架故障分布式从站掉线报警OB100暖启动工艺初始状态、DB 初值重写打开项目后先在左侧树里数一下有没有 OB35、OB82、OB86这决定后面调整参数时该去哪里找代码。OB35 里调用块多时要留意执行时间OB35 的中断周期默认 100ms如果中断程序本身执行时间超过了 100ms系统会报循环中断错误而不是等你发现 PID 没输出。我见过一个项目因为 PID 回路太多导致 OB35 超时处理办法是把循环中断时间从 100ms 改到 200ms代价是调节周期变长。加药回路可以接受流量反馈回路就不行改之前要想清楚。2.2 泵阀封装FBUDT多重背景是S7-300时代的对象编程水处理程序里大量重复“启动—反馈—故障—停机”逻辑。写得好的项目一般用 FB 配合 UDT用户自定义数据类型做封装把一台泵的所有输入输出和参数打包进 UDT一个 FB 只处理一台泵每台泵给一个背景 DB 实例。这样加药泵从 2 台扩到 4 台时不用复制十几行梯形图多建两个 DB 实例把参数写上就行。UDT 定义如下TYPE UDT_Pump STRUCT Auto : BOOL; // 自动模式使能 Cmd : BOOL; // 启动指令来自面板或上位机 Fault : BOOL; // 综合保护输入 RunFb : BOOL; // 接触器反馈触点 StartDly : TIME; // 启动确认窗口 Alarm : BOOL; // 泵故障汇总输出给HMI END_STRUCT END_TYPE对应的泵控制 FB 骨架FUNCTION_BLOCK FB_Pump VAR_IN_OUT p : UDT_Pump; // 泵对象IN_OUT保证可读可写 END_VAR VAR ton_Fb : TON; // 启动反馈监视定时器 END_VAR // 自动模式下启动条件成立且无故障置位输出 IF p.Auto AND p.Cmd AND NOT p.Fault THEN p.Alarm : FALSE; ton_Fb(IN : TRUE, PT : p.StartDly); IF NOT p.RunFb AND ton_Fb.Q THEN p.Alarm : TRUE; // 启动后反馈没跟上判定故障 END_IF; ELSE ton_Fb(IN : FALSE); p.Alarm : p.Fault; // 故障直接透传 END_IF;逻辑说明这段不是某个项目里的真实代码只是把 S7-300 老项目里最常见的泵逻辑还原成可读形式。Fault透传给Alarm是为了让手动模式下故障也能被上位机看到。改别人程序时最容易犯的错就是把这句“故障透传”当成多余逻辑删掉结果现场故障时 HMI 上没有任何提示。TON 是 S7-300 标准定时器背景数据保存在实例 DB 里多次调用互不干扰。StartDly一般设 2~5 秒取决于接触器和电机启动时间RunFb接的是接触器辅助触点不是电流信号反映不了过载。如果现场用电机综合保护器的常闭触点做Fault注意别把它串在接触器控制回路里否则故障时接触器先分断PLC 里根本看不到Fault变化。2.3 模拟量三段式标定、滤波、限幅水处理信号 4-20mA 进入 SM331 后是 0~27648 的整数S7-300 标准库里的 FC105 完成量程转换。调用方式CALL FC105 IN : IW64 // SM331模块的通道输入字 HI_LIM : 10.0 // 液位变送器满量程单位米 LO_LIM : 0.0 // 量程下限 BIPOLAR : FALSE // 单极性4-20mA RET_VAL : #ErrorCode // 16位状态字 OUT : LT_PoolLvl // 工程值实数参数说明IN是模拟量模块的原始值HI_LIM/LO_LIM对应变送器的实际量程OUT是换算后的工程量。RET_VAL非零时必须去查 FC105 的错误代码表不能直接忽略。单极性接 4-20mA 时BIPOLAR必须为 FALSE设成 TRUE 后量程下一半都是无效区。FC105 之后的滤波我一般放在 OB35 里做一阶惯性不用单独写 PID 块// OB35中0.5为按采样周期折算的滤波系数 LT_PoolLvl_Filter : LT_PoolLvl_Filter 0.5 * (LT_PoolLvl - LT_PoolLvl_Filter);水处理的 PID 大多用在加药回路上响应以分钟计不建议第一次投运就切自动。先手动观察余氯或 pH 曲线稳定后再让 FB41 输出叠加在手动频率上比例带从较大的值开始往下压。FB41 的CYCLE参数必须和 OB35 实际中断周期一致这是旧项目里最常见的参数错位。另一个坑是 FB41 输出是 0~100.0 的百分比变频器可能接收 0~16384 的 16 位输出格式中间必须再做一次量程映射不能直接接到 PQW。pH 调节是典型非线性环节5~7 和 7~9 两个区间的对象特性完全不同源程序里如果按“加酸/加碱”拆了两个 FB41那是工艺需要不是冗余。3. 打开与还原STEP 7 与 TIA Portal 读取 S300 源码包的姿势拿到 zip 先别双击。先分清是 STEP 7 归档文件还是普通项目文件夹这决定你用哪个软件、走哪条流程。错误打开方式会破坏项目结构我见过有人用“打开项目”去开后缀是 zip 的归档文件弹出一句“不是有效项目”就以为文件损坏了。3.1 用命令行确认压缩包内容S7 归档与项目目录的判别老 S7-300 压缩包常见两种一种是 V5.x 的归档文件内部有SIMATIC/相关目录另一种是项目文件夹的直接打包。先列一下内容7z l 水处理程序S300.zip | head -60输出如果出现SIMATIC/或项目名目录下有S7Proj/说明是 V5.x 归档。这时在 SIMATIC Manager 里用File Retrieve恢复而不是File Open。Retrieve会把项目解到指定路径并重建辅助文件Open打不进去。反过来如果 zip 解开就是一个带.plc目录的 TIA 项目直接在 TIA Portal 里用项目 打开选那个目录即可。中文 Windows 下解压老项目经常遇到文件名乱码。Linux/macOS 下用 unzip 时加参数unzip -O GBK 水处理程序S300.zip -d s300_srcWindows 上有乱码时用 Bandizip 选“自动检测编码”再解压。这一步不解决项目内部引用关系但至少能让你看懂文件名。归档恢复时报“路径太长”的话把目标目录放到C:\S7Proj这类短路径下不要用带空格的深层目录。3.2 版本血缘哪些版本能开哪些必须移植S7-300 在 STEP 7 V5.x 和 TIA Portal 里都能编程但项目文件不通用。常见链路V5.4/V5.5/V5.6 项目在 TIA 里用“项目 移植项目”导入导入后可以下载到 S7-300更老的 V5.2 项目先拿对应 V5 版本打开另存为高版本再进 TIA直接移植容易丢符号。TIA 版本低时打开高版本 V5 归档会报“无法读取项目数据”。我一般先确认当前 TIA 版本是否能新建 S7-300 项目能新建才去尝试移植。老项目很多用到标准库里的 PID 块移植后 TIA 库版本对不上FB41、FC105 还在但接口可能变成CONT_C风格。移植前先在 V5 里把所有 FB/FC/DB 打开并编译一遍确认无错误再移植。移植后逐个打开 FB 看变量注释是不是变成问号如果变了说明源程序的中文符号在编码转换中损坏。处理办法是把这个块单独导出再导入一次而不是在移植后手工改变量名。源项目状态推荐打开方式遇到问题时的处理V5.4 项目归档SIMATIC Manager Retrieve再用 V5.4 打开升级到 V5.6 后另存V5.5 项目TIA V13 SP1 及以上版本移植移植前在 V5 里编译检查TIA V14/V15 项目TIA 对应版本直接打开用“项目 升级”逐级升纯 DB 导出 txtExcel 或 Notepad 查看保留 ANSI 和 UTF-8 两种编码比较3.3 打开后先做三件事核对硬件组态、导出符号表、刷新交叉引用打开项目不要急着读梯形图。第一件事打开 HW Config 对照 CPU 型号与机架模块清单。水处理旧项目很多用 315-2DP 带 ET200 分布式从站。如果现场模块比组态少一张 AI 卡下载会报“模块不存在”这是组态问题不是程序问题删掉多余模块再下载通常不影响逻辑。第二件事把符号表导出成 CSV 检查点表完整性。在符号表窗口右键“导出”格式选“电子表格CSV”。老项目符号表的中文注释在 Excel 里显示乱码时改导入编码为 ANSI。如果符号表几乎为空说明源码在流传过程中被清理过后面只能按绝对地址读程序工作量会大很多。第三件事用“参考数据 分配列表”查看 I/Q/M 地址的使用密度。水处理程序最常见的隐患是 M 区地址复用一个工位用 M50.0 做“加药泵1自动”另一段程序又把 M50.0 当“反洗正在运行”的中间位。PLC 不会报错运行时动作却互相覆盖。交叉引用能直接看到同一个 M 位被哪些块读写这是判断源码是否被多人改过的快速途径。4. 从源码到自己的工艺点表核对、地址重映射与参数调整程序能打开之后重点就是“这一个包”怎么变成“你这一个现场”。水处理工艺差异大但源码改造路径可以固定成三步先核对点表再改地址映射最后调整时序和 PID 参数。4.1 先核对点表符号表才是程序的地基S7-300 在符号寻址模式下FB/FC 里写的是符号名真实地址放在符号表里。所以改造顺序是改符号表地址而不是在梯形图里挨个找 I/Q 编号。我一般先做一张核对表把原地址、新地址、设备位号、信号说明列在一起。点表序号符号名原地址新地址数据类型设备与位置信号说明是否复用1原水液位LT-101IW64IW256INT原水箱液位变送器4-20mA0-10m保留2提升泵P-101运行反馈I0.0I2.0BOOL1号提升泵接触器辅助触点替换更新符号表时注意新地址是否与原有地址重叠。原程序用了 IW64~IW66 三路模拟量换成 IW256~IW258 时要确认 IW258 没有被下一张模拟量模块占用。SM331 每通道占一个字地址从偶数开始不能从奇数地址编排模拟量通道。符号表改完之后在 SIMATIC Manager 里右键 PLC 程序选择“编译 软件重置”把所有块重新生成一遍。不编译的话下载的仍然可能是旧的引用关系在线监视时输入点全对不上。4.2 工艺段修改轮换控制与反洗时序怎么改水处理常见的几段逻辑提升泵轮换、过滤器反洗、加药联动、沉淀池排泥。老程序里最值得保留的是轮换和反洗这两段顺控。如果只是设备编号不同建议保留顺控骨架只改设备号映射如果工艺段本身不一样不要试图在原程序上改出第二套逻辑直接新写一个 FC把原 FC 的调用条件屏蔽掉。轮换切泵的简化骨架FUNCTION FC_Rotate : BOOL VAR_INPUT b_Enable : BOOL; // 轮换使能 i_CurPump : INT; // 当前运行泵编号 1/2/3 b_Req : BOOL; // 需要切换 END_VAR VAR_OUTPUT i_NextPump : INT; // 下一台泵编号 END_VAR IF b_Enable AND b_Req THEN IF i_CurPump 3 THEN i_NextPump : 1; ELSE i_NextPump : i_CurPump 1; END_IF; ELSE i_NextPump : i_CurPump; END_IF; FC_Rotate : TRUE;逻辑说明这个骨架只演示递增轮换实际项目要加“优先启动可用泵”的判断。某台泵处于故障状态时要先跳到下一台泵再启动而不是等泵 FB 把泵停了才轮换否则会有一次无效切换。i_CurPump定义成 INT 是为方便 HMI 显示但要注意 S7-300 的 INT 是 16 位有符号数范围 -32768~32767HMI 上数值回绕显示负数会吓到操作工。现场设备超过 10 台时建议改用 DINT 或把编号拆成两个字节处理。反洗时序改造要特别留意“步进条件”。老程序常用一组 M 位表示“气洗中、水洗中、等待中”然后用定时器到点跳步。改造时先把跳步条件列成一张表确认每一步的进入条件和退出条件再决定是沿用定时器还是改成用实时钟计算累计时长。4.3 定时器与扫描周期旧程序里最隐蔽的坑S7-300 的定时器资源是全局的按 CPU 型号有 128 或 256 个。梯形图里两段网络用了同一个 T 号后调用的逻辑会重置定时器状态前一段的计时结果在下一轮扫描里被覆盖。旧项目经过多人修改后T 号复用非常普遍。处理办法是在交叉引用里按定时器排序找重复项把冲突的定时器改成 IEC 定时器。S7-300 里 IEC TON 是 SFB4实例用一个 DB不再占用全局 T 号多个调用互不影响。水处理里的长时间定时比如滤池“气洗 5 分钟、水洗 10 分钟”不要用 T 定时器累加因为显示不了剩余时间。常见做法是用 OB10 记录“本次反洗开始时刻”拿当前时刻减开始时刻得到累计时长。S7-300 用 SFC1 READ_CLK 读取时钟返回 DATE_AND_TIME 格式。注意这个格式是 BCD 编码要先做字节转换得到可计算的时间差不能把 8 个字节当整数直接相减。HMI 上要显示“剩余 xx 秒”时用这个时长减去设定的总时间。PID 参数不要从默认值开始整定。源码的 FB41 背景 DB 里通常有别人的整定值抄那个值作为初始值更靠谱。水处理加药回路的工程起点参考回路作用方向P/增益I/积分时间D输出上限%备注pH加酸反向1.0~2.05~10 分钟080输出指向加酸泵变频器余氯反向0.88~15 分钟060余氯波动大积分不能太小浊度正向0.510 分钟0100通常开环运行PID 只做后备投自动前先手动固定频率观察 pH 从启动到稳定的响应时间。响应大约 3 分钟时积分时间给 5~10 分钟P 从 1.0 开始加倍试。若输出振荡且周期长先加大积分时间而不是减小 P这是最常见的方向性错误。5. 验证与进阶PLCSIM 强制输入、交叉引用阅读与向 S7-1500 迁移的边界5.1 用 PLCSIM 把整套程序跑起来的三步硬件组态和程序编译通过后在 SIMATIC Manager 里启动 PLCSIM下载对象选“整个项目”勾选硬件组态一起下载。打开变量表VAT把输入字强制成现场信号。比如原水液位IW64 : 5000对应约 1.8 米再把液位下限原水液位低 : TRUE强制进去观察提升泵是否按逻辑启动。PLCSIM 能跑状态机但模拟量输入断线诊断、高速计数和部分通讯报错是仿真不了的。程序里如果用了 OB82 做诊断仿真时不会触发需要在变量表里人为把报警寄存器位置位才能验证 HMI 画面上的故障文字是否显示。5.2 用交叉引用读程序别顺着 OB1 一行行读几十个块顺着扫描顺序读效率太低。更快的方式是用参考数据导出的地址分布列表把 M 区和 DB 位里“只写不读”“只读不写”的地址筛出来。“只写不读”的中间位多半是调试遗留删掉能让程序更清晰“只读不写”的 DB 位来源是 HMI 写入或上位机通讯这一类的符号不要动否则 HMI 的变量连接也要跟着改。这个筛选动作在移植老项目时能省下大量排查时间。5.3 向 S7-1500 迁移时能搬什么、不能搬什么S7-300 的 OB35、FB41、FC105 在 S7-1500 里有对应但不等价的新版本OB35 变成循环中断 OBFB41 对应 PID_Compact 或 PID_3StepFC105 可以用 NORM_X/SCALE_X 指令替代。直接把 S7-300 块复制到 S7-1500 项目会报不兼容。迁移时建议搬三层UDT 和符号表原样保留泵阀对象 FB 用 SCL 重写OB35 调用逻辑重排不搬的是通讯功能块和硬件诊断块因为接口体系完全不同。循环中断时间在 S7-1500 里可以设到 10ms 以下但如果源程序的工艺节拍以秒计保持 100ms 也够用没必要为了指标去压周期。如果你拿到的是带 HMI 画面的完整包下一步先在 HMI 变量表里按通讯连接过滤出 PLC 变量和更新后的 PLC 符号表做一次变量同步然后启动 PLCSIM 与 WinCC Runtime Advanced 联合仿真验证画面上的启停按钮和指示灯是否对应到正确的 DB 位排除符号表改名后 HMI 连接丢失的问题。本文还有配套的精品资源点击获取