当前位置: 首页 > news >正文

GRBL 1.1 移植到 STM32 (HAL库)

GRBL 1.1 移植到 STM32 (HAL库) 的核心文件


1. 硬件映射文件 (cpu_map.h)

这个文件定义了 GRBL 抽象的引脚(如 STEP, DIR, LIMIT)对应到 STM32 的具体 GPIO 引脚。

// cpu_map.h
#ifndef cpu_map_h
#define cpu_map_h#include "stm32f4xx_hal.h" // 根据你的芯片修改 (如 stm32f1xx_hal.h)// --- 步进电机引脚定义 (X, Y, Z 轴) ---
#define STEP_PORT       GPIOA
#define X_STEP_PIN      GPIO_PIN_0
#define Y_STEP_PIN      GPIO_PIN_1
#define Z_STEP_PIN      GPIO_PIN_2#define DIR_PORT        GPIOA
#define X_DIR_PIN       GPIO_PIN_3
#define Y_DIR_PIN       GPIO_PIN_4
#define Z_DIR_PIN       GPIO_PIN_5#define ENABLE_PORT     GPIOA
#define STEPPERS_ENABLE_PIN GPIO_PIN_6// --- 限位开关引脚定义 ---
#define LIMIT_PORT      GPIOB
#define X_LIMIT_PIN     GPIO_PIN_12
#define Y_LIMIT_PIN     GPIO_PIN_13
#define Z_LIMIT_PIN     GPIO_PIN_14// --- 控制引脚 (复位, 急停等) ---
#define CONTROL_PORT    GPIOB
#define RESET_PIN       GPIO_PIN_15// --- 主轴控制 (PWM/继电器) ---
#define SPINDLE_PORT    GPIOC
#define SPINDLE_PWM_PIN GPIO_PIN_6 // 假设使用 TIM3_CH1// --- 宏定义:简化 GPIO 操作 ---
#define STEP_PORT_SET(x)    HAL_GPIO_WritePin(STEP_PORT, x, GPIO_PIN_SET)
#define STEP_PORT_CLR(x)    HAL_GPIO_WritePin(STEP_PORT, x, GPIO_PIN_RESET)
#define DIR_PORT_SET(x)     HAL_GPIO_WritePin(DIR_PORT, x, GPIO_PIN_SET)
#define DIR_PORT_CLR(x)     HAL_GPIO_WritePin(DIR_PORT, x, GPIO_PIN_RESET)#endif

2. 步进定时器中断 (stepper.c 修改部分)

GRBL 的核心是一个高频定时器中断,用于计算加减速并输出脉冲。这是移植最难的部分。

需要配置一个 STM32 定时器(如 TIM1) 产生 1ms 或更高频率的中断,然后在中断里调用 GRBL 的步进函数。

// stepper.c (仅展示移植相关的修改)
#include "stm32f4xx_hal.h"
#include "grbl.h"extern TIM_HandleTypeDef htim1; // CubeMX 生成的定时器句柄// 定时器中断回调函数 (在 stm32f4xx_it.c 中会被调用)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if (htim->Instance == TIM1) {// 这里是 GRBL 的心跳// 原 AVR 代码中的 ISR(TIMER1_COMPA_vect) 逻辑放在这里st_isr(); // GRBL 内部的步进中断处理函数}
}// 初始化步进定时器
void st_init() {// 使用 CubeMX 初始化 TIM1// 配置预分频器,使得定时器频率为 1MHz (1us 计数)// 配置周期为 1000 (即 1ms 进入一次中断)HAL_TIM_Base_Start_IT(&htim1);// 初始化 GPIO (调用上面的 cpu_map)GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitStruct.Pin = X_STEP_PIN | Y_STEP_PIN | Z_STEP_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(STEP_PORT, &GPIO_InitStruct);
}

3. 串口重定向 (serial.c)

GRBL 通过串口与 PC 通信。你需要将 AVR 的 USART_Receive 改为 STM32 的 UART。

// serial.c
#include "serial.h"
#include "usart.h" // CubeMX 生成的 USART 头文件// 接收缓冲区
#define RX_RING_BUFFER 256
volatile uint8_t rx_buffer[RX_RING_BUFFER];
volatile uint8_t rx_head = 0;
volatile uint8_t rx_tail = 0;// UART 接收中断回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {if (huart->Instance == USART1) {rx_buffer[rx_head] = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);rx_head = (rx_head + 1) % RX_RING_BUFFER;}
}// GRBL 调用的读字节函数
uint8_t serial_read() {if (rx_head == rx_tail) {return SERIAL_NO_DATA;} else {uint8_t data = rx_buffer[rx_tail];rx_tail = (rx_tail + 1) % RX_RING_BUFFER;return data;}
}// GRBL 调用的写字节函数
void serial_write(uint8_t data) {HAL_UART_Transmit(&huart1, &data, 1, 10);
}void serial_init() {// CubeMX 会自动初始化 UART1// 开启接收中断__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
}

4. EEPROM 模拟 (eeprom.c)

STM32 没有硬件 EEPROM,通常使用 Flash 模拟。

// eeprom.c
#include "eeprom.h"
#include "stm32f4xx_hal_flash.h"#define EEPROM_START_ADDR 0x0800F000 // 使用 Flash 最后一页void memcpy_to_flash(uint32_t addr, void *src, uint32_t len) {HAL_FLASH_Unlock();uint32_t *p = (uint32_t *)src;for(uint32_t i=0; i<len; i+=4) {HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr+i, *p++);}HAL_FLASH_Lock();
}void memcpy_from_flash(void *dst, uint32_t addr, uint32_t len) {uint8_t *p = (uint8_t *)dst;for(uint32_t i=0; i<len; i++) {p[i] = *(__IO uint8_t*)(addr + i);}
}

5. 主函数 (main.c)

将 GRBL 的主循环嵌入到 STM32 的 main 函数中。

// main.c
#include "main.h"
#include "grbl.h"int main(void) {HAL_Init();SystemClock_Config();// CubeMX 初始化外设MX_GPIO_Init();MX_USART1_UART_Init();MX_TIM1_Init(); // 步进定时器// 初始化 GRBL 核心serial_init();settings_init(); // 加载参数st_init();       // 初始化步进电机plan_init();     // 初始化运动规划// 启动 GRBL 协议解析器protocol_main_loop();while (1) {// GRBL 已经在 protocol_main_loop 中死循环了}
}

参考代码 GRBL 移植stm32 www.youwenfan.com/contentcnu/70177.html

移植关键注意事项

  1. 定时器频率:GRBL 对时间极其敏感。原版 AVR 是 16MHz,STM32 是 72/168MHz。你需要调整 config.h 中的 F_CPU 宏定义,或者在定时器预分频器中做等效换算,否则会导致 进给速度(Feed Rate)快 10 倍
  2. 中断优先级:STM32 的中断有抢占优先级。串口中断 的优先级必须高于 定时器中断,否则在发送大量状态时可能会阻塞步进脉冲,导致丢步。
  3. 引脚电平反转:如果你的驱动器是高电平有效,而 GRBL 默认是低电平有效(或反之),记得在 cpu_map.h 中修改宏定义,或者在 settings.c 中设置 $3 参数(方向取反)。
http://www.jsqmd.com/news/821571/

相关文章:

  • 开源量化交易框架openclaw-autotrader:架构解析与实战指南
  • 从零上手ScreenToGif:在Windows上轻松录制与编辑GIF动图
  • 如何在3分钟内掌握gInk:Windows上最轻量的免费屏幕标注工具终极指南
  • STM32F407标准库工程模板详解:从文件夹结构到第一个LED闪烁(MDK5环境)
  • ChatGPT Web共享方案:低成本实现团队AI协作部署指南
  • 软件工程师的终结?当 AI 代理让开发门槛降为零,硬核开发者的底牌是什么
  • H.264编码核心:从宏块到GOP的压缩艺术
  • ADS仿真结果别再只会看S参数了!手把手教你用函数表达式和Marker玩转数据绘图
  • 从零到一:Windows桌面应用自动化测试框架搭建全记录与避坑指南
  • Android 系统将预装语音输入法;Inworld 发布 Realtime Router:为对话式 AI 实时调度 100+LLM 丨日报
  • 计算机视觉注意力机制演进:从SENet到ViT的脉络与启示
  • 前端自动化构建工具Abra:零配置集成Vite与esbuild的工程实践
  • 在Rockchip RK3588开发板上,用Qt 5.15.0和OpenGL ES2跑起第一个3D程序(保姆级避坑指南)
  • FPGA实战:SPI总线驱动Flash存储全解析(时序与模块设计)
  • fastRAG:基于CPU优化的RAG性能加速方案与实战指南
  • 学生机票怎么订最便宜?高考毕业季“捡漏”攻略+城市推荐
  • Vivado IP核封装实战:从零到一构建自定义AXI-Stream接口模块
  • 如何快速掌握League Akari:英雄联盟玩家的完整效率工具指南
  • 智能电表mSure®技术:从实时诊断到预测性维护的实践解析
  • Yuzu模拟器进阶配置指南:解锁多核、图形优化与着色器缓存,让你的Switch游戏帧数更稳定
  • RK3568开发实战:基于buildroot定制开机自启Qt应用,彻底解决全屏显示与任务栏冲突
  • JetBrains IDE试用期重置终极指南:3分钟快速恢复30天免费试用
  • Overleaf投稿Elsevier期刊,手把手教你搞定.sty文件和PDF生成(避坑指南)
  • Adobe GenP 3.0 完整使用指南:轻松解锁Adobe CC全系列软件
  • AI时代技能大升级:小白程序员必备的收藏学习攻略!
  • 开源桌面宠物应用开发指南:从原理到实践
  • 中性盐雾试验箱知名品牌|质量好、售后稳、性价比高厂家盘点 - 品牌推荐大师
  • 图像分割‘元老’分水岭算法:从地理概念到Matlab仿真,理解它的前世今生与局限
  • Termux环境集成Gemini AI:移动端命令行AI助手实战指南
  • 从Cityscapes到自定义数据集:如何用PyTorch微调DeeplabV3+的ASPP模块提升分割效果?