Technical Article
西门子循环数量设为0仍执行一次:WHILE与REPEAT的入口差别
依据西门子828D CNC5.24手册,用0、1、3组计数对比WHILE与REPEAT的入口差别,解释零数量为何仍执行一次,以及继续条件和退出条件怎样对应。
把加工数量改成0,程序却仍进入了一次循环体。如果原程序写的是REPEAT…UNTIL,这不一定是数量没有传进去:REPEAT先执行循环体,到了UNTIL才判断是否结束。若循环体放着钻孔调用或一次进给,数量为0也挡不住第一次执行。
这里限定为SINUMERIK 828D、CNC软件5.24,依据07/2024版NC programming手册。讨论的是结构化REPEAT…UNTIL循环,不是用于重复带标签程序段的REPEAT指令。以下全部是变量计算片段,没有轴运动、主轴、换刀或夹紧指令。
第一次判断放在哪,决定能不能执行零次
WHILE的条件在循环体前面:条件成立才进去,不成立就直接越过ENDWHILE。REPEAT的条件在循环体后面:先执行一次,再由UNTIL判断是否退出。因此“重复执行直到完成”和“还有数量才执行”虽然听起来接近,入口条件却不同。

用纯计数片段隔离问题
CXQTY存本次要求数量,CXDONE存已经完成的计数。这两个名字是本文新定义的局部INT变量,集成前先核对现有程序是否重名。两段是替代关系,不应把两组DEF连续粘进同一作用域。输入限定为0或正整数,不能把负数量当作正常零数量。
修改前的后判断写法:
DEF INT CXQTY,CXDONE
CXQTY=0
CXDONE=0
REPEAT
CXDONE=CXDONE+1
UNTIL CXDONE>=CXQTY
第一轮先把CXDONE从0加到1,再判断1≥0,条件成立后退出。最终是1,不是0。这只是循环结构的推演结果,不能称为机床实际加工了一个零件。
如果业务要求数量为0时完全跳过循环体,改成入口判断:
DEF INT CXQTY,CXDONE
CXQTY=0
CXDONE=0
WHILE CXDONE<CXQTY
CXDONE=CXDONE+1
ENDWHILE
入口先判断0<0,结果为假,循环体不执行,CXDONE保持0。注意比较号也改变了:WHILE使用“还没完成”的继续条件,UNTIL使用“已经完成”的退出条件。不能只换关键字、原样保留同一个布尔表达式。
正常数量通过,不代表边界数量通过
把CXQTY分别设为0、1、3,从CXDONE=0开始逐行算。要求1次和3次时,上面两段都分别累计到1和3;区别只在0这组。审核后处理输出时,只看一份正常数量程序,很容易漏掉入口差异。

这个示例把“循环体执行”和“加1”看作同一步。真实加工程序必须另外定义何时算完成,例如某个子程序正常返回后再增加计数。仅把计数提前,并不能证明那次加工已经完成;异常退出、跳段和断点续加工也不在这两段纯计算代码中。
不要把动作留在入口判断之外
改成WHILE后,再检查原来的第一刀、定位或子程序调用是否仍位于WHILE之前。循环只能控制它包住的程序段;已经放在循环前面的动作,不会因为数量为0自动跳过。反过来,也不能为凑成循环而把只应执行一次的初始化全部移进循环体。
后处理对照时,应把初始化、入口条件、循环体和计数更新四部分分别标出。数量变量还要与层深、步距分开:INT与REAL层深变量的区别处理的是数值类型,不是循环入口。若随后要读取运动相关状态,STOPRE与运动准确停止的边界也应单独核对,不能用一个循环关键字代替机床状态判断。
技术依据
Siemens SINUMERIK 828D NC programming,07/2024,CNC 5.24,第4.1.7.4与4.1.7.5节、纸页480–481:WHILE在入口检查条件;REPEAT至少执行一次,UNTIL条件成立时终止。本文示例与图表为基于该规则的原创逻辑推演,不含实机验证数据。