GreatLight CNC 加工工厂 logo
CNC 加工
快速原型打样
材料
行业
新闻
关于 GL

获取即时报价

CNC 编程指南

如何在 CNC 机床中编写子程序

子程序是一段 G 代码,控制系统按指令反复运行。本指南介绍 M98 和 G65 语法、参数传递规则,以及导致加工中途停止的常见错误。面向需要代码一次跑通的编程员和装夹操作工。

Fanuc 风格 M98/M99G65 参数传递嵌套最多 4 层安全重启做法
how to write sub program in cnc machine
快速回答

要点速览

子程序是另一个程序号它以 O1001 存放在控制内存中,由主程序用 M98 P1001 调用。
用 M99 结束,不是 M30M30 复位程序并倒回开头。M99 把控制权返回到调用后的程序段。
用 G65 传值,不用 M98普通 M98 不携带参数。G65 P9010 X50. Y30. 把数值传入局部变量。
嵌套层数有限多数 Fanuc 风格控制系统允许 4 层子程序调用。更深嵌套会报警。
先用单段模式测试以快速倍率 25% 空运行,确认返回点后再切削金属。
定义

子程序是什么,何时值得用

子程序是以独立 O 号存放的单独程序,由主程序调用运行。当控制读到 M98 P1001 时,跳转到 O1001,执行这些程序段,并在 M99 处返回到调用后的下一行。主程序保持原有流程。子程序存放重复的工作。

收益体现在有重复几何特征的零件上:一块有 24 个相同 M8 螺纹孔的板、一个有 8 个型腔的工装夹具、一组共用同一螺栓孔位的支架。孔加工循环写一次,用不同的 X 和 Y 调用 24 次。改一次进给,24 个孔全部改变。

不要仅因为代码看起来长就用子程序。如果一段顺序只运行两次,直接复制粘贴更易读、更易重启。当同一运动重复三次以上,或多个程序共用同一固定循环序列时,子程序才值得用。

尽量让子程序不包含机床相关的假设。如果 O1001 中含有 G54 工件偏置,每个调用它的程序都会继承该偏置。在一台机床上没问题,在另一台上可能撞机。把偏置放在主程序,让子程序只处理几何。

  • 1
    适合重复孔位、共用型腔循环、同族零件的螺栓圆。
  • 2
    不适合只用一两次且无参数变化的顺序。
  • 3
    注意偏置G54–G59 放在主程序中,不要放在子程序内。
控制行为

M98 和 M99:调用与返回

M98 是调用。其 P 字给出子程序号。在 M98 P1001 中,控制把 1001 读作程序号并运行 O1001。部分厂商也接受 L 字表示重复次数,例如 M98 P1001 L6,连续运行子程序六次,无需写六个调用段。

M99 是返回。把它放在子程序的最后一段。控制随后跳回 M98 调用后的程序段。如果子程序以 M30 结束,控制会倒回整个程序并停止。在攻丝中途这意味着断丝锥或零件报废。

M99 还有一个让人意外的用法。如果把 M99 放在主程序末尾而不是 M30,控制会循环整个程序并再次运行。这对棒料送料循环很方便,但忘了它存在就很危险。

调用深度很重要。子程序可以调用另一个子程序。多数 Fanuc 风格控制系统允许 4 层。超过就会触发 P/S 报警并停机。如果逻辑需要 5 层,把它展平或把工作拆成两个主程序。

  • 1
    调用M98 P1001 — 跳转到 O1001,在 M99 处返回。
  • 2
    重复M98 P1001 L6 — 同一子程序运行六次。
  • 3
    返回M99 — 回到调用后的程序段。
  • 4
    绝不要用 M30 结束子程序它会倒回并停止循环。
参数

用 G65 和局部变量传递数值

普通 M98 不携带数据。每次调用都运行相同运动。如果想让一个子程序在 24 个位置加工 24 个孔,要么在主程序中写 24 行带位置的调用,要么用 G65 把位置作为参数传入。

G65 P9010 X50. Y30. Z-12. R2. F180 调用 O9010 并把数值装入局部变量。X 映射到 #24,Y 到 #25,Z 到 #26,R 到 #18,F 到 #9。在子程序内写 G81 Z#26 R#18 F#9,控制会代入你传入的数值。

在多数控制系统中,子程序返回时局部变量 #1 到 #33 会被清除。这是特性。意味着下次调用从干净状态开始,没有上一位置的残留值。如果某个值需要在返回后保留,把它写入公共变量,如 #100 或 #500。

参数不是免费的。每次 G65 调用比普通 M98 多花少量加工节拍,且深度嵌套的 G65 调用在尺寸出错时难以追踪。对于永不改变的固定模式,普通 M98 更简单。对于由位置表驱动的模式,G65 是更清晰的路线。

  • 1
    X → #24,Y → #25,Z → #26Fanuc 风格控制系统的标准参数映射。
  • 2
    R → #18,F → #9用于子程序内的固定循环。
  • 3
    局部变量在返回时复位若数值需保留,用 #100 以上。
命名与结构

命名、编号,以及哪些内容应放在子程序内

给子程序分配一个独立的 O 号,放在车间为子程序保留的号段内。常见做法是:O1000–O1999 用于共享子程序,O9000–O9999 用于机床厂商程序或宏程序。保留书面记录。两个编程员把 O1050 分配给不同代码,就是等着撞机。

开头程序段应设定已知状态。写入安全 Z 值、用 G80 取消任何固定循环,以及子程序所需的模态值。绝不要假设主程序把系统留在了方便的模式。子程序若意外以 G91 开头,就会把孔钻成一条直线而不是一个圆。

编写子程序时要保证它能从任意起点运行。除非确实需要增量运动,否则阵列几何用绝对定位。从某一位置调用能正常工作的增量代码,从另一位置调用常常失效,因为机床停在了意料之外的位置。

结束时让机床停在可预测的位置。抬到安全平面,用 G40 取消刀具补偿,用 G80 取消循环,然后 M99。主程序的下一个程序段不应替子程序收拾残局。

  • 1
    保留号段O1000–O1999 用于共享子程序,并在一处登记。
  • 2
    入口设定状态G80、G40、安全 Z 值,以及所依赖的模态值。
  • 3
    出口保持状态干净G40、G80、安全 Z 值,然后 M99。
操作步骤

分步操作:编写、测试并调用子程序

按顺序执行。跳过第 5 步,正是大多数首次运行撞机的原因。

  • 1
    明确子程序的任务写一句话:“在 X、Y 传入的位置钻一个 M8 孔。”如果这句话里有“和”,说明子程序做得太多。拆开它。既钻孔又攻丝的子程序是两个子程序。
  • 2
    分配程序号并添加注释从预留号段中选一个未占用的编号,例如 O1050,并在同一行添加注释:O1050 (M8 DRILL CYCLE)。这条注释就是下一位操作员在凌晨 2 点看到的内容。
  • 3
    设定入口状态开头用 G80 取消任何活动固定循环,用 G40 取消刀具补偿,再用 G0 Z50. 到达已知安全高度。然后设定循环所需的模态值,例如 G90 绝对坐标和 G17 XY 平面。
  • 4
    编写运动程序段钻孔循环:G0 X#24 Y#25,然后 G81 Z-12. R2. F180.。型腔加工:下刀、斜降切入、走轮廓,然后 G40 并退刀。每个坐标要么用绝对坐标,要么明确用增量坐标,没有注释时绝不混用。
  • 5
    干净地结束子程序用 G80 取消循环,用 G40 取消补偿,用 G0 Z50. 抬到安全平面,然后写 M99。不要写 M30。除非下一次调用需要,否则不要让主轴继续转。
  • 6
    不装工件,用单段测试载入主程序,把快速倍率设为 25%,单段执行前两次调用。观察剩余距离显示。确认每次 M98 后机床回到准确程序段,再允许全速运行。
  • 7
    从主程序调用用 G65:G65 P1050 X50. Y30.。固定阵列且无参数:M98 P1050。带重复次数:M98 P1050 L6。所有工件坐标系(G54–G59)都放在主程序里,不要放进子程序。
  • 8
    批量运行前验证首件切一件,按图纸检查孔位,并确认返回点没有漂移。在 24 孔的板上,一个局部变量写错,会表现为整排孔位置错误。
选择正确的调用方式

M98、G65 与宏程序:该用哪种调用

根据子程序是否需要传入数据来选择调用方式。

方法传递数值适用场景注意事项
M98 P1001否固定顺序,每次运动相同无参数;位置必须写在主程序中
M98 P1001 L6否同一循环按设定次数重复重复次数必须与实际阵列一致
G65 P9010 X.. Y..是,传入局部变量位置驱动的阵列和零件族每次调用稍慢;出错尺寸更难追踪
G66 模态宏调用是同一宏应用于后续多个程序段容易意外保持激活;用 G67 取消
直接复制粘贴否只用一两次的顺序改了一份却忘了其他副本
问题排查

常见子程序错误与修复

先看现象,再看原因和修复方法。

现象可能原因处理
M98 行报警程序号不在内存中或 O 号错误载入 O1001 并检查 P 字是否匹配
最后一个孔后循环中途停止子程序以 M30 而不是 M99 结束把 M30 改为 M99
机床反复运行程序主程序末尾写了 M99把主程序结束改为 M30
第二次调用在错误位置切削第一次调用后增量运动仍处于激活状态在子程序开头设定 G90
每次调用孔位偏移越来越大返回前未取消补偿或循环在 M99 前加 G40 和 G80
深层嵌套时出现 P/S 报警子程序调用超过 4 层简化逻辑或拆成两个主程序

子程序写一次,验证两次

如果同一运动重复三次或更多,子程序就值得用。先单段测试前两次调用,再让循环运行。代码确认无误后,把图纸发给我们,我们来报价。

常见问题

工程师常问的子程序问题

子程序和宏程序有什么区别?

子程序是用 M98 调用的存储程序,每次运行相同的程序段。宏程序也是存储程序,但能做算术运算、读取系统变量、用 IF 和 GOTO 跳转,并通过 G65 接收参数。

实际使用中两者界限并不清晰。很多系统允许子程序读取局部变量,所以简单的宏程序就是一个恰好用到 #24 和 #25 的子程序。如果代码需要数学运算或条件逻辑,就称它为宏程序,并存放在 O9000 号段。

子程序加工位置不对,怎么调试?

先检查子程序处于绝对还是增量模式。在开头加一行 G90 或 G91 再试。多数位置错误来自残留的 G91,而不是坐标写错。

如果模式正确,就看变量值。用 G65 调用时,在调用执行前到宏变量画面查看 #24 和 #25。数值正确说明错误在子程序内部;数值错误说明错误在调用程序段。

子程序可以嵌套吗?

可以。子程序能调用另一个子程序。多数 Fanuc 风格系统允许 4 层嵌套。有些系统把主程序算作第一层,有些不算,依赖这个限制前先在机床上实测。

嵌套时出现 P/S 报警,通常就是层数超限。把最内层顺序移到调用方以压平结构,或把任务拆到两个主程序。

使用子程序有哪些限制?

内存是一方面。每个子程序都占用系统内存,老系统内存很少。加工节拍是另一方面。G65 调用因参数处理比内联代码略慢。

更大的限制是可读性。一个编号背后做六件事的子程序,比六个短程序更难调试。每个子程序只做一件事,并把编号范围记录在全车间都能看到的地方。

工件坐标系偏置应该放在子程序里吗?

不要。G54 到 G59 保留在主程序中。偏置放在子程序里,每个调用它的程序都会继承该偏置。在一台机床上没问题,在另一台机床上就可能撞刀。

刀长偏置同理。在主程序中调用刀具和偏置,子程序只处理几何轨迹。

子程序返回后需要保留某个值怎么办?

用公共变量。多数系统在子程序返回时会清除局部变量 #1 到 #33。在 M99 之前把值写入 #100 或 #500,在主程序中读取。

公共变量在系统断电或手动清除前一直保留。用它做 24 次调用的计数器很方便,但下一件工件开头忘记清零就很危险。

把 G 代码变成成品零件

上传图纸,12 小时内获得报价和免费 DFM 分析。从单件原型到 10,000+ 件批量,出货前 100% 检验。

12 小时报价100% 全检无最小起订量可按需签署保密协议

关注 GreatLight

更多来自车间的加工笔记

我们发布来自工厂车间的装夹记录、刀具试验和检测数据。

FacebookTikTokYouTubeLinkedInInstagramThreadsPinterest

深受全球工程师和制造商信赖

Tesla Ford Motor Company 比亚迪汽车 电装 麦格纳国际 波音 空客 美敦力 库卡 发那科