三菱FX3U ST语言实战|WHILE 循环遍历数组计算最大、最小值

案例需求回顾​

沿用与 FOR 循环实战完全相同的测试场景:​

  • 一维数组:数组0..10,数据类型为WordSigned(有符号 16 位整型),共 11 个元素;
  • 目标:遍历数组全部元素,自动提取数组的最大值与最小值;
  • 测试数据:复用之前的验证用例,确保两种循环结构的输出结果一致性。

全局标签配置:

完整 ST 源代码

复制代码
// 1. 最值基准初始化:必须以数组真实元素为初始值,适配全负数/全正数场景
最大值 := 数组[0];
最小值 := 数组[0];

// 2. WHILE循环变量初始化:从数组起始下标0开始遍历
循环索引 := 0;

// 3. WHILE循环主体:遍历条件为"下标未超过数组最大边界10"
WHILE 循环索引 <= 10 DO
    // 4. 更新最大值:当前元素大于暂存最大值时,刷新暂存值
    IF 数组[循环索引] > 最大值 THEN
        最大值 := 数组[循环索引];
    END_IF;
    
    // 5. 【修复】更新最小值:修正赋值变量,将较小值存入最小值寄存器
    IF 数组[循环索引] < 最小值 THEN
        最小值 := 数组[循环索引];
    END_IF;
    
    // 6. 循环变量手动自增:移动变址指针,向循环终止条件靠近
    循环索引 := 循环索引 + 1;
END_WHILE;

// 7. 遍历完成后重置索引:便于后续复用该变量,避免其他逻辑受影响
循环索引 := 0;

二、WHILE循环的基本语法

在三菱ST语言中,WHILE循环的语法格式如下:

复制代码
WHILE <布尔表达式> DO
    <执行语句>;
END_WHILE;

它的执行逻辑是:

  1. 先判断 <布尔表达式>是否为TRUE
  2. 如果为TRUE ,执行DOEND_WHILE之间的语句
  3. 执行完后,再次回到第1步判断条件
  4. 如果为FALSE ,直接跳过循环体,执行END_WHILE后面的代码

简单来说就是:条件为真就一直循环,条件为假就退出

与FOR循环的区别
特性 FOR循环 WHILE循环
适用场景 循环次数已知 循环次数未知,依赖条件判断
循环控制 由循环变量自动控制 需要手动更新循环条件
典型用途 遍历固定长度的数组 等待某个条件成立、持续监控状态

对于遍历数组 这种循环次数固定的场景,其实FOR循环更常用。但WHILE循环的优势在于灵活性 ------当循环次数不固定时(比如"一直累加直到超过某个值"),WHILE是更好的选择。


三、代码逐行解析

1. 初始化
复制代码
最大值 := 数组[1];
最小值 := 数组[1];
index1 := 2;

在开始比较之前,先把第一个元素 同时赋给最大值最小值作为初始值。然后从第2个元素开始逐一比较。

💡 为什么不把最大值设为0、最小值设为9999?

因为数组元素可能是负数。如果用0作为初始最大值,当所有元素都是负数时,最大值就会错误地变成0。用数组的第一个元素作为初始值是最安全的方式。

2. WHILE循环条件
复制代码
WHILE index1 <= 10 DO

只要index1小于等于10,循环就继续执行。当index1变成11时,条件为FALSE,循环退出。

3. 比较与更新
复制代码
IF 最大值 < 数组[index1] THEN
    最大值 := 数组[index1];
END_IF;

IF 最小值 > 数组[index1] THEN
    最小值 := 数组[index1];
END_IF;
  • 找最大值 :如果当前元素比最大值还大,就更新最大值
  • 找最小值 :如果当前元素比最小值还小,就更新最小值

两个IF语句是独立的,可以同时执行。比如当前元素既是目前最大的又是最小的(数组中只有一个元素时),两个条件可能同时成立。

4. 循环变量递增
复制代码
index1 := index1 + 1;

这是最关键的一步! 如果没有这行代码,index1永远等于2,条件index1 <= 10永远为TRUE,循环将永远不会结束 ,最终导致看门狗超时,PLC报错停机。


四、WHILE循环的核心注意事项

⚠️ 注意1:必须确保循环能退出(防止死循环)

WHILE循环的退出完全依赖于条件表达式变为FALSE。如果条件永远为TRUE,循环就会无限执行,直到PLC的看门狗超时报警。

常见的死循环陷阱

  • 忘记在循环体内更新循环变量
  • 循环变量的更新方向错误(比如应该递增却写成了递减)
  • 条件表达式使用了不会改变的外部变量
⚠️ 注意2:循环在一个扫描周期内完成

三菱PLC的WHILE循环是在一个扫描周期内完成的。也就是说,循环体执行多少次,这个扫描周期就会延长多少时间。

如果循环次数过多(比如上万次),可能会导致扫描周期超长,触发看门狗故障。因此:

  • 循环次数不宜过多
  • 如果确实需要大量循环,考虑在循环体内适当位置复位看门狗定时器 (通过WDT指令)
⚠️ 注意3:语法细节------DO后面不加分号

在三菱GX Works2/GX Works3的ST语言中,WHILE语句的DO关键字后面不加分号

复制代码
WHILE index1 <= 10 DO   // ✅ 正确,DO后面没有分号
    ...
END_WHILE;

WHILE index1 <= 10 DO;  // ❌ 错误,DO后面加了分号会导致语法错误
    ...
END_WHILE;

这与C语言等编程语言的语法不同,初学者容易踩坑。

⚠️ 注意4:循环结束后变量的值

FOR循环类似,三菱PLC中WHILE循环结束后,循环变量(如index1不会自动重置 ,而是保持循环结束时的最终值。在上述代码中,循环结束后index1的值是11


五、代码扩展与优化

扩展1:使用FOR循环实现(更简洁)

对于遍历数组这种固定次数的场景,FOR循环更加简洁:

复制代码
最大值 := 数组[1];
最小值 := 数组[1];

FOR index1 := 2 TO 10 BY 1 DO
    IF 最大值 < 数组[index1] THEN
        最大值 := 数组[index1];
    END_IF;
    IF 最小值 > 数组[index1] THEN
        最小值 := 数组[index1];
    END_IF;
END_FOR;

FOR循环自动管理循环变量的递增,不需要手动写index1 := index1 + 1,代码更简洁,也从根本上避免了忘记递增导致的死循环

扩展2:使用EXIT提前退出循环

如果数组元素较多,而我们已经找到了想要的结果,可以用EXIT提前退出循环:

复制代码
WHILE index1 <= 10 DO
    // 如果找到了目标值,提前退出
    IF 数组[index1] = 目标值 THEN
        EXIT;
    END_IF;
    index1 := index1 + 1;
END_WHILE;
扩展3:动态数组长度

如果数组长度不是固定的,可以用LOWER_BOUNDUPPER_BOUND函数获取数组的边界:

复制代码
index1 := LOWER_BOUND(数组, 1);  // 获取第1维的下界
WHILE index1 <= UPPER_BOUND(数组, 1) DO  // 获取第1维的上界
    // 处理逻辑
    index1 := index1 + 1;
END_WHILE;

这样即使数组长度发生变化,代码也不需要修改。


六、总结

要点 说明
语法格式 WHILE <条件> DO <语句>; END_WHILE;
执行逻辑 条件为TRUE时执行循环体,为FALSE时退出
适用场景 循环次数未知,依赖条件判断
最大风险 忘记更新循环变量导致死循环
语法陷阱 DO后面不加分号
扫描周期 循环在一个扫描周期内完成,次数过多会触发看门狗

WHILE循环是三菱ST语言中非常灵活的循环控制语句,特别适合循环次数不确定 的场景。但使用时一定要谨慎,确保循环条件最终会变为FALSE,否则就会触发PLC的看门狗报警和停机。

相关推荐
Emily156853598701 天前
ABB FM9925A HIEE45116R0001 Feedback Measuring Board
plc·dcs·abb·feedback·fm9925a·hiee45116r0001
AlanBruce1 天前
逻辑控制功能详解
自动化·上位机·plc·modbus·mthings·摩尔信使
Oflycomm3 天前
智能网联汽车渗透率攀升至38.4%,Wi-Fi 7 + 蓝牙6.0如何重塑车载无线连接?
物联网·plc·车联网·wifi7·智能网联汽车·蓝牙6.0
深蓝海拓6 天前
基于QtPy (PySide6) 的PLC-HMI工程项目(十五)后续完善和改进:PLC端数据解析的防粘包、残包、废包、拆包
笔记·学习·plc
Emily156853598707 天前
Emerson 1C31129G03 Analog Input Module
java·开发语言·前端·plc·emerson·1c31129g03·input module
澄纸气7 天前
FX3U ST 语言案例|定时器 OUT_T + 计数器 OUT_C 实现多步骤闪烁流程
plc·st语言·三菱 fx3u·gx works2
AlanBruce12 天前
摩尔信使MThings新功能:水电不分家、一键设备扫描
网络·自动化·plc·mthings·摩尔信使·电气·西门子s7
深蓝海拓12 天前
基于socket的 TCP上位机通信内容解析程序
网络·笔记·python·学习·tcp/ip·plc
微小冷13 天前
Beremiz梯形图编程初步
plc·梯形图·beremiz·ladder logic·ladder diagram