1. 项目概述:洁净空调控制系统的结构化编程实践
这套基于WinCC 7.5和博途V16的洁净空调控制系统项目,是我在医药厂房自动化改造中的实战成果。不同于教学演示项目,这套系统已经连续稳定运行超过8000小时,处理过各种极端工况下的设备联动控制。整个项目最突出的特点是将复杂的空调系统逻辑拆解为23个标准化功能块,每个功能块都对应着WinCC画面上的具体操作元素。
在洁净厂房环境中,空调系统不仅要维持恒温恒湿,还需要确保空气洁净度达到GMP要求的ISO 5级标准。这就意味着控制系统需要同时处理:
- 变频风机的PID调节(精度±0.5Hz)
- 表冷阀的开度控制(调节粒度1%)
- 三级过滤器的压差监测(响应时间<200ms)
- 房间压差梯度维持(偏差<5Pa)
项目采用结构化编程的最大优势在于,当某个功能需要修改时(比如调整风机启动曲线),只需修改对应的FB块,所有调用该块的实例都会自动更新。这种"一次修改,全局生效"的特性,在维护阶段节省了大量调试时间。
2. 系统架构设计解析
2.1 硬件组态方案
控制系统采用西门子S7-1500系列PLC(具体型号为CPU 1516-3 PN/DP)作为主控制器,通过PROFINET网络连接:
- 4台G120变频器(驱动送/回风机)
- 16个ET200SP分布式IO站(采集256个DI/128个DO)
- 12台SITRANS TF201温湿度变送器
- 8台MAG5000流量传感器
WinCC运行在工控机(配置:i5-8500/8GB/256GB SSD)上,通过工业交换机与PLC建立S7连接。网络配置中特别需要注意TSAP地址的设置:
- PLC端TSAP: 03.02
- WinCC端TSAP: 03.01
- 连接超时设置为1500ms(考虑PROFINET的实时性要求)
2.2 软件架构设计
博途项目中采用模块化编程结构:
code复制├─OB1(主循环)
│ ├─FC100 设备状态扫描
│ ├─FC101 报警处理
│ ├─FC102 模式切换
├─OB35(循环中断100ms)
│ ├─FC200 模拟量处理
│ ├─FC201 PID运算
├─DB块
│ ├─DB1 系统参数
│ ├─DB2 设备状态
│ ├─DB3-10 各子系统数据
└─FB块
├─FB1 风机控制
├─FB2 阀门控制
├─FB3 过滤器监控
这种架构确保了:
- 周期任务(如PID运算)在OB35中稳定执行
- 非实时逻辑在OB1中顺序处理
- 每个设备类型有独立的数据块
3. 核心功能实现细节
3.1 风机控制逻辑实现
以AHU1送风机为例,其FB块(FB1)包含完整的控制链:
ST复制FUNCTION_BLOCK "AHU_Control"
VAR_INPUT
AutoMode : Bool;
StartCmd : Bool;
StopCmd : Bool;
FrequencySetpoint : Real;
END_VAR
VAR_OUTPUT
RunStatus : Bool;
ActualFrequency : Real;
FaultCode : Word;
END_VAR
VAR
tStartDelay : TON;
tStopDelay : TON;
ramp : RAMP;
END_VAR
// 启动逻辑
IF AutoMode AND StartCmd THEN
tStartDelay(IN := TRUE, PT := T#30S);
IF tStartDelay.Q THEN
ramp(
EN := TRUE,
START := TRUE,
STOP := FALSE,
RATE := 10.0, // 10Hz/s变化率
PV := FrequencySetpoint,
CV => ActualFrequency);
RunStatus := TRUE;
END_IF;
ELSE
ramp.STOP := TRUE;
RunStatus := FALSE;
END_IF;
关键设计要点:
- 使用RAMP功能块实现频率斜坡给定,避免直接阶跃变化
- 启动/停止分别设置30秒延时,防止频繁启停
- 运行状态与频率输出分离,方便HMI状态显示
3.2 温湿度PID控制
在OB35中调用PID_Compact指令处理温湿度控制:
ST复制// 温度控制回路
"PID_Temp"(
Setpoint := "DB_Param".TempSP,
Input := "AI1".Temperature,
Output => "AQ1".HeatingValve,
Config := "PID_Temp_Param");
// 湿度控制回路
"PID_Hum"(
Setpoint := "DB_Param".HumSP,
Input := "AI1".Humidity,
Output => "AQ1".Humidifier,
Config := "PID_Hum_Param");
参数整定经验:
- 温度回路:P=2.5, I=60s, D=0(惯性大系统)
- 湿度回路:P=1.8, I=120s, D=5s(快速响应)
- 采样周期统一为100ms(OB35周期)
3.3 过滤器压差监控
使用UDT定义过滤器数据结构:
ST复制TYPE "FilterData" :
STRUCT
PressureDiff : REAL; // 当前压差
AlarmThreshold : REAL := 150.0; // Pa
PreAlarmThreshold : REAL := 120.0;
LastCleanTime : DT;
END_STRUCT
END_TYPE
报警处理逻辑包含:
- 两级报警(预警和严重报警)
- 自锁功能,需手动复位
- 清洁时间记录
4. WinCC人机界面设计技巧
4.1 画面布局规范
采用"三区式"布局:
code复制+-----------------------+
| 顶部:系统状态栏 |
| 显示时间、模式、报警 |
+-----------+-----------+
| 左侧 | 右侧 |
| 导航树 | 动态内容 |
| 设备分组 | 工艺流程图|
+-----------+-----------+
每个区域使用不同的背景色(RAL定义):
- 状态栏:RAL 7035(浅灰)
- 导航区:RAL 7040(深灰)
- 工作区:RAL 9016(纯白)
4.2 动态元素实现
以阀门开度显示为例,使用C脚本实现动画效果:
C复制void OnLButtonDown(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName, UINT nFlags, int x, int y)
{
#define TAG "PLC1.AQ1.ValveOpen"
float fValue = GetTagFloat(TAG);
SetTagFloat(TAG, fValue > 0 ? 0 : 100);
UpdatePicture();
}
4.3 报警系统配置
在WinCC Alarm Control中配置:
-
消息等级划分:
- 16-19:预警(黄色)
- 20-23:一般报警(橙色)
- 24-31:严重报警(红色)
-
添加报警文本时使用变量替换:
"过滤器%1压差超标!当前值:%2 Pa"
(%1对应过滤器编号,%2对应当前值)
5. 项目调试与优化经验
5.1 仿真测试步骤
-
使用PLCSIM Advanced建立虚拟PLC
bat复制PLCSIM_Advanced.exe /Instance:1 /Port:1024 /Lifetime:0 -
WinCC连接配置修改:
- 将"TCP/IP"改为"PLCSIM Virtual Eth Adapter"
- 保持TSAP设置不变
-
强制测试信号技巧:
ST复制// 在OB1开头添加测试代码 IF "TestMode" THEN "AI1".Temperature := 22.5 + SIN(TIME()/1000) * 2; END_IF;
5.2 现场调试问题汇总
常见问题及解决方法:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| HMI响应慢 | 网络负载高 | 1. 优化S7通信周期 2. 减少非必要变量刷新 |
| 阀门振荡 | PID参数不当 | 1. 降低P增益 2. 增加滤波时间 |
| 通讯中断 | TSAP不匹配 | 1. 检查PLC和WinCC的TSAP设置 2. 确认PG/PC接口设置 |
5.3 性能优化措施
-
程序优化:
- 将周期任务移到OB35(100ms)
- 使用"Optimized"块访问模式
- 避免在循环中使用间接寻址
-
HMI优化:
- 将频繁更新的变量分组到同一周期
- 禁用非活动画面的变量更新
- 使用智能对象替代基本图形
6. 结构化编程的最佳实践
6.1 功能块设计规范
-
命名规则:
- 前缀表示功能类型(FB_AHU_表示空调机组)
- 动词+名词结构(如FB_AHU_StartSequence)
-
接口定义原则:
- IN参数:只读,由调用方提供
- OUT参数:只写,供调用方使用
- STATIC变量:块内部状态保持
-
典型功能块模板:
ST复制FUNCTION_BLOCK "FB_Template"
VAR_INPUT
bEnable : Bool;
rSetpoint : Real;
END_VAR
VAR_OUTPUT
rActualValue : Real;
wErrorCode : Word;
END_VAR
VAR
// 内部变量按功能分组
// 1. 定时器相关
tDelay : TON;
// 2. 运算中间量
rTemp : Real;
END_VAR
// 主逻辑分为清晰段落
// 段落1:使能控制
IF NOT bEnable THEN
RETURN;
END_IF;
// 段落2:核心算法
rTemp := rSetpoint * 0.8;
// 段落3:输出处理
rActualValue := LIMIT(0.0, 100.0, rTemp);
6.2 数据块管理策略
-
全局数据块规划:
- DB1:系统参数(设定值、模式等)
- DB2:设备状态(运行、故障等)
- DB3-DB20:各子系统数据
-
使用UDT统一数据结构:
ST复制TYPE "MotorData" :
STRUCT
bRunning : Bool;
bFault : Bool;
rCurrent : Real;
rSpeed : Real;
END_STRUCT
END_TYPE
- 优化访问方式:
- 优先使用"Symbolic access"
- 复杂结构使用"BLKMOV"复制
- 避免直接访问绝对地址
6.3 异常处理机制
-
标准错误代码定义:
- 0x0000:无错误
- 0x1xxx:传感器故障
- 0x2xxx:执行器故障
- 0x3xxx:通讯故障
-
错误处理函数块示例:
ST复制FUNCTION "FC_ErrorHandler" : Void
VAR_INPUT
wErrorCode : Word;
END_VAR
VAR_TEMP
iErrorType : Int;
END_VAR
iErrorType := wErrorCode SHR 12;
CASE iErrorType OF
1: // 传感器故障
"DB_Alarm".bSensorFault := TRUE;
2: // 执行器故障
"DB_Alarm".bActuatorFault := TRUE;
END_CASE;
这套洁净空调控制项目经过三年实际运行验证,最宝贵的经验是:结构化编程不是简单的代码拆分,而是建立清晰的设备控制模型。每个FB块都应对应一个物理设备或明确的功能单元,同时保持适度的粒度——太细会增加调用复杂度,太粗则失去复用价值。在移植到新项目时,通常可以复用约70%的功能块,只需重新配置硬件地址和调整部分参数即可快速部署。