Technical Article
海德汉 QL 参数为什么被改了?CALL LBL 与 CALL PGM 的作用域
海德汉TNC 640的QL局部参数,为什么CALL LBL返回后变成25,CALL PGM返回后仍为20?按34059x-18手册,用两张数据流图核对NC程序范围、Q1600显式输出及坐标变换边界。
把一段计算从主程序里的 LBL 抽成独立的 CALC.H,调用方式改成 CALL PGM 后,计算段里明明已经得到 25,主程序接着读 QL1,却还是 20。反过来,原本想把 QL1 当成子程序的临时量,执行 CALL LBL 后,主程序里的值又跟着变了。遇到这种现象,先查这次调用有没有进入另一个 NC 程序。
海德汉 QL 的“局部”,以当前 NC 程序为范围。本文按 TNC 640、NC 软件 34059x-18、2023 年 10 月版官方 Klartext 手册说明,讨论普通 CALL LBL 和 CALL PGM;示例不使用 FN 37 EXPORT、OEM 宏或专用循环。下面给出的数值是按手册规则推演的结果,计算只涉及变量。
同一程序里的 LBL,共用这一份 QL1
官方手册把 QL0~QL499 定义为在一个 NC 程序内局部有效的用户参数。同时,CALL LBL 的执行顺序是进入本程序中的标签段,执行到 LBL 0,再回到调用后的下一段。结合这两处定义可知:一个 LBL 标签不会另外划出一套独立的 QL 参数。
设 MAIN_A.H 在调用前把 QL1 设为 20,调用结束后用 QL2 记录它的值。这里只摘出相关调用和赋值行:
FN 0: QL1 = +20 CALL LBL 10 FN 0: QL2 = +QL1
同一 MAIN_A.H 中的 LBL 10 做一次加法:
LBL 10 FN 1: QL1 = +QL1 + +5 LBL 0
QL1 的演算是 20+5=25。返回后,主程序读到的仍是本程序这份 QL1,因此 QL2 得到 25。改变数值的是 LBL 内执行的加法,CALL LBL 本身没有自动加数或清零的作用。
这些摘录不能直接首尾拼接。按手册的普通子程序结构,LBL 子程序应放在主程序 M2 或 M30 之后,避免主流程顺序落入标签段。本文的 CALL LBL 10 不带 REP;CALL LBL REP 的程序块重复次数是另一种执行结构,不能混在这里计算。
换成独立 CALC.H,同号 QL1 各在各的程序里
另一组示例从头开始。MAIN_B.H 把自己的 QL1 设为 20,再调用同目录的 CALC.H:
FN 0: QL1 = +20 CALL PGM CALC FN 0: QL2 = +QL1
CALC.H 也显式初始化自己的 QL1,然后加 5。这样不需要猜测进入被调程序时局部参数的初值:
0 BEGIN PGM CALC MM 1 FN 0: QL1 = +20 2 FN 1: QL1 = +QL1 + +5 3 END PGM CALC MM
CALC.H 内的 QL1 得到 25;普通 CALL PGM 返回后,MAIN_B.H 里的 QL1 仍为 20,接下来的 QL2 也得到 20。官方在外部程序调用章节明确建议使用仅在当前 NC 程序生效的 QL,避免被调程序的参数修改影响调用方。

这里能确定的是本次调用的参数范围,不能据此推导 QL 在重选程序、复位或断电后还保留什么。要比较两种调用,像上面一样,在每组起点和每个被调程序中明确赋初值,记录调用前、计算后及返回后的值。
要把 25 交回主程序,就约定一个输出参数
如果 CALC.H 的任务就是算出一个值交给主程序,单纯改它自己的 QL1 不够。可以为这个普通 CALL PGM 调用约定一个共享的 Q 参数作为输出。以下选 Q1600:该号位于本版手册的用户参数范围内,但接入实际项目之前,仍要查清它是否已经被别的程序使用。
主程序调用前将 Q1600 显式设为 0;CALC.H 算出 25 后、到达 END PGM 之前,增加这一行:
FN 0: Q1600 = +QL1
返回后,主程序从约定输出位取值:
FN 0: QL2 = +Q1600
这时 MAIN_B.H 的 QL1 仍为 20,QL2 则得到 25,Q1600 也是 25。输出关系由赋值行写清楚,不需要依赖两个程序恰好用了相同的 QL 号码。

把输出位清成 0,只能消除旧值,不能证明本次计算成功。若实际程序有条件跳过计算、提前返回或多个结果分支,还需另外约定完成标志及其检查位置,不能把“读到了一个数”当成结果已更新。
整理后处理时,先画调用关系再分配参数
把 LBL 拆成独立程序,或者把外部程序重新合并进主程序,都会改变 QL 的可见范围。检查这种修改时,不能只比较计算公式是否一字未动,还要记录每一份 QL 属于哪个 NC 程序、输入从哪里来、输出写到哪里去。
同一主程序里两个 LBL 都拿 QL1 当临时量,后执行的标签段就可能覆盖前一段留下的值。若前一个结果还要继续用,应调整参数分配,或在覆盖前保存到本程序内约定且未占用的位置。把 Q 全部替换成 QL,也可能切断原来有意共享的输入和输出。
本文用 Q1600 说明普通外部调用的共享输出,不把规则扩大为“所有 Q 在任何地方都全局”。手册还列有 Q0~Q99 在宏与循环内的局部例外。遇到 OEM 宏或专用循环,应按它自己的参数接口核对。修改前后可对照后处理 NC 输出比较方法,把调用方式和参数赋值行放在一起审查。
QL 隔离了变量,并不替你恢复坐标变换
CALC.H 使用自己的 QL,不代表它对加工状态也完全隔离。官方外部程序调用章节特别提示:被调程序中使用而未复原的坐标变换,可能继续影响调用方。因此,确认“主程序的 QL1 没变”之后,还要单独检查被调程序有没有留下零点偏移、旋转等状态。
从实际程序里缩小问题时,可以先保留本文这种不含轴运动的赋值与调用,在对应 34059x-18 编程站中核对三处参数:调用前的 QL1、被调段计算后的 QL1、返回后记录的 QL2。随后再逐项核对原程序的输入输出与状态恢复。这样,QL 取值问题和运动状态问题都有明确的检查位置,不会把“局部参数”误当成整个调用的自动复原开关。
参考资料
海德汉《TNC 640 Klartext 对话式编程用户手册》,892903-ZB,NC 34059x-18,10/2023。第 223 页为 CALL LBL 与 LBL 0 的调用结构;第 225~227 页为外部 NC 程序调用、QL 使用提示、路径及坐标变换提醒;第 241 页为参数类型和范围,第 245~246 页为赋值及加法。文中调用前后的数值和两张图,是依据这些规则编制的原创演算。
英文同版 892903-2C 的对应位置为第 253、258~260、277、283 页。本文“同一程序的 LBL 共用该程序的 QL”由局部范围定义与 CALL LBL 结构结合推得。