急停的判定
急停判定的作用是:在急停常闭中断时,输出急停激活信号,且在按下复位按钮之前,保持急停状态不变。
这意味着我们要记忆状态,但是IEC61131-3
标准Function
是无状态的,而且也不接受指针、引用作为参数。
方法一自然是使用Function_Block
,但是为这个简单的功能建一个FB
,有点杀鸡焉用牛刀之感;何况其中只有一个BOOL
型状态变量,我并不确定这个FB
的实例会占据多大的字节空间——对这个FB
中的BOOL
型变量究竟是否会被优化与其它外部BOOL
型变量合并,我更是持怀疑态度。
方法二是借用函数式编程语言的惯用操作,状态由外部存储和管理,FUNCTION
只接收老状态,经过计算后返回新状态。由于FUNCTION
本身无状态,所使用的参数和局部变量都分配在栈上,这种方式更符合我的品味,所以这里采用这种方法。
其声明如下:
FUNCTION CheckEmStop
VAR_INPUT
btnEmStop_nc: BOOL; // 急停信号常闭点
btnReset: BOOL ; // 复位信号
oldEmStopActive: BOOL; // 老状态
END_VAR
VAR_OUTPUT
newEmStopActive : BOOL; // 新状态
END_VAR
代码实现非常简单,直接按业务逻辑进行翻译即可:
newEmStopActive := oldEmStopActive;
IF NOT btnEmStop_nc THEN
newEmStopActive := TRUE;
END_IF
// 如果急停常闭恢复,再按下复位,则复位急停
IF btnEmStop_nc AND btnReset THEN
newEmStopActive := FALSE;
END_IF
急停功能测试
让我们写一个简单的程序来测试急停判定功能:
PROGRAM PLC_PRG
VAR
sbReset: BOOL; // 复位按钮
emStop_nc: BOOL; // 急停常闭
emStopActive: BOOL; // 急停中
END_VAR
急停判定的调用:
CheckEmStop(
btnEmStop_nc := emStop_nc, // 急停常闭
btnReset := cmdReset, // 复位按钮
oldEmStopActive := emStopActive, // 当前状态
newEmStopActive => emStopActive // 新状态
);
急停常闭断开
急停常闭一旦断开,会使得目标处于急停激活状态:
急停常闭恢复之前进行复位
在急停常闭恢复之前,按下复位按钮也无法清除急停激活状态:
急停常闭恢复
急停常闭恢复之后,目标并不会退出急停激活状态。这有助于在急停信号常闭恢复后,防止设备立刻动起来伤害人生安全:
急停常闭恢复之后复位
在急停常闭恢复之后,再进行复位,会使得当前退出急停激活状态: