数控G代码表不是字典:用模态分组读懂CNC编程状态机
简介:围绕数控机床标准G、M代码整理的速查文档,面向数控编程初学者、机床操作人员及需要快速查阅指令含义的技术人员,帮助厘清常用准备功能与辅助功能代码的作用范围及使用场景。压缩包内含1个doc文件,约123KB,篇幅精简,便于在电脑或移动设备上随查随用。已有272人学习下载,具备一定参考热度。文档以代码表和功能说明为主线,覆盖G00快速定位、G01直线插补、G02/G03圆弧插补、G17~G19平面选择、G40~G49刀具补偿、G54~G59工件坐标系、G71~G73固定循环以及G90~G99进给模式等,并列出M03~M05主轴控制、M06换刀、M07~M09冷却液和M30程序结束等常用M代码。读者可借此快速建立代码索引,理解粗加工、精加工与固定循环的编程对应关系,同时留意不同数控系统对代码解释存在差异,实际操作仍需以机床说明书为准。
1. 数控机床标准 G 代码表:为什么它更像一台状态机而不是字典
很多人第一次翻数控机床标准 G、M 代码表,都会把它当字典用:G00 快速定位、G01 直线插补、G04 暂停,一条一条背下来似乎就掌握了。真正上手才发现不是这么回事——同一段程序里 G01 只写了一次,后面几十行只写坐标和 F 值,机床照样走直线;另一段里 G90 和 G54 同时出现,两条指令谁也不覆盖谁。这说明代码表下面还压着一层东西:组号和模态。看懂这一层,才能明白为什么一份看起来只是罗列代码的表格,值得反复回查。
2. 模态与分组:G01 写一次就管到程序尾,靠的是什么机制
2.1 组号列:一张表里真正的骨架
原表里每行代码后面跟着一个两位数字,00、01、03、05、07、08、09、10、11、12、13、14、15、16、17、18、25,位置不固定、有的还空着。这列数字是整张表的骨架,也就是组号。规则只有一句话:同一组内,后写的覆盖先写的;不同组之间互不干扰,各自保持自己的状态。
按这个规则回看原表就很清楚了。G00、G01、G02、G03 都标 01,说明它们是运动方式的四种取值,同一时刻只能有一个生效;你写了 G01,机床就从快速定位切换到直线插补,G00 的状态被顶掉。G90 和 G91 标 03,绝对值和增量值互斥,也是同一个道理。而 G54 标 14、G17 属于平面选择组、G40/G41/G42 属于刀补组,它们和运动组不是一组,所以 G90 不会取消 G54,G41 也不会改变当前是 G01 还是 G00。
这个设计动机不难猜:如果把每条指令都做成一次性开关,一段稍长的程序就要反复重写 G01、G17、G54,程序体积和出错概率都会翻倍。分组加模态,本质是把「当前机床处于什么状态」这件事交给控制系统维护,程序里只写变化的部分。这是数控语言里最像配置管理的一处设计,也是新手最容易忽略的一处。
O1001 ; 程序号,模态状态从这里开始延续 G17 G21 G40 G49 G80 G90 G94 ; 程序头:把各组状态强行拉回已知值 G54 ; 14 组:选定工件坐标系 G43 H01 Z100. ; 长度补偿,Z 轴先抬到安全高度 G01 X0 Y0 F500 ; 01 组:从这里起运动方式锁定为直线插补 X50. ; 只写坐标,仍然按 G01 走 Y50. ; 同上 G00 Z100. ; 01 组被覆盖,恢复快速定位 M30上面这段里,G01 出现一次之后带出两个只写坐标的程序段,这就是模态在起作用。加工中心上这类写法占绝大多数,F 值也是模态量——写了 F500,后续程序段不写 F 就沿用 500,直到被新的 F 覆盖。注意程序头那一行不是摆设,它把运动、平面、刀补、循环、绝对增量、进给方式几个组一次性复位,避免上一段程序或上一次复位残留的状态带进新工件。
2.2 模态是怎么被"记住"的:上电默认值与复位
控制系统内部维护的是一组状态变量,每个组一个槽位。上电时这些槽位要填一个默认值,这个默认值不是 ISO 统一规定的,而是各家系统自己定的。常见的实现思路是:运动默认 G00、平面默认 G17、刀补默认 G40、循环默认 G80、绝对增量默认 G90,但不同系统、不同参数配置下会有出入。
这就是「血泪经验」的来源。你以为程序开头是干净的,实际上机床刚上电时处于哪个模态,取决于出厂参数;你在中途按了复位再从中断处重启,模态状态会被拉回默认值,而不是停在中断时的状态。原表里 G04、G28、G53 这些指令下面没有可延续的状态,正是为了让这类「跳出去再回来」的操作有明确语义。
用一段状态机的伪代码看,这套机制就很直白了:
# 用状态机视角读 NC 程序:每条 G 指令做两件事之一 GROUPS = { "motion": {0: "G00", 1: "G01", 2: "G02", 3: "G03"}, # 01 组:同时只留一个 "absinc": {90: "G90", 91: "G91"}, # 03 组:绝对 / 增量 "offset": {40: "G40", 41: "G41", 42: "G42"}, # 刀补组 "cycle": {80: "G80", 81: "G81", 83: "G83"}, # 09 组:固定循环 } # 上电默认值:因系统而异,这也是换机床最容易翻车的地方 state = {"motion": "G00", "absinc": "G90", "offset": "G40", "cycle": "G80"} def execute(block): for code in block.g_codes: for group, table in GROUPS.items(): if code in table.values(): state[group] = code # 同组覆盖,异组共存 # 没有出现 G 指令的程序段,沿用 state 里全部现有值执行 run_motion(block.coords, state)参数说明:GROUPS是组到取值的映射,键名只是便于阅读,真正决定互斥关系的是组;state每个组一个槽位;execute里只有命中同组才覆盖,没命中就保持。这段代码不是任何系统的真实实现,但它精确描述了模态的行为边界——也解释了为什么「换机床要重新验证程序头」。
2.3 00 组与"*"行:一次性指令和被厂商征用的保留位
原表里 G04 暂停、G28 原点返回、G30 第二三四原点返回、G52 局部坐标系设定、G53 机械坐标系、G92 设定工件坐标系,都标 00 组。00 组在多数系统里表示非模态:只在本程序段内有效,执行完立即消失,不进入状态槽位。所以 G04 每次暂停都得重写一遍,G28 每次回零都得单独一段,系统不会替你记住。
另一类是标了星号的行。G05、G07、G08、G10、G11、G24、G25、G26、G31、G36、G38、G39,原表要么写「不指定」,要么直接标星。这些是保留位,含义由机床厂商按需征用。G05 在有些系统里是高速高精轮廓控制,G08 在某些系统里是预读加速,G10 在另一些系统里是数据设定——同一串字符,落到不同机床上可能完全是两件事。
提示:移植程序时,凡是原表里标星或写「不指定」的代码,都要回到目标机床的手册里确认一遍,不能按「字面意思差不多」处理。
3. 偏置链:从 G54 到刀尖,一个坐标到底被加了几次
3.1 从机床零点到刀尖:四层偏移的叠加顺序
程序里写的 X50. Y50.,到底是相对谁说的?答案不是机床零点,而是一条偏移链。第一层是机床坐标系,也就是回零后的机械原点,G53 直接在这一层里动作。第二层是工件坐标系 G54 到 G59,每个坐标系在参数表里存着一组 X/Y/Z 偏置值,这是对刀时测出来的。第三层是 G52 局部坐标系,在 G54 的基础上再叠一层,常用来处理同一工件上的多个小区域。第四层是刀具长度补偿 G43/G44 配 H 号,把主轴端面到刀尖的那段长度补进去,通常只作用于 Z。
常见的实现思路是:X、Y 方向按「程序坐标 + G54 偏置 + G52 偏置」合成,Z 方向再多加一项 H 号对应的长度值。写出来大概是这样:
G54 G90 G00 X0 Y0 ; 定位到工件坐标系原点(叠加 G54 偏置) G43 H02 Z50. ; Z 方向叠加 H02 的长度值,刀尖停在工件上方 50mm G52 X100. Y0 ; 在 G54 之上再叠一个局部原点,后续坐标相对它算 G01 X10. F200 ; 实际走到 G54 原点 + G52 偏置 + 10mm 处 G52 X0 Y0 ; 局部坐标系复位(这是 G52 的取消写法) G49 ; 取消长度补偿这里最容易出错的是顺序感:G52 是在 G54 之上叠加的,不是替换,取消时也必须显式写回零值,而不是指望 G54 重新生效。原表把 G52 标成 00 组,正好对应这个事实——它是一次性的设定动作,执行完不留模态,但它的效果会一直存在,直到你再写一次把它归零。这种「非模态但状态持久」的组合,是原表里最不直观的一处设计。
3.2 G92 与 G54 的分水岭:改显示还是改参数表
很多人把 G92 和 G54 当成两种等效的「设原点」方式,实际差别很大。G54 的偏置值存在参数表里,掉电不丢,换程序不影响,是黑匣子之外的持久数据。G92 走的是另一条路:它不改参数表,而是把「当前刀具位置」当成你指定的那个坐标值,直接改写坐标显示。
差别会体现在三个地方。第一,掉电或复位之后 G92 建立的基准通常会丢失,而 G54 还在。第二,G92 之后刀具一旦移动,基准跟着当前点走,如果中间有手动干预,整个基准就漂了。第三,G92 建立的原点无法像 G54 那样在多个坐标系之间切换复用。所以产线上常见的做法是:用 G54 到 G59 放正式的工件坐标系,G92 只用在临时调整或特殊工艺里,而且要在程序里显式说明。
原表把 G92 标 00 组、G54 到 G59 标 14 组,其实也在暗示这个区别:前者是一次性的动作,后者是被选中的状态。
3.3 G53 与 G52:一次性跳转和可叠加的局部原点
G53 常被误解成「绝对坐标」,其实它是「在机床坐标系里动作一次」。写 G53 G00 Z0 意味着忽略所有工件偏置,直接回到机械原点的 Z 位置,常用于换刀点或安全退刀。它标 00 组,用完即失效,下一段仍回到 G54 体系。
G54.1 Pn 是附加工件坐标系,在 G54 到 G59 六个不够用时扩容,标号通过 P 参数指定。它和 G54 属于同一层,只是数量不同。这一点在多点位工装、一次装夹加工多个相同零件的场景里非常实用——每个零件一个坐标系,程序里只改 P 号,不用重复写偏移值。
把这几个代码放在同一张表里看,能看出一条清晰的分层:G53 在机床层,G54-G59 和 G54.1 在工件层,G52 在局部层,G43/G44 在刀具层。层次关系决定了叠加顺序,也决定了取消时该取消哪一层。搞混层次,就会出现「取消 G52 结果把 G54 也搞没了」这类事故。
| 代码 | 所在层 | 是否模态 | 取消方式 |
|---|---|---|---|
| G53 | 机床坐标系 | 否(00 组) | 执行完自动失效 |
| G54-G59 | 工件坐标系 | 是(14 组) | 切换到另一个坐标系 |
| G54.1 | 附加工件坐标系 | 是 | 用 P 号切换或切回 G54 |
| G52 | 局部坐标系 | 否(00 组) | 写 G52 X0 Y0 Z0 归零 |
| G43/G44 | 刀具长度层 | 是 | G49 取消 |
4. 固定循环:G83 一行指令如何展开成七个动作
4.1 一行 G83 展开后的七个动作
原表里 G73 到 G89 这一大段都标 09 组,G80 也在 09 组。它们的共同点是把一串重复动作打包成一行:你写一行 G83,控制系统内部展开成七个动作——快速定位到孔位 XY、快速下到 R 点、按 Q 值分段钻削、每段退刀排屑、钻到 Z 深度、孔底暂停、返回 R 点或初始点。
拆开看会更清楚。G81 是最简单的钻孔循环,动作是「定位 → 快下到 R → 工进到 Z → 快退回」。G83 在中间加了分段:每钻 Q 深度就退回到 R 点一次,把切屑带出来,适合深孔。G73 则只退一小段断屑,不退到 R 点,效率更高但对排屑要求也更高。这两个代码的差别不在「钻」这个动作上,而在「怎么把切屑弄出来」这个工程问题上。
G80 ; 先取消,确保上一段循环没有残留 G00 X30. Y40. ; 定位到第一个孔位 G43 H03 Z50. ; 长度补偿,抬到安全高度 G98 G83 Z-45. R2. Q5. F120 ; G98 返回初始点;R2 起钻平面;Q5 每次啄深;Z-45 孔底 X60. ; 只写坐标:循环状态还在,继续钻第二个孔 X90. G80 ; 显式取消,切回普通运动参数说明:R是安全平面,从 R 点才开始工进;Q是每次啄钻深度,单位跟随 G20/G21 的设定;Z是孔底绝对坐标(G90 下);F是进给速度。G98让每次循环结束返回初始点(这里是 Z50),G99返回 R 点。上面这段里第二、三个孔只写了 X 坐标,是因为 G83 属于 09 组、是模态的——循环一旦被激活,后续每个带坐标的程序段都会再执行一遍循环。这也解释了为什么 G80 必须写。
4.2 G98 与 G99:返回平面决定的是效率还是安全
G98 和 G99 都标 10 组,是固定循环的返回平面选择。G99 让刀尖退回 R 点,行程短、效率高;G98 退回初始点,行程长但安全。什么时候用哪个,本质是「R 点到初始点之间有没有障碍物」的判断。
如果工件上有夹具、压板,或者是阶梯面,G99 退回 R 点后横向移动就可能撞上这些凸起。反过来,如果工件是平板、孔位密集,G98 每次多退几十毫米,一个几百孔的模板上累积的空行程相当可观。产线上的常见做法是:默认用 G99 提效率,在有干涉风险的程序段里单独改 G98,而不是整段程序一刀切。
注意:G98/G99 是模态的,写一次会影响后续所有循环。在一段程序里混用时,务必在每个循环块开头重写一遍。
4.3 G73、G81、G76:同一组 09 里的取舍
原表里同属 09 组的还有 G76 精镗、G74 左旋攻丝、G84 右旋攻丝、G85/G86/G88/G89 各种镗削循环。它们的共同结构是「定位 → 进给 → 孔底动作 → 退刀」,差别在孔底那一瞬:G81 钻完直接退;G82 在孔底暂停 P 秒再退,用于沉孔;G76 精镗在孔底让主轴定向后偏移一小段再退,避免退刀时刮伤已加工表面。
G76 的这个偏移量是个典型的设计取舍。镗刀在孔底如果直接沿原路径退回,刀刃会蹭到已经加工好的孔壁,留下一条螺旋划痕。解决办法是让主轴停在一个固定角度,刀尖朝一个确定方向,然后横向偏一点点再退。代价是必须有主轴定向功能,且偏移方向要跟刀尖安装方向匹配。这类参数在表里只有一个代码,实际调起来全是经验。
4.4 G80 与复合循环:模态循环为什么必须显式取消
G80 在 09 组里负责取消上面的所有循环。它的存在不是冗余,而是模态设计的必然结果:既然 G83 能被后续程序段继承,就必须有一个明确的出口把状态切回来。不写 G80 直接写 G01 X50.,有些系统会把这一行当成「在孔位 X50 再钻一次」,结果就是莫名其妙多钻一个孔,或者刀直接扎进工件。
原表里 G70、G71、G72 标的是 00 组,和 G73 的 09 组不同,这里藏着一处容易被忽略的差异。车削系统里 G71 是内外径粗切复合循环、G72 是台阶粗切循环、G73 是封闭轮廓粗车循环,它们是「一整段轮廓的粗加工指令」;而钻削体系里 G73 是高速深孔断屑循环。同一串字符,在不同工艺体系里对应完全不同的展开逻辑。这也是为什么那份表在开头就写明「仅供参考,如有不同以各机床系统为主」——不是免责套话,而是这行业真实存在的分歧。
5. 排查现场:五类最容易被 G 代码表误导的翻车
5.1 模态残留与程序头
现象一:程序跑到一半按下暂停,处理完报警后从中断处重启,第一段移动就撞刀。
原因在于复位把各组状态拉回了上电默认值,而你中断时的状态可能是 G91 增量、G41 左补、G55 坐标系。重启后系统按 G90、G40、G54 解释同一段坐标,位置自然全偏。原表里标 00 组的那些指令不参与状态保持,更容易让人误以为「整个程序是连续的」。
解决方法是给每段程序配一个固定的安全程序头,把运动、平面、刀补、循环、绝对增量、进给方式、坐标系各组全部显式写一遍,再开始加工。中断重启时不要直接跳段,先跑一次程序头。
现象二:换了一台机床,同样的程序头跑出来尺寸差了几十丝。
原因是两台机床的上电默认值不同,或者某台机床的 G54 偏置表里还留着上一个工件的数据。解决办法是把坐标系、刀补号也写进程序头,不依赖机床当前选中值。
5.2 刀补与圆弧的几何坑
现象三:轮廓外侧过切一小块,或者内角留了个圆角。
G41/G42 的建立和撤销必须挂在有移动的程序段上,而且建立时的移动距离要大于刀具半径。如果直接在圆弧段上建立补偿,或者建立段的直线长度小于刀补值,系统插补出来的过渡轨迹就会切进工件。原表里 G40 标 07 组、G41/G42 属于同一组,说的就是「三者互斥、切换即生效」,但生效的几何前提表里没写。
解决办法是留一段长度大于刀具半径的引入直线做建立,引出段同理;D 号对应的值必须等于实际刀具半径,换刀后要重新核对。
现象四:同样的程序,换一把刀后尺寸系统性偏移。
先查 H 号和 D 号有没有混用。G43/G44 配 H 号管长度(Z 方向),G41/G42 配 D 号管半径(XY 平面内),两组偏置存在不同的表里,号数相同不代表数值相同。这是很典型的一处误读,表里只有两个字母,实际是两个独立的偏置库。
5.3 单位、进给与循环参数的数值坑
现象五:钻孔深度差了半个钻尖,或者攻丝直接断在孔里。
G20 英制、G21 公制标的是 06 组,切换后所有坐标、R、Q、F 的单位一起变。如果程序里 G21 写在 G83 之后,那一行循环仍然按英寸解释,深度会差 25 倍。G94 每分钟进给和 G95 每转进给标 05 组,攻丝必须用每转进给,否则转速一波动螺距就对不上。
解决办法是把 G20/G21、G90/G91、G94/G95 全部放进程序头,并且在固定循环之前确认。钻孔深度还要考虑钻尖角度带来的附加深度,这部分表里不会有,只能按刀具样本算。
6. 通用表与专有机型:这份代码表该怎么用才不背锅
一份覆盖 G00 到 G99 的通用对照表,价值不在于让你背下每条代码,而在于让你看清三件事:哪些组是互斥的、哪些指令是模态的、哪些格子是空的。互斥关系决定了你改一条指令会牵动哪一段程序;模态关系决定了程序段的顺序能不能省;空格和星号决定了哪些地方必须回查具体机床。
这里有个真实的取舍。做得越通用,覆盖面越广,但对单个机型的精度就越低——同一行 G05,在这台机床是高速高精,在那台是保留位,通用表只能写「不指定」。做得越专用,越贴合某一台机床,可迁移性就越差。原表选择的是前者,所以它在开头就写明了适用范围和免责边界,这不是推卸,而是对「通用表必然有歧义」这件事的诚实交代。
验证方法其实很朴素:新程序先在机床上空运行一遍,看坐标显示与实际位置是否一致;再用单段模式跑前十个程序段,逐段核对当前模态状态和刀补值;固定循环单独拿一块废料试钻,量深度和孔径。三步走完,大部分隐患都能提前暴露。
那张表里我印象最深的是 G52 那一行——标着 00 组,看起来是一次性指令,实际效果却一直持续到显式归零。这种「非模态但持久」的组合,光看组号根本看不出来,只能靠踩过一次记住。从那以后我每次写含 G52 的程序,都强制在程序尾加一行 G52 X0 Y0 Z0 归零,不管当时觉得有没有必要。希望帮到你。
需要这份完整的数控机床标准 G、M 代码对照表,可以在资源区取用,配合机床手册一起看,比单独背代码管用得多。
本文还有配套的精品资源,点击获取