STM32 Blue Pill 运行 GRBL:从烧录到多轴 CNC 配置全攻略

STM32 Blue Pill 运行 GRBL:从烧录到多轴 CNC 配置全攻略 简介这是一份面向嵌入式开发者、CNC设备制造商及创客群体的STM32平台GRBL固件资源解决传统8位AVR版GRBL在轴数扩展、通信速率与开发灵活性上的瓶颈问题。资源基于GRBL 1.1f深度适配STM32F103系列支持3至6轴高精度运动控制兼容Blue Pill等低成本开发板并提供USB与USART双通信通道最高波特率921600特别适合需定制化CNC/激光雕刻控制逻辑且倾向命令行开发环境的用户。压缩包含178个文件以70个.h头文件和55个.c源码为主覆盖USB描述符、步进电机驱动、G代码解析、定时器与外设底层驱动等核心模块另有4个.hex烧录文件、9张原理图与界面参考图jpg/png、Makefile构建脚本及PDF说明文档总大小4.21MB。目前已有81人学习下载可直接获取预编译固件快速部署亦可通过文本编辑器命令行完成全流程二次开发与调试。 如果你跟我一样先是玩了一两年基于 Arduino 的 GRBL后来慢慢觉得 3 轴不够用、想加第四轴旋转轴或者直接上激光联动那你大概率会遇到同一个坎原版 GRBL 在 8 位单片机上的性能已经压榨到极限了。我在这个节点上转到了 STM32 平台的 32 位 GRBL 固件也就是标题里这套基于 STM32、支持 3 至 6 轴控制、专门适配 Blue Pill 等开发板、可以走 USB 或串口通信的固件包。这篇文章完整记录我从选型、烧录、接线到配置调参的全过程以及我踩过的那些坑。如果你正准备升级自己的桌面级 CNC、激光雕刻机或者手里刚好有一块吃灰的 Blue Pill 想让它干点正事这篇应该能帮你省掉好几个晚上的折腾时间。整套东西说白了就是把经典的 GRBL 运动控制核心从 8 位 AVR 移植到了 ARM Cortex-M3 上让运动控制有了更充裕的 CPU 资源、更大的内存空间和更丰富的外设。原来在 Arduino UNO 上跑 3 轴就紧张兮兮的固件现在可以在 STM32F103C8T6 这块十几块钱的板子上跑 6 轴而且还不用额外插 USB 转串口模块——板载 USB 就能直接当虚拟串口用。这篇文章面向的读者就是那些不甘心止步于 3 轴雕刻机、想把手上的 Blue Pill 改造成多轴运动控制器的 DIY 玩家。1. 项目核心思路为什么是 STM32 而不是 Arduino1.1 原版 GRBL 的性能天花板如果你看过市面上绝大多数 GRBL 教程基本都是同一个套路Arduino UNO 刷一个 grbl 1.1h.20190825.zip 的 Release连上 CNC Shield V3然后就能用了。不是说这个方案不能跑而是它的天花板太明显了。Arduino UNO 用的 ATmega328P 是一颗 8 位、16MHz、2KB RAM 的单片机GRBL 要在这样的芯片上实时生成步进脉冲、处理 G 代码解析、响应上位机命令靠的是定时器中断在一微秒一微秒地挤。3 轴、每轴 40kHz 左右的脉冲频率基本就是这个平台的舒适区上限。一旦你想上第 4 轴、第 5 轴中断处理的时间就分配不过来了脉冲频率一高电机就开始丢步。更麻烦的是ATmega328P 的串口缓冲区只有 256 字节上位机发送 G 代码的速度稍微快一点缓冲区就满了上位机只能停下来等固件消化整体加工效率会明显降低。1.2 32 位平台带来的硬核升级转 STM32 之后这些瓶颈基本都被解开了。STM32F103C8T6 的 CPU 主频 72MHz是 AVR 的 4.5 倍20KB RAM 是 AVR 的 10 倍64KB Flash 也整整扩大了一倍。更重要的是STM32 有多个硬件定时器步进脉冲生成可以更多交给硬件去处理CPU 只需要在定时器中断里更新下一个脉冲的计数值负载压力比纯软件翻转 IO 低得多。我把两个平台的对比整理成了表格方便你直观感受差异项目Arduino UNO 版 GRBLSTM32 版 GRBL处理器ATmega328P8 位16MHzSTM32F103C8T632 位72MHzRAM2KB20KBFlash32KB64KBUSB 通信需外接 USB 转串口模块板载 USB 虚拟串口或硬件串口轴数支持通常 3 轴3 至 6 轴典型脉冲频率上限30 至 40kHz100kHz 以上与配置相关上位机驱动能力256 字节串口缓冲高速传输会卡顿串口 USB 双通道缓存和中断处理能力更强看到这个对比基本就能理解为什么这么多做桌面级 CNC 的人开始转向 STM32 方案。当然不是说 Arduino 版 GRBL 就该被淘汰如果你只做简单的 3 轴雕刻、进给速度要求不高那 Arduino 方案依然够用且简单。但如果你想跑 4 轴联动、或者把主轴转速提高、或者接激光模块那 32 位平台几乎是必然选择。2. 硬件准备与引脚分配2.1 Blue Pill 开发板选型Blue Pill 这个名字很形象蓝色的小板子核心是 STM32F103C8T6。它现在最大的优势就是便宜十几块钱就能买到一块而且板载了 USB 接口、8MHz 晶振、LED、复位按键引脚也全部引出特别适合当运动控制板。买的时候有一点要注意部分廉价版的晶振没有焊或者焊的是贴片陶瓷谐振器这会导致 USB 通信不稳定甚至无法识别拿到手先确认晶振在不在。板载 USB D 的上拉电阻绝大多数 Blue Pill 是有的所以可以直接插 USB 线识别成虚拟串口不需要额外飞线。这一点对后面选通信方式影响很大因为很多 32 位 GRBL 固件默认就是用板载 USB 做串口通信的。如果你手头没有 Blue Pill其实 STM32F103 系列其他型号也大多能跑只是引脚定义需要自己重新映射。F103C8T6 是性价比最高的选择Flash 64KB 正好能装下 6 轴版的 GRBL 固件再多加功能就容易超了。2.2 引脚分配一览不同作者发布的 32 位 GRBL 固件引脚定义会有差异这个一定要先看自己固件包里的源码或者说明文档不要在网上随便找一张引脚图就照着接。我用的这套固件引脚分配大概是这样功能引脚备注X 轴步进脉冲 PULPA8定时器通道输出X 轴方向 DIRPA6普通 IOY 轴步进脉冲 PULPA10定时器通道输出Y 轴方向 DIRPA9普通 IOZ 轴步进脉冲 PULPB5定时器通道输出Z 轴方向 DIRPB4默认 JTAG 引脚固件已禁用 JTAG第四轴 A 步进脉冲PB3默认 JTAG 引脚固件已禁用 JTAG第四轴 A 方向PA15默认 JTAG 引脚固件已禁用 JTAG步进使能 ENPB7低电平使能主轴 PWMPA0定时器通道输出X/Y/Z 限位PB0/PB1/PB10常开输入这里特别提醒一句PA15、PB3、PB4 这三个引脚在 STM32F103 上默认复用为 JTAG 的 JTDI、JTDO、NJTRST如果你用的固件没有在启动阶段禁用 JTAG那这三只脚是输出不了步进脉冲的。好在大多数成熟的 32 位 GRBL 固件都默认把 JTAG 关掉、只保留 SWD在 SystemInit 里就处理好了这也是为什么烧录仍然可以用 ST-Link 的 SWD 接口因为 SWD 只用 PA13/PA14不影响。2.3 USB 和串口两种通信方式这套固件的通信方式有两种一是板载 USB 直连电脑二是通过外部 USB 转 TTL 模块连接硬件串口。我实际两种都用过说下各自场景。板载 USB 的好处是干净利落一根 USB 线搞定供电和通信不需要额外接任何模块。F103 内置 USB 2.0 全速外设固件里跑一个 USB CDC 虚拟串口电脑上会识别成一个 COM 口grbl control 这类上位机直接选它就行。缺点就是线不能太长超过一米半容易掉线而且有的 Windows 系统需要用 Zadig 或者 ST 官方驱动来正确识别虚拟串口。外接 USB 转 TTL 模块常见芯片有 CH340、CP2102、FT232R、FT231X 这几类。接线方式很简单模块的 RX 接板子 PA9USART1_TX模块的 TX 接板子 PA10USART1_RXGND 共地。这里有个容易翻车的点很多 USB 转 TTL 模块默认输出 5V 电平Blue Pill 是 3.3V 逻辑直接怼上去长期使用有风险。稳妥做法是选支持 3.3V 电平的模块或者在模块和板子之间加电平转换。我自己因为偷懒用 5V 电平的模块怼过一次结果板子偶尔重启排查了半天才发现是电平不匹配。2.4 供电注意事项Blue Pill 板子本身是 3.3V 逻辑而电机驱动板比如 A4988、DRV8825需要 12V 或 24V 供电。接线时最核心的一条所有模块的 GND 必须共地。如果不共地信号电平根本没有参考点步进脉冲会乱跳甚至可能烧毁驱动板。另外供电来源要理清楚。如果 USB 只负责通信、电机驱动板单独供电那没问题如果同时用 ST-Link 给板子供电、又用 USB 给板子供电可能会出现倒灌导致板上稳压芯片发热。我习惯的做法是调试阶段用 USB 供电给板子VMOT 单独接 12V大功率主轴启动瞬间电压跌落严重此时建议给板子单独加一个 5V 稳压供电否则 GRBL 容易电压不足复位加工行程跑到一半突然回到原点非常折磨人。3. 从固件编译到烧录3.1 编译环境准备你拿到的固件包是 .zip解压之后里面一般有两种东西一是已经编译好的 .bin 或 .hex 固件文件二是完整源码工程。如果你不想折腾编译直接用现成的固件文件烧录就行。但如果你想改轴数、改引脚、调整脉冲频率上限那就需要自己编译。编译环境我推荐 PlatformIO主要是它能把 toolchain、依赖库、烧录工具一次性装好不用手动折腾 arm-none-eabi-gcc。具体步骤先在 VSCode 里装好 PlatformIO 插件然后用它打开固件源码工程目录在 platformio.ini 里确认 board 是 bluepill_f103c8framework 设置为 stm32cube。改好之后点一下 Build几分钟就能编出固件。如果你更熟悉 STM32CubeIDE也完全可以。但要注意GRBL 源码依赖 STM32 HAL 库的定时器、串口、USB 初始化代码这些在 CubeMX 生成工程时必须勾选对应外设否则编译直接报错。我第一次用 CubeIDE 编译的时候就踩了“缺少 USB 设备描述符回调”的坑后来回去看了工程 README 才发现它要求先跑一下 CubeMX 重新生成代码把外设初始化补全。3.2 用 ST-Link Utility 烧录固件最推荐的烧录方式是用 ST-Link V2 调试器因为它走 SWD 接口速度稳定、可靠而且可以顺便检查芯片状态。接线就四根ST-Link 的 SWDIO 接板子的 PA13SWCLK 接 PA14GND 接 GND3.3V 看情况接如果 ST-Link 能从 USB 供电给目标板可以接但我建议还是不要靠 ST-Link 给板子供电因为 Blue Pill 在带电机驱动板的情况下电流需求并不小ST-Link 那点电流很容易被拖垮。打开 STM32 ST-LINK Utility先点 Target - Connect连接成功后会看到芯片型号和 Flash 大小。然后点击 Target - Program选择解压出来的 .hex 或 .bin 文件把地址设为 0x08000000烧录完成后按一下板子上的复位键固件就开始运行了。这里要提醒一个非常常见的问题如果你之前在这块板子上烧过其他程序而且那个程序禁用了 SWD 引脚或者芯片开启了读保护ST-Link 会一直连不上。解决方法是先把 BOOT0 跳线跳到 1让芯片从系统存储器启动而不是从 Flash 启动再用 ST-Link 连接并擦除整个 Flash最后把 BOOT0 跳回 0重新烧录。3.3 没有 ST-Link 时的串口 ISP 烧录手上没有 ST-Link 也没关系用 USB 转 TTL 模块一样能烧走的是芯片内置的串口 ISP 引导程序。把 BOOT0 跳到 1、BOOT1 保持 0PA9 和 PA10 分别接 USB 转 TTL 的 RX 和 TXGND 共地然后用 FlyMcu 或者 STM32CubeProgrammer 的 UART 模式连接。选择串口号、波特率 115200点击读取芯片信息能读到芯片就说明 ISP 链路通了。烧录时需要选择 .hex 文件擦除全片之后写入然后要把 BOOT0 跳回 0再按复位键固件才会从 Flash 启动。这个流程稍微麻烦好处是不需要额外买调试器USB 转 TTL 模块基本人人都有。FlyMcu 这个软件有点老界面也简陋但胜在稳定大部分人烧录 Blue Pill 都是靠它。3.4 连接上位机并执行第一次回测固件烧好之后电脑上插上 USB 线或者接上 USB 转 TTL 模块打开设备管理器看看串口有没有出现。CH340 会出现一个 USB-SERIAL CH340 的 COM 口CP2102 会出现 Silicon Labs CP210x USB to UART Bridge 的 COM 口FT232R 和 FT231X 都会出现 FTDI FT232R USB UART 的 COM 口而板载 USB 虚拟串口则显示为 STMicroelectronics Virtual COM Port。如果没有出现先别慌大概率是驱动问题这个我在第五部分详细说。打开 grbl control 或者 grbl studio选对 COM 口波特率填 115200点击打开连接。正常情况下立刻就能在日志区域看到固件返回的欢迎信息一般是一行类似 “Grbl 1.1h [$ for help]” 的字符串。看到这行字符串就说明固件在正常跑了。我自己习惯先用串口调试助手发一个 ? 命令收到状态报告就说明通信完全畅通。4. GRBL 参数配置与多轴扩展4.1 核心参数速查GRBL 的参数通过$命令来查看和设置。连上上位机之后先发一个$$固件会把当前所有参数全部打印出来。不同版本的参数编号基本兼容我在这里按我自己常用的版本列一份速查表。参数含义典型值$0步进脉冲宽度微秒10 至 20$1步进空闲延时毫秒25$2步进脉冲反转掩码0$3方向反转掩码按需设置$4步进使能反转掩码0$5限位开关反转掩码0$10状态报告选项1$20软限位使能0$21硬限位使能0$22寻零循环使能0$30主轴最大转速255 或 10000$31主轴最小转速0$32激光模式使能0$100X 轴步数/mm按机械结构计算$101Y 轴步数/mm按机械结构计算$102Z 轴步数/mm按机械结构计算$110X 轴最大进给率mm/min按电机能力设置$111Y 轴最大进给率按电机能力设置$112Z 轴最大进给率按电机能力设置$120X 轴加速度mm/s²10 至 100$121Y 轴加速度10 至 100$122Z 轴加速度10 至 100$130X 轴行程范围按机械限位设置$131Y 轴行程范围按机械限位设置$132Z 轴行程范围按机械限位设置其中 $100/$101/$102 是所有人必须改的参数直接决定了电机走多少步才是一毫米。计算公式很简单步进电机固有步数通常 200 步/圈乘以驱动器细分数再除以丝杆导程或者齿轮减速比换算出来的每毫米行程。比如一个 1.8 度的步进电机驱动器设置为 16 细分丝杆导程是 5mm那 X 轴的步数/mm 就是 200 × 16 ÷ 5 640。这个值填错最直观的后果就是 G 代码里走 10mm实际跑出去 8mm 或者 12mm怎么调都对不上图纸尺寸。4.2 三轴到六轴怎么配原版 GRBL 只支持 3 轴而 32 位版固件一般能支持到 6 轴。但这不意味着烧录进去就直接能用 6 轴多出来的 A、B、C 轴通常需要在固件编译阶段就开启或者在参数层面对应轴做一些显式配置。我用的这套固件编译时默认开启了前三轴第四轴 A 轴也要自己打开宏定义然后再重新编译。打开之后$103 就是 A 轴步数/mm$113 是 A 轴最大进给率$123 是 A 轴加速度$133 是 A 轴行程。以此类推B 轴对应 $104/$114/$124/$134C 轴对应 $105/$115/$125/$135。如果你只是把某个轴当作旋转轴比如第四轴做旋转雕刻那步数/mm 需要按旋转轴的角度步数来算而不是线性的 mm 步数。比如一个 200 步的步进电机、16 细分、减速比 5:1那每转一周是 200 × 16 × 5 16000 步对应 360 度步数/度就是 16000 ÷ 360 ≈ 44.44。有一点很重要不是所有固件都默认把 6 轴全部映射到引脚上。如果你需要 5 轴或者 6 轴一定要看固件源码里的 cpu_map 或 pinout确认对应轴位是否已经分配了步进脉冲和方向引脚。如果没有分配那就要自己改引脚映射重新编译难度会稍微高一些但只要盯住定时器通道和 GPIO 配置基本能搞定。4.3 常见配置误区第一个误区改完参数不重启。GRBL 的很多参数尤其是 $100 系列步数/mm 和 $110 系列进给率在修改后需要软复位或者重启固件才能真正生效。你连着 grbl control 改完参数如果不执行重启命令下次发 G 代码走的还是旧参数很容易让人误以为参数没保存。我自己习惯改完就发一个 CtrlX 或者直接按上位机的重置按钮。第二个误区进给率设置过高。很多人刚装好 3 轴兴奋地设了一个 5000mm/min 的进给率实际跑起来电机啸叫、丢步、甚至板子重启。原因很简单脉冲频率超过了固件或者驱动器的承受范围。以 $100640、$1105000 为例这个参数组合下的脉冲频率是 640 × 5000 ÷ 60 ≈ 53.3kHz一般没问题但如果细分再高一点、进给再快一点就很容易超限。所以配置完之后先用低速试跑比如 F100然后逐步加大不要一上来就全速冲刺。第三个误区激光模式搞错。如果你要接激光模块做雕刻$32 必须设为 1。这个参数开启后主轴 PWM 会随着运动指令实时开关否则激光会一直常亮容易烧坏工件而且激光模式下运动轨迹规划的逻辑也不一样不改这个参数雕刻出来的线条边缘会很糊。第四个误区把 Arduino 版 GRBL 的习惯直接套到 32 位版。Arduino 版在改完参数后需要写 EEPROM 保存32 位版虽然也做了 EEPROM 模拟但不同固件版本的保存时机不一样有的版本是在每次参数修改时自动写有的需要手动执行一条特定的存储命令。建议拿到固件后先看 README 里关于参数保存方式的说明免得每次断电都要重新配置一遍。5. 常见问题与排查实录5.1 USB 和串口识别不到这个问题是我被问得最多的也是新手最容易卡住的地方。现象是插上 USB 线电脑一点反应都没有或者设备管理器里出现一个带黄色感叹号的未知设备。处理顺序我建议这样第一步确认线是不是纯充电线很多 USB 线只有电源线没有数据线这种情况在 mini-USB 时代尤其常见换一条线试试第二步看设备管理器里出现的是什么。如果是 CH340 相关的未知设备就去装 CH340 的官方驱动如果是 CP2102去 Silicon Labs 官网下 CP210x 驱动如果是 FTDI 芯片FT232R、FT231X去 FTDI 官网下 VCP 驱动Win10/Win11 下如果系统自动更新装了一个错误版本的 FTDI 驱动一定要手动卸载后装官网新版。特别说一下 STM32 板载 USB 虚拟串口。这种设备依赖固件的 USB 描述符Windows 一般会识别成 COM 端口但偶尔会有识别不到的情况。一个有效的办法是用 Zadig 给这个设备安装 WinUSB 驱动或者去 ST 官网下载并安装 STM32 Virtual COM Port 驱动。如果连设备枚举这一步都没到用 USB Device Tree Viewer 看一下 USB 总线上有没有设备挂载如果能看到设备但无法识别多半是固件 USB 描述符与驱动不兼容如果根本看不到设备请检查 USB 口的 D 上拉电阻和 USB 线的信号线是否正常。Linux 下又是另一套情况但结论很简单设备节点一般是 /dev/ttyACM0 或 /dev/ttyUSB0如果没有权限执行sudo chmod 666 /dev/ttyACM0即可。如果你发现从串口接收数据会丢失最可能是上位机设置的波特率与固件不一致因为 GRBL 默认 115200如果你不小心配到了 9600那根本不可能顺畅通信。5.2 烧录失败的问题排查烧录失败也是高频问题我把常见情况整理成一张表方便你直接对照排查。现象可能原因解决办法ST-Link 连接不上SWD 接线错误、GND 未共地仔细检查 SWDIO、SWCLK、GND 三线必要时用万用表量通断连接成功但烧录时报错芯片读保护开启在 ST-LINK Utility 的 Option Bytes 里将读保护级别改为 Level 0再重新连接烧录完成后板子没反应BOOT0 还在 1固件未从 Flash 启动把 BOOT0 跳回 0按复位键串口 ISP 连不上USB 转 TTL 模块 TX/RX 接反交叉互换 PA9/PA10 两根线烧录后 USB 虚拟串口不出现USB 描述符加载失败或驱动问题用 STM32CubeProgrammer 重新烧录一次并检查固件版本是否支持板载 USB我遇到过最诡异的一次ST-Link 连上了烧录也显示成功但板子就是不工作。后来发现是我忘了把 BOOT0 从 1 跳回 0固件一直停留在 ISP 引导模式。这个错误很小但排查起来很浪费人生写在这里提醒一下。5.3 电机不转、抖动、乱跑固件跑起来了参数也设了结果电机不转或者抖动这是第二个大坑。电机完全不转先查驱动板供电VMOT 有没有接 12V 或者 24V然后查使能引脚A4988 之类的驱动板 EN 引脚默认低电平使能如果固件的使能逻辑是反的需要检查 $4 参数。如果使能没问题再检查步进 PUL 有没有信号可以用示波器量一下引脚没有示波器的话用万用表看电压跳动也行。电机抖动最常见的原因是脉冲频率超出范围。尤其当你用的是高细分驱动板时比如 32 细分$100 参数算出来可能是 6400 步/mm此时 $110 设置个 5000mm/min脉冲频率就高达 6400 × 5000 ÷ 60 ≈ 533kHz这个频率很多普通光耦隔离驱动器都跟不上了。降低细分、降低进给率、提高 $0 脉冲宽度三个方向都能缓解。电机往一个方向疯跑这种一般是方向引脚没接好或者方向映射错误。确认 $3 的方向反转掩码如果 X 轴方向反了把 $3 的 bit0 置 1 就可以反转。另外 DIR 信号和步进脉冲的时序配合也很重要GRBL 里的方向信号会在脉冲之前提前一点建立如果驱动器反应慢可以在固件里调方向建立时间但多数情况下不用动。5.4 上位机连接不上或频繁掉线grbl control 和 grbl studio 都连不上的时候先排查是不是串口被其他程序占用了。Windows 下同一时刻只能有一个程序占用串口如果你开了串口调试助手又开 grbl control那后者必然打不开。关掉其他占用程序再试。还有一种情况是 USB 供电不足导致板子反复复位。现象就是连上后能收到一两条欢迎信息然后立刻消失或者每次点击连接都会听到 Windows 的 USB 拔插声。这时候单独给板子接一个稳定电源问题基本就解决了。grbl studio 连不上的一个细节它默认的波特率是 115200但有些 USB 转 TTL 模块在高波特率下如果线材质量差、干扰大就会丢数据导致连接不稳定。可以尝试把波特率降到 57600 或者 38400然后在固件里重新编译对应波特率配置或者在 grbl studio 里修改串口波特率再测试。写在最后的实操体会这套基于 STM32 的 32 位 GRBL 固件我前前后后用了小半年从最初的 3 轴改到现在的 4 轴最大的感受是可玩性和稳定性都远高于 Arduino 方案但前提是你要耐心把引脚映射和参数配置吃透。拿到固件包的第一时间不是急着接线而是先看源码里的引脚定义确认每个轴对应哪些定时器通道这样才能少烧几块驱动板。一个小技巧分享给你把步数/mm 的计算公式直接存到上位机的参数备注里每次换机械结构直接套用不用重新推导。另一个建议是先把 USB 或串口通信跑通确认能看到固件欢迎信息之后再接电机和机械部分分轴调试时单独发G91 G1 X10 F100这样的短命令逐个方向确认遇到问题就能很快定位到具体是哪个轴、哪个信号出了问题。多轴控制的折腾过程确实费时间但当你看到四个轴同时跟着代码顺畅运动的时候前面那些排查的辛苦一下子就值了。本文还有配套的精品资源点击获取