博途(TIA Portal)是西门子推出的全集成自动化软件,涵盖PLC编程、HMI设计、驱动配置等功能。在实际工程项目中,程序运行难免遇到通信中断、数据越界、硬件故障等异常情况。若缺乏系统的错误处理机制,轻则导致设备停机,重则引发生产事故。本文从实际工程需求出发,系统讲解博途程序的错误处理与异常捕获方法。
一、错误类型与风险等级划分
博途项目中的错误可分为三类,需采取不同的处理策略。
| 错误类别 | 典型场景 | 处理原则 |
|---|---|---|
| 致命错误 | CPU进入STOP模式、循环时间超时、存储器故障 | 立即停机,人工排查 |
| 功能错误 | 通信中断、伺服报警、传感器信号异常 | 自动复位或切换至安全模式 |
| 警告信息 | 参数越限、非关键设备离线 | 记录日志,继续运行 |
评估项目风险等级时,需结合设备价值、生产节拍和安全规范。对于涉及人身安全的场景(如机器人工作站),任何异常都应触发急停回路。
二、组织块(OB)的异常捕获机制
S7-1200/1500 PLC通过组织块实现系统级错误处理。合理配置OB是构建容错程序的基础。
2.1 必配的组织块
创建以下OB文件,确保CPU在异常时保持RUN状态:
| OB编号 | 功能说明 | 触发条件 |
|---|---|---|
OB82 |
诊断中断 | 模块诊断状态变化 |
OB83 |
插拔中断 | 模块插入/移除 |
OB85 |
程序循环错误 | 访问缺失的OB/FC/FB |
OB86 |
机架故障 | 分布式IO站故障 |
OB100 |
启动组织块 | CPU从STOP→RUN |
操作路径:项目树 → 双击"程序块" → 点击"添加新块" → 选择"组织块" → 指定OB编号。
2.2 诊断OB的编程模板
以OB82为例,标准处理流程如下:
// OB82: 诊断中断处理
VAR_TEMP
slotInfo : Word; // 槽位信息
moduleState : Byte; // 模块状态
END_VAR
BEGIN
// 提取启动信息
slotInfo := OB82_MDL_ADDR; // 故障模块的起始地址
moduleState := OB82_MDL_TYPE; // 模块类型信息
// 写入诊断缓冲区
#diagnosticBuffer.write(
timestamp := RD_SYS_T(),
eventID := 16#55_82, // 自定义事件代码
info1 := slotInfo,
info2 := WORD_TO_BYTE(OB82_RACK_SLOT)
);
// 触发HMI报警
#hmiInterface.setAlarm(
alarmID := 2000 + BYTE_TO_INT(OB82_RACK_SLOT),
severity := 2 // 中等优先级
);
END
关键细节:OB82的启动信息仅在执行期间有效,必须立即读取并转存至全局变量或数据块。
三、程序代码层的防御性编程
系统OB只能捕获硬件和运行时错误,逻辑错误需在代码层面预防。
3.1 输入数据合法性检查
在功能块入口添加过滤器,防止无效数据进入运算环节:
// FB: 电机速度控制
VAR_INPUT
setSpeed : Real; // 设定转速 (rpm)
maxSpeed : Real := 3000.0; // 最大允许转速
enable : Bool;
END_VAR
VAR_OUTPUT
valid : Bool; // 输入数据有效标志
cmdSpeed : Real; // 输出至驱动的指令值
END_VAR
VAR
filteredSpeed : Real;
END_VAR
BEGIN
// 步骤1: 使能检查
IF NOT #enable THEN
#valid := FALSE;
#cmdSpeed := 0.0;
RETURN;
END_IF;
// 步骤2: 数值范围检查
IF #setSpeed < 0.0 OR #setSpeed > #maxSpeed THEN
#valid := FALSE;
#cmdSpeed := 0.0;
// 记录错误日志
#logError(errorCode := 16#8001,
detail := "速度设定越限");
RETURN;
END_IF;
// 步骤3: 变化率限制(防冲击)
#filteredSpeed := #rateLimiter(
input := #setSpeed,
maxDelta := 500.0 // 每秒最大变化500rpm
);
#valid := TRUE;
#cmdSpeed := #filteredSpeed;
END
3.2 除零与溢出防护
实数运算前执行零值检测,整数运算使用饱和处理:
// 安全除法函数
FUNCTION safeDivide : Real
VAR_INPUT
numerator : Real; // 分子
denominator : Real; // 分母
defaultVal : Real := 0.0; // 除零时的返回值
END_VAR
BEGIN
IF ABS(#denominator) < 1.0E-6 THEN
safeDivide := #defaultVal;
// 可选:设置错误标志位
ELSE
safeDivide := #numerator / #denominator;
END_IF;
END_FUNCTION
// 整数饱和加法(防止溢出)
FUNCTION satAddInt : Int
VAR_INPUT
a, b : Int;
END_VAR
VAR_TEMP
sum : DInt;
END_VAR
BEGIN
#sum := INT_TO_DINT(#a) + INT_TO_DINT(#b);
IF #sum > 32767 THEN
satAddInt := 32767; // 正饱和
ELSIF #sum < -32768 THEN
satAddInt := -32768; // 负饱和
ELSE
satAddInt := DINT_TO_INT(#sum);
END_IF;
END_FUNCTION
四、通信错误的自动恢复
工业现场中,PROFINET、Modbus TCP等通信链路易受电磁干扰。设计"自愈"机制可显著提升系统可用性。
4.1 通信状态机设计
采用状态机管理通信生命周期,实现故障自动重连:
4.2 SCL实现代码
// FB: TCP客户端通信管理
TYPE
CommState : (IDLE, CONNECTING, RUNNING, ERROR_WAIT, STOPPING);
END_TYPE
VAR
state : CommState := IDLE;
retryTimer : TON;
retryCount : Int;
maxRetries : Int := 3;
retryDelay : Time := T#5S;
END_VAR
BEGIN
CASE #state OF
IDLE:
IF #startReq THEN
#state := CONNECTING;
#tsapConnect.remoteIP := #targetIP;
#tsapConnect.remotePort := #targetPort;
#tsapConnect.execute := TRUE;
END_IF;
CONNECTING:
#tsapConnect.execute := TRUE;
IF #tsapConnect.done THEN
#state := RUNNING;
#retryCount := 0;
#tsapSend.execute := TRUE; // 启动数据交换
ELSIF #tsapConnect.error THEN
#state := ERROR_WAIT;
#retryTimer(IN := TRUE, PT := #retryDelay);
IF #retryCount >= #maxRetries THEN
#fatalError := TRUE;
#state := IDLE;
END_IF;
END_IF;
RUNNING:
#tsapSend.execute := TRUE;
#tsapReceive.execute := TRUE;
// 检测通信中断
IF #tsapSend.error OR #tsapReceive.error
OR NOT #tsapConnect.connected THEN
#state := ERROR_WAIT;
#retryTimer(IN := TRUE, PT := #retryDelay);
END_IF;
ERROR_WAIT:
#retryTimer(IN := TRUE);
IF #retryTimer.Q THEN
#retryTimer(IN := FALSE);
#retryCount := #retryCount + 1;
#state := CONNECTING;
#tsapConnect.execute := FALSE; // 复位连接块
END_IF;
IF #stopReq THEN
#state := IDLE;
#retryTimer(IN := FALSE);
END_IF;
END_CASE;
// 背景调用通信功能块
#tsapConnect();
#tsapSend();
#tsapReceive();
END
关键参数:retryDelay建议设为通信超时时间的2-3倍,避免过快重试导致网络拥塞。
五、诊断缓冲区的深度应用
诊断缓冲区是排查间歇性故障的核心工具。合理设计自定义诊断信息,可将平均故障修复时间(MTTR)降低60%以上。
5.1 标准诊断数据结构
// 全局数据块: DiagnosticBuffer
TYPE
DiagEntry : STRUCT
timestamp : Date_And_Time; // 事件发生时刻
eventCode : Word; // 分类编码
sourceBlock : String[16]; // 来源FB/FC名称
lineNumber : UInt; // 代码行号(SCL)
param1 : DWord; // 上下文参数1
param2 : DWord; // 上下文参数2
END_STRUCT;
END_TYPE
VAR
entries : Array[0..99] of DiagEntry; // 循环缓冲区
writeIndex : Int := 0;
overflowCount : UDInt := 0;
END_VAR
5.2 日志写入函数
FUNCTION writeDiag : Void
VAR_INPUT
eventCode : Word;
param1 : DWord := 0;
param2 : DWord := 0;
END_VAR
VAR_TEMP
callerInfo : Block_FC_C;
END_VAR
BEGIN
// 获取调用者信息(S7-1500支持)
GET_INSTRUCTIONS(CODE := callerInfo);
// 写入当前槽位
"DiagnosticBuffer".entries["DiagnosticBuffer".writeIndex] :=
(timestamp := RD_SYS_T(),
eventCode := #eventCode,
sourceBlock := #callerInfo.BLOCK_NAME,
lineNumber := #callerInfo.LINE_NUMBER,
param1 := #param1,
param2 := #param2);
// 更新索引
"DiagnosticBuffer".writeIndex :=
("DiagnosticBuffer".writeIndex + 1) MOD 100;
// 检测溢出
IF "DiagnosticBuffer".writeIndex = 0 THEN
"DiagnosticBuffer".overflowCount :=
"DiagnosticBuffer".overflowCount + 1;
END_IF;
END_FUNCTION
5.3 与HMI的集成
在WinCC或精智面板中,配置诊断视图控件,绑定数据块数组。启用时间筛选功能,允许操作员按时间段检索历史报警。
六、安全相关的故障处理
涉及安全功能(急停、安全门、光幕)的程序,必须遵循EN ISO 13849或IEC 62061标准。
6.1 安全程序与普通程序的隔离
| 项目 | 安全程序(F-CPU) | 标准程序 |
|---|---|---|
| 编程语言 | F-LAD/F-FBD(有限制) | 全部语言 |
| 数据类型 | F-BOOL/F-INT等 | 全部类型 |
| 故障反应 | 强制进入安全状态 | 可配置 |
| 认证要求 | 需TÜV等第三方认证 | 自行测试 |
关键原则:安全功能不得依赖标准程序的计算结果。标准程序可读取安全状态,但不能覆盖安全输出。
6.2 F-CPU的集体安全签名
每次修改安全程序后,必须执行"一致性检查"并记录安全签名(Collective F-Signature)。该签名是安全审计的法定依据。
七、调试与验证方法
完善的错误处理机制需经过系统性验证。
7.1 故障注入测试清单
| 测试项 | 注入方法 | 预期行为 |
|---|---|---|
| 通信中断 | 断开网线/关闭交换机端口 | 状态机转入ERROR_WAIT,HMI显示特定报警 |
| 模块故障 | 拔出分布式IO模块 | OB82触发,程序切换至降级模式 |
| 数据越界 | 强制写入超范围设定值 | 输入过滤器阻断,记录诊断日志 |
| 循环时间超时 | 插入大量空循环 | OB80触发,CPU保持RUN(若已配置) |
| 电源波动 | 使用可调电源模拟欠压 | 电源模块诊断位变化,触发预警 |
7.2 在线诊断工具的使用
打开"在线与诊断"视图,掌握以下功能:
- 模块状态:查看所有硬件的LED状态模拟图
- 诊断缓冲区:按时间顺序浏览系统事件
- 分配列表:检查IO地址冲突
- 交叉引用:追踪变量在程序中的使用情况
- 比较功能:离线与在线程序的差异分析
八、性能优化注意事项
过度复杂的错误处理可能拖累扫描周期。遵循以下准则:
限制每个OB82/OB83的执行时间,超过5ms的诊断操作移至循环中断OB(如OB35)异步执行。
避免在故障处理程序中调用通信功能块,防止错误级联。
评估诊断缓冲区的写入频率,高频场景(如每秒超过10次)改用采样记录而非全量记录。
监控PLC的循环时间负荷率,保持在60%以下以预留故障处理的计算余量。
博途的错误处理体系涵盖硬件配置、程序架构和运维工具三个层面。建议从项目初期即规划诊断策略,而非事后补丁式添加。建立统一的错误编码规范、设计可复用的诊断功能块、训练运维人员解读诊断信息,三者结合方能构建真正可靠的自动化系统。

暂无评论,快来抢沙发吧!