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

第 02 篇 · 变量江湖:#0 到 #999 全解

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

开场钩子:一栋楼的四个房间

把数控系统想象成一栋办公楼。

你写的每个 # 号,本质上都是在挑一间房间去存东西。搞清楚每间房的脾气,你才能不乱放、不撞车。

1. 变量江湖四大家族总览

先给一张"户口本",一表看懂四大家族:

家族编号范围断电后谁能用典型用途
空变量#0—(永远空)全局只读判断"这参数传没传"
局部变量#1~#33清零仅当前宏参数传递、临时计算
公共变量(A区)#100~#199清零(可选掉电保持,看参数6001#6)全局跨程序临时通信
公共变量(B区)#500~#999保持不丢全局重要数据、状态保持
系统变量#1000+系统定义全局读写坐标/刀具/模态/报警

别被"全局"吓到:公共变量和系统变量是所有宏程序共享的"公共空间",局部变量才是每个宏自己的"私有空间"。

2. 空变量 #0:不是 0,是"没有"

#0 是全局最特殊的一个变量。它不是数值 0,而是"空"——表示"这个数根本不存在"。

它是只读的,你不能#0 = 5

空变量的两大诡异行为(必考!)

行为 1:地址字遇空,直接忽略。

#1 = 100                    (#1 有值)
#10 = #0                   (#10 是空的)

G90 X100 Y#1 Z#10          (实际执行:G90 X100 Y100 —— Z 被忽略!)

因为 #10 是空的,程序段里的 Z#10 连同 Z 地址一起被扔掉了,只执行 X100 Y100

行为 2:判断里,空 ≠ 0。

#1 = 0
IF [#1 EQ #0] GOTO 100      (这里不会跳!因为 0 ≠ 空)

在条件判断里,空变量既不等于 0,也不等于任何数(它"谁都不等于")。想判断"这个参数传没传",就要用 IF [#x EQ #0],这是宏编程检查参数是否缺失的唯一正确姿势。

3. 局部变量 #1~#33:宏程序自己的"草稿纸"

#1~#33 是局部变量,规矩很明确:

常见约定(非强制,但行业习惯如此):

#1 ~ #26    (接收 G65 传入的自变量,对应 A~Z)
#30 ~ #33   (宏内部临时变量,随便用,别覆盖 #1~#26)

4. 公共变量 #100~#999:程序间的"共享内存"

公共变量是全局的,任何宏程序都能读写同一个 #100。这既是便利,也是事故源头。

分区在断电行为上不同

区段断电后用途倾向
#100~#199清零(除非改参数6001#6让它保持)临时的全局交换、计数器
#500~#999掉电保持要长期保存的数据,如刀具基准直径、工件原点偏移

典型用途:

(程序 A 结束时,把当前加工号记进公共变量)
#500 = 101                  (掉电也不丢,下次开机还能读)

(程序 B 开机检查:上次加工到哪个号了?)
IF [#500 NE #0] THEN #501 = #500

⚠️ 但请看这段的坑:程序 A 刚写 #500,程序 B 就指望读它——如果 A 和 B 不同时在线、或 B 先于 A 运行,#500 读到的可能是上一次运行残留的旧值,甚至 #0。共享变量最大的敌人是"时序错乱"。

5. 系统变量 #1000+:机床的"仪表盘"

系统变量映射 CNC 内部真实状态,是宏编程真正"高级"的地方:

系统变量大多是只读的,少数可写(如 #3000 触发报警、#1100 输出信号)。乱写千万别试,改错坐标系统变量可能让刀直接怼上工件。

系统变量的详细拆解,是第 05、06 篇的重头戏。这一篇你只需记住:它是机床"现在真实状态"的窗口

6. 变量表示法:直接指定、间接寻址、名称标号

① 直接指定

最常见的写法,直接写变量号:

#100 = 3
#102 = #100 + #100 * 10    (#102 = 3 + 30 = 33)

② 间接寻址:#[#xxx](变量号存在另一个变量里)

想把"变量号"也做成变量,用 #[#xxx]。当 #xxx = *** 时,#[#xxx] 就等同于 #***

#1 = 100                    (#1 里存的是"变量号"100)
#[#1] = 5                   (等同于 #100 = 5)
#7 = #2                     (#7 等于 #2 的值 —— 这是直接指定,别跟上面搞混)

规则:#1 存数值 N 时,#[#1] 就是变量 #N 例:#10 = 500#[#10]#500#3 = 2001#[#3]#2001

方括号里不一定是单独的变量,也可以是变量号表达式#[2000 + #n]。当 #n=5 时它就是 #2005 —— 这是动态访问刀补的标准写法,后面第 05 篇会用到。

间接寻址特别适合做循环:用 #1 当计数器(依次存 100、101、102...),就能批量访问 #[#1]#100、#101、#102...

③ 系统变量的"名称标号":[#_OFS[n]](别跟间接寻址混)

成组系统变量(刀补、位置、PMC 接口等)除了用变量号直接写,还可以用官方预定义的名称[n] 标号访问,n 为组内序号:

#31 = 5
#32 = [#_OFS[#31]]           (名称标号:刀补组第 5 个 → 就是 #2005)
#33 = [#_ABSMT[1]]           (名称标号:第 1 轴机械坐标 → 就是 #5021)

⚠️ 千万别把 ② 和 ③ 当成一回事:

间接寻址取的是"变量号=#31的值"那个变量;名称标号取的是"刀补组第 n 个"。注意:官方语法里不存在 #2001[#31] 这种"数字变量号后面挂下标"的写法,想动态访问第 n 号刀补,请用表达式间接寻址 #[2000+#n] 或名称标号 [#_OFS[#n]]。学到第 05 篇刀补时会用到。

巨坑警告 ⚠️

坑 1:拿公共变量当局部变量用,结果"撞车"。
两个宏程序都自作主张用 #100 存临时数据,先后调用时后写的把先写的覆盖掉,整个程序乱套。规矩:公共变量 #100~#199 一定只存"真正要跨程序共享"的数据,临时计算全部丢给局部变量 #30+。

坑 2:断电清零的变量,开机后是 #0 空值,不是 0。
很多新手误以为"没存东西就是 0"。错!没存过就是空 #0。所以读到公共变量后,判断要用 IF [#x EQ #0] 检查"到底有没有值",而不是想当然地直接拿去算。空值参与运算会整段忽略,意外就来了。