AI教你学数控 · FANUC 宏B科普

第 01 篇 · 宏程序是什么?为什么它这么牛

系列 · 面向会操机的从业者 · 轻松科普

开场钩子:同样一个孔,两种人生

想象一下,你每天在机台上打一排孔。今天图纸改成了 6 个孔,明天又换成 8 个孔。

像极了买菜:一个是"每天把整个冰箱的菜都换一遍",另一个是"我只改购物清单上的数量"。

宏程序,就是给你的数控程序装上"脑子"——它会记数、会判断、会算数,还能自己根据条件决定走哪条路。

1. 宏程序 vs 普通程序 vs 子程序

先给三个概念划清界限,别混:

名称能不能用变量调用方式典型用途
普通主程序基本不用直接运行整件加工流程
子程序不能(参数很死)M98 Pxxx重复的固定动作
宏程序能!这就是核心G65 Pxxx A_B_...可变尺寸/可变逻辑的通用加工

子程序和宏程序长得像,都能用 M99 返回。但子程序里的坐标是焊死的数字,而宏程序里可以塞满 #1 #2 #3 这种"活数字"。

一句话记住:子程序是"剧本",宏程序是"活的剧本"。

2. 参数化思维:把数字变成"填空格"

宏编程最颠覆认知的一点,是你要把程序里的尺寸,从"写死的数字"变成"填空格的变量"。

看一个对比。同样一个"打同心圆上的均布孔":

普通写法(改数量=重写):


(实际编程不要使用中文注释,这里只是为了说明)
(打 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.,结束。

这就是参数化:程序结构不变,输入变了,输出自动跟着变。

3. 宏程序到底"牛"在哪?三个应用场景

场景 A:零件系列化(同结构、不同尺寸)

法兰盘有 5 种规格,只有直径和孔数不同。写一个通用宏,一把刀子管 5 种工件。

场景 B:数学轮廓(直线圆弧画不出来的)

椭圆、抛物线、螺旋槽,用 G 代码一段段凑太痛苦。宏程序用 SINCOS 算出上千个点,一条条直线逼近,几乎零误差。

场景 C:自动化补偿(加工中自己算)

比如测到毛坯余量多了 0.5mm,宏程序读系统变量"知道"实际位置,自动把切深补回来,不用人盯着干。

4. 第一次写宏:一个能"呼吸"的简单例子

别急着啃大程序,先看最小可运行的骨架。下面这个宏打印一个固定的点路径(供理解结构,后续篇幅再展开真功能):

%                                        (程序开始标记)
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 数据溢出。写大数前,先想想这个数到底存不存得下、有没有必要用变量存。