想象一下,你每天在机台上打一排孔。今天图纸改成了 6 个孔,明天又换成 8 个孔。
像极了买菜:一个是"每天把整个冰箱的菜都换一遍",另一个是"我只改购物清单上的数量"。
宏程序,就是给你的数控程序装上"脑子"——它会记数、会判断、会算数,还能自己根据条件决定走哪条路。
先给三个概念划清界限,别混:
| 名称 | 能不能用变量 | 调用方式 | 典型用途 |
|---|---|---|---|
| 普通主程序 | 基本不用 | 直接运行 | 整件加工流程 |
| 子程序 | 不能(参数很死) | M98 Pxxx | 重复的固定动作 |
| 宏程序 | 能!这就是核心 | G65 Pxxx A_B_... | 可变尺寸/可变逻辑的通用加工 |
子程序和宏程序长得像,都能用 M99 返回。但子程序里的坐标是焊死的数字,而宏程序里可以塞满 #1 #2 #3 这种"活数字"。
一句话记住:子程序是"剧本",宏程序是"活的剧本"。
宏编程最颠覆认知的一点,是你要把程序里的尺寸,从"写死的数字"变成"填空格的变量"。
看一个对比。同样一个"打同心圆上的均布孔":
(实际编程不要使用中文注释,这里只是为了说明)
(打 4 个孔,圆心在 (100,50),半径 40)
G00 G90 X100. Y50. (假装定位)
...
(每个孔坐标都要手算、手写)
G81 X140. Y50. Z-10. R2. F100.
X100. Y90.
X60. Y50.
X100. Y10.
G80
(输入:X=圆心X Y=圆心Y I=半径 K=孔数 R=安全高度 Z=孔深 F=进给)
G65 P9100 X100. Y50. I40. K4. R2. Z-10. F100.
O9100
(************************************************************)
( 功能:在指定圆心、半径上,打 K 个均布孔 )
( 调用格式:G65 P9100 X_ Y_ I_ K_ R_ Z_ F_ )
( )
( 【变量映射——严格对照字母】 )
( 字母 X → #24 (圆心X坐标) )
( 字母 Y → #25 (圆心Y坐标) )
( 字母 I → #9 (分布圆半径, 必须 >0) )
( 字母 K → #11 (孔数, 必须 ≥2) )
( 字母 R → #18 (安全平面R值) )
( 字母 Z → #26 (孔底Z值) )
( 字母 F → #6 (钻孔进给速度, 必须 >0) )
( )
( 【内部局部变量】 )
( #1 = 当前角度(度) )
( #2 = 角度增量(360 / K) )
( #3 = 当前孔 X 计算值 )
( #4 = 当前孔 Y 计算值 )
(************************************************************)
(1 ★★★ 防错校验:关键参数缺失或非法,直接 #3000 报警停机 ★★★)
IF [#24 EQ #0] THEN #3000 = 1 (X CENTER MISSING)
IF [#25 EQ #0] THEN #3000 = 2 (Y CENTER MISSING)
IF [#9 EQ #0] THEN #3000 = 3 (I RADIUS MISSING)
IF [#9 LE 0] THEN #3000 = 4 (I RADIUS MUST >0)
IF [#11 EQ #0] THEN #3000 = 5 (K HOLE COUNT MISSING)
IF [#11 LT 2] THEN #3000 = 6 (K MUST >=2)
IF [#18 EQ #0] THEN #3000 = 7 (R PLANE MISSING)
IF [#26 EQ #0] THEN #3000 = 8 (Z DEPTH MISSING)
IF [#6 EQ #0] THEN #3000 = 9 (F FEED MISSING)
IF [#6 LE 0] THEN #3000 = 10 (F FEED MUST >0)
(2保存并强制绝对坐标模态)
#500 = #4003 (保存当前G90/G91模态到公共变量)
G90 (强制绝对坐标)
(3计算角度参数)
#2 = 360 / #11
#1 = 0
(4快速定位到圆心)
G00 X#24 Y#25
(5循环钻孔)
WHILE [#1 LT 360] DO1
#3 = #24 + #9 * COS[#1]
#4 = #25 + #9 * SIN[#1]
G81 X#3 Y#4 R#18 Z#26 F#6
#1 = #1 + #2
END1
(6取消循环 回圆心)
G80
G00 X#24 Y#25
(7恢复调用前的G90/G91模态)
G#500
M99
宏程序内部用循环把一个孔挨个转出来,你只管填圆心、半径、数量。图纸改 6 个孔?把 K4. 改成 K6.,结束。
这就是参数化:程序结构不变,输入变了,输出自动跟着变。
法兰盘有 5 种规格,只有直径和孔数不同。写一个通用宏,一把刀子管 5 种工件。
椭圆、抛物线、螺旋槽,用 G 代码一段段凑太痛苦。宏程序用 SIN、COS 算出上千个点,一条条直线逼近,几乎零误差。
比如测到毛坯余量多了 0.5mm,宏程序读系统变量"知道"实际位置,自动把切深补回来,不用人盯着干。
别急着啃大程序,先看最小可运行的骨架。下面这个宏打印一个固定的点路径(供理解结构,后续篇幅再展开真功能):
% (程序开始标记)
O9101 (O号,文件名要对应)
(SIMPLE DEMO MACRO) (程序注释)
(变量说明: #1=循环起点, #2=终点, #3=步距)
#1 = 0
#2 = 10
#3 = 2
WHILE [#1 LE #2] DO1 (从0走到10,每次走2)
(这里将来放G01 X#1 之类的加工指令)
#1 = #1 + #3 (变量自己加自己——这就是"记数")
END1
M99 (返回)
% (程序结束)
这里你第一次看到 #1 = #1 + #3。别被吓到,意思很简单:把 #1 现在的值,加上 #3,再存回 #1。循环 6 次,#1 就从 0 蹦到 2、4、6、8、10,然后退出。
宏程序就是靠这种"自己给自己加数"的方式,实现"记数"、"推进度"的。
坑 1:宏程序 ≠ 子程序,别用 M98 调宏然后指望它在调用端改参数。
M98 调用的子程序无法接收 G65 那种 A_B_C_ 变量赋值。想用参数化,必须走 G65(或 G66 模态调用,见第 11 篇)。用错调用方式,宏里读到的全是 #0 空值,程序会"莫名其妙"。
坑 2:想当然往宏里塞 # 号结果报警 PS0107。
有些初学者随手写 #100 = 12345678901234,超出变量允许范围(约 ±10^308 或 ±10^7,取决参数 6008#0),系统直接报 PS0110 数据溢出。写大数前,先想想这个数到底存不存得下、有没有必要用变量存。
这一篇的目标很简单:让你知道宏程序是"会算数、会记数、会判断"的活程序,核心是把写死的数字升级成填空格的变量,靠 G65 调用并传入参数。
不过,光知道 #1 #2 还远远不够——变量的世界远比你想的复杂。下一篇:
👉 第 02 篇《变量江湖:#0 到 #999 全解》——带你逛遍变量这个"大江湖",搞清楚空变量、局部变量、公共变量、系统变量到底谁管谁、谁能断电保数据、谁一复位就清零。
我们下一篇见!