在西门子S7-1500/1200的梯形图(LAD)或函数块图(FBD)编程中,函数块(FB)的静态变量(Static)和临时变量(Temp)是每个工程师的必修课。然而,在实际工程中,由于对两者存储机制理解不透彻,常常引发难以排查的“幽灵故障”。本文通过一个废水处理厂的PH调节剂投加控制逻辑案例,揭示因变量使用不当导致的严重后果。
该案例中,工程师在FB内部使用了一个Temp变量作为“加药完成”的脉冲标志。在循环扫描周期内,该标志在逻辑上被置位,并在后续网络中被用于累加加药次数。然而,当程序扫描到该网络的下一周期时,Temp变量会立即失效(归零)。这导致累积计数值永远无法增加。更致命的是,如果某个中断组织块(OB)打断了该FB的执行,Temp变量在中断恢复后极大概率会变成随机值,导致电机误动作。此问题的根源在于Temp变量存储在L堆栈中,不具备保持功能。
正确的做法是使用FB的Static变量来记录跨周期的状态。但静态变量同样有陷阱:在博途(TIA Portal)中,Static变量具有“隐式锁存”特性。如果工程师在程序段中对Static变量进行了位操作(如XOR或SET/RESET组合),容易造成变量在断电重启后恢复为旧值。例如,我们用Static变量存储“手动/自动模式”切换状态,若在自动模式子程序中对它进行了清零操作,而手动模式子程序中也未做初始化,设备重启后可能直接进入错误模式。解决方案是在OB100(启动组织块)中对关键静态变量进行显式初始化,或者利用系统提供的“保持性”属性设置,确保非易失性存储区的数据是预期的。
此外,在SCL语言中,FB的Static变量与LAD中的行为一致,但Temp变量在SCL中若未初始化就读取,会直接导致程序崩溃或算数运算错误。我们在排查一个模糊PID温控程序时,发现Temp变量被用作累加器尚未清零,导致积分饱和。建议在每次FB调用开始时,对所有Temp变量执行复位操作(RESET指令或初始化赋值),并在程序结尾通过断言(Assert)机制检查关键Temp变量是否溢出。唯有如此,才能彻底摆脱变量生命周期引发的随机性故障。