第四节:位逻辑指令——常开触点、常闭触点、线圈输出、置位复位、边沿检测
各位工程师朋友,今天我们来聊聊位逻辑指令。这可以说是逻辑控制器编程的“地基”。你想想看,不管多复杂的控制程序,拆到最底层,无非就是这些基本指令的组合。我个人习惯把位逻辑指令比作“数字世界的开关”——要么通,要么断,没有中间态。
4.1 常开触点与常闭触点
先说常开触点。它的逻辑很简单:当输入信号为1时,触点闭合,信号能通过;输入为0时,触点断开。说白了,就是“有信号才通”。
常闭触点正好相反:输入为0时,它反而是通的;输入为1时,它断开。嗯,这里要注意,很多新手会搞混。我刚开始做项目时,就因为在急停按钮上用了常开触点,结果设备一上电就报警……后来养成了习惯:急停、安全门这类安全相关的信号,一律用常闭触点。
核心记忆法:
- 常开触点:像门,推(1)才开
- 常闭触点:像窗,推(1)就关
在梯形图中,常开触点用“-| |-”表示,常闭触点用“-|/|-”表示。代码层面,以IEC 61131-3标准的ST语言为例:
// 常开触点示例
IF Input1 THEN
Output1 := TRUE;
END_IF
// 常闭触点示例
IF NOT Input2 THEN
Output2 := TRUE;
END_IF
4.2 线圈输出
线圈输出,就是根据输入条件决定输出变量的状态。它像是一个“执行器”——条件满足,线圈得电;条件不满足,线圈失电。
我在项目中遇到过一个问题:某个气缸的电磁阀线圈,在程序里直接用了输出指令。结果调试时发现,只要CPU扫描周期稍微抖动,线圈就会频繁通断。后来我加了一个自锁逻辑,才稳定下来。
实用技巧:线圈输出尽量配合自锁或互锁逻辑使用,避免因扫描周期导致的误动作。
ST语言示例:
// 简单线圈输出
Motor := Start AND NOT Stop;
// 带自锁的线圈输出
IF Start AND NOT Stop THEN
Motor := TRUE;
ELSIF Stop THEN
Motor := FALSE;
END_IF
4.3 置位与复位
置位(SET)和复位(RESET)是一对好搭档。置位指令让输出保持为1,复位指令让输出恢复为0。它们的特点是:一旦触发,状态会保持,直到被另一个指令改变。
你想想看,这在实际中多有用。比如一个液压站的油泵,按下启动按钮后,我们希望它一直运行,直到按下停止按钮。用置位复位就非常合适。
| 指令 | 功能 | 触发条件 | 保持特性 |
|---|---|---|---|
| SET | 将输出置为1 | 上升沿有效 | 保持为1,直到RESET |
| RESET | 将输出置为0 | 上升沿有效 | 保持为0,直到SET |
避坑指南:我曾经在一个项目中,同时用两个不同的条件对同一个变量进行置位和复位。结果程序跑飞了,输出状态完全不可控。记住:同一个变量,尽量只在单一逻辑块中进行置位复位操作,或者用优先级明确的逻辑。
ST语言示例:
// 置位复位逻辑
IF StartBtn THEN
Pump := TRUE; // 置位
END_IF
IF StopBtn THEN
Pump := FALSE; // 复位
END_IF
4.4 边沿检测
边沿检测,说白了就是捕捉信号变化的瞬间。上升沿检测(R_TRIG)捕捉信号从0变1的那一刻,下降沿检测(F_TRIG)捕捉信号从1变0的那一刻。
为什么要用边沿检测?因为很多时候,我们只需要“按一下”这个动作,而不是“按住不放”。比如计数器的触发、单次脉冲的生成,都离不开边沿检测。
我记得有一次调试包装机的计数功能,用普通电平触发,结果每包产品计数了3次。后来换成上升沿检测,问题立刻解决。嗯,这就是边沿检测的威力。
// 上升沿检测示例(ST语言)
R_TRIG_Instance(CLK := Sensor);
IF R_TRIG_Instance.Q THEN
Count := Count + 1;
END_IF
// 下降沿检测示例
F_TRIG_Instance(CLK := Sensor);
IF F_TRIG_Instance.Q THEN
Alarm := TRUE;
END_IF
4.5 知识体系总览
下面这张图,是我自己整理的位逻辑指令知识框架。你可以把它当作一张“地图”,随时回来对照。
4.6 综合应用示例
最后,我们来看一个综合案例。假设我们要控制一个传送带的启停,要求:
- 按下启动按钮(常开触点),传送带运行
- 按下停止按钮(常闭触点),传送带停止
- 每次启动时,计数器加1(上升沿检测)
- 当计数达到100时,自动停止并报警(置位复位)
// 传送带控制逻辑
// 启动:上升沿检测
R_TRIG_Start(CLK := StartBtn);
IF R_TRIG_Start.Q THEN
Conveyor := TRUE;
RunCount := RunCount + 1;
END_IF
// 停止:常闭触点逻辑
IF NOT StopBtn THEN
Conveyor := FALSE;
END_IF
// 计数满100,置位报警
IF RunCount >= 100 THEN
Conveyor := FALSE;
Alarm := TRUE; // 置位报警
END_IF
// 复位报警
IF ResetBtn THEN
Alarm := FALSE;
RunCount := 0;
END_IF
这个例子,把常开触点、常闭触点、线圈输出、置位复位、边沿检测都用上了。你可以在自己的项目中试着套用这个框架。
最后说一句:位逻辑指令虽然基础,但用好了能解决80%的控制问题。别小看它们,我见过不少复杂的设备,核心逻辑就是这几条指令的巧妙组合。