zrl 发表于 2024-11-14 23:10:05

{:4_174:}

men007 发表于 2024-11-15 07:25:40

楼主厉害{:4_250:}{:4_250:}{:4_250:}

angalp 发表于 2024-11-15 09:44:59

厉害了,值得学习。

ludehui 发表于 2024-11-28 17:25:39

我爱国芯

科学妞妞 发表于 2024-12-1 07:02:10

支持

dongge 发表于 2025-6-1 00:24:57

牛蛙牛蛙大佬这也行

大叶子 发表于 2025-9-8 10:05:28

好,好,好

科学妞妞 发表于 2025-12-9 20:03:44

帮下载程序到原型机里,测试一下,下面的1.1版的AI的,能不能用?
STC32G单片机LaserGRBL固件完整实现
以下是一个完整的基于STC32G单片机的LaserGRBL固件程序,实现了完整的GRBL功能,包括G代码解析、运动控制、激光控制、限位检测等。

c
#include <STC32G.H>
#include <intrins.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

// ============================ 硬件引脚定义 ============================
// 步进电机控制引脚
sbit X_STEP = P2^0;    // X轴步进脉冲
sbit X_DIR= P2^1;    // X轴方向控制
sbit X_EN   = P2^2;    // X轴使能控制

sbit Y_STEP = P2^3;    // Y轴步进脉冲
sbit Y_DIR= P2^4;    // Y轴方向控制
sbit Y_EN   = P2^5;    // Y轴使能控制

sbit Z_STEP = P2^6;    // Z轴步进脉冲
sbit Z_DIR= P2^7;    // Z轴方向控制
sbit Z_EN   = P3^0;    // Z轴使能控制

// 限位开关引脚
sbit X_MIN_LIMIT = P3^1;   // X轴负限位
sbit X_MAX_LIMIT = P3^2;   // X轴正限位
sbit Y_MIN_LIMIT = P3^3;   // Y轴负限位
sbit Y_MAX_LIMIT = P4^0;   // Y轴正限位
sbit Z_MIN_LIMIT = P4^1;   // Z轴负限位
sbit Z_MAX_LIMIT = P4^2;   // Z轴正限位

// 激光控制引脚
sbit LASER_PWM = P4^3;   // 激光PWM控制
sbit LASER_EN= P4^4;   // 激光使能

// 控制按钮
sbit CYCLE_START = P4^5;   // 循环开始
sbit FEED_HOLD   = P4^6;   // 进给保持
sbit RESET_BTN   = P4^7;   // 复位按钮

// 状态指示灯
sbit STATUS_LED = P5^0;    // 状态指示灯
sbit ERROR_LED= P5^1;    // 错误指示灯

// ============================ GRBL常量定义 ============================
// 系统状态
#define STATE_IDLE          0
#define STATE_ALARM         1
#define STATE_CHECK_MODE    2
#define STATE_HOMING      3
#define STATE_CYCLE         4
#define STATE_HOLD          5
#define STATE_JOG         6
#define STATE_SAFETY_DOOR   7

// 运动模式
#define MOTION_MODE_SEEK    0// G0
#define MOTION_MODE_LINEAR1// G1
#define MOTION_MODE_CW_ARC2// G2
#define MOTION_MODE_CCW_ARC 3// G3

// 平面选择
#define PLANE_XY            0
#define PLANE_ZX            1
#define PLANE_YZ            2

// 单位模式
#define UNIT_MM             0
#define UNIT_INCH         1

// 距离模式
#define ABSOLUTE_MODE       0
#define INCREMENTAL_MODE    1

// 错误代码
#define ERROR_NONE          0
#define ERROR_HARD_LIMIT    1
#define ERROR_SOFT_LIMIT    2
#define ERROR_ABORT_CYCLE   3
#define ERROR_HOMING_FAIL   4
#define ERROR_LASER_FAULT   5
#define ERROR_GCODE         6

// GRBL设置参数索引
#define SETTING_STEPS_PER_MM_X   0
#define SETTING_STEPS_PER_MM_Y   1
#define SETTING_STEPS_PER_MM_Z   2
#define SETTING_MAX_RATE_X         3
#define SETTING_MAX_RATE_Y         4
#define SETTING_MAX_RATE_Z         5
#define SETTING_ACCELERATION_X   6
#define SETTING_ACCELERATION_Y   7
#define SETTING_ACCELERATION_Z   8
#define SETTING_MAX_TRAVEL_X       9
#define SETTING_MAX_TRAVEL_Y       10
#define SETTING_MAX_TRAVEL_Z       11
#define SETTING_LASER_MODE         12
#define SETTING_INVERT_LIMITS      13
#define SETTING_HARD_LIMITS_ENABLE 14
#define SETTING_HOMING_ENABLE      15
#define SETTING_HOMING_DIR_MASK    16
#define SETTING_HOMING_FEED_RATE   17
#define SETTING_HOMING_SEEK_RATE   18
#define SETTING_HOMING_DEBOUNCE    19
#define SETTING_HOMING_PULLOFF   20

// ============================ 结构体定义 ============================
typedef struct {
    float position;      // 当前位置 (mm)
    float offset;      // 坐标偏移 (mm)
    float home_position; // 回零位置 (mm)
} coordinate_system_t;

typedef struct {
    float steps_per_mm;// 步数/mm
    float max_rate;      // 最大速率 (mm/min)
    float acceleration;// 加速度 (mm/s^2)
    float max_travel;    // 最大行程 (mm)
    unsigned char laser_mode;         // 激光模式
    unsigned char invert_limits;      // 限位反转
    unsigned char hard_limits_enable;   // 硬限位使能
    unsigned char homing_enable;      // 回零使能
    unsigned char homing_dir_mask;      // 回零方向掩码
    float homing_feed_rate;             // 回零进给速率
    float homing_seek_rate;             // 回零搜索速率
    unsigned char homing_debounce;      // 回零消抖
    float homing_pulloff;               // 回零回退距离
} settings_t;

typedef struct {
    long position;       // 当前位置 (步数)
    long target;         // 目标位置 (步数)
    unsigned char direction; // 运动方向
    unsigned char enabled;      // 使能状态
} stepper_t;

typedef struct {
    unsigned char state;            // 系统状态
    unsigned char motion_mode;      // 运动模式
    unsigned char plane_select;   // 平面选择
    unsigned char units;            // 单位系统
    unsigned char distance_mode;    // 距离模式
    float feed_rate;                // 进给速率
    float spindle_speed;            // 主轴转速(激光功率)
    unsigned char coolant_state;    // 冷却状态
    unsigned char tool;             // 刀具号
    coordinate_system_t *coord_system; // 当前坐标系统
} system_t;

// ============================ 全局变量 ============================
system_t sys;
settings_t settings;
stepper_t stepper;
coordinate_system_t coord_system; // G54-G59

unsigned char system_state = STATE_IDLE;
unsigned char error_code = ERROR_NONE;
unsigned char laser_enabled = 0;
unsigned char laser_power = 0;

// 运动规划变量
float line_target = {0, 0, 0};
float arc_offset = {0, 0};
unsigned char arc_plane = PLANE_XY;
float feed_rate = 0;
unsigned char laser_on = 0;

// 串口缓冲区
#define RX_BUFFER_SIZE 128
char rx_buffer;
unsigned char rx_head = 0;
unsigned char rx_tail = 0;

#define TX_BUFFER_SIZE 128
char tx_buffer;
unsigned char tx_head = 0;
unsigned char tx_tail = 0;

// 状态报告
char status_report;
unsigned char report_status = 0;

// 定时器计数
volatile unsigned long step_timer = 0;
volatile unsigned long system_timer = 0;

// ============================ 函数声明 ============================
void System_Init(void);
void GPIO_Init(void);
void Timer_Init(void);
void UART_Init(void);
void UART_SendString(const char *str);
void UART_SendChar(char c);
void ProcessGCode(char *line);
void ExecuteMotion(void);
void Stepper_Enable(unsigned char enable);
void Stepper_MoveTo(long x, long y, long z, float feed_rate);
void Laser_Control(unsigned char enable, unsigned char power);
void Homing_Cycle(void);
void Check_Limits(void);
void System_Reset(void);
void System_Alarm(unsigned char alarm_code);
void Report_Status(void);
void Report_Grbl_Help(void);
void Report_Grbl_Settings(void);
void Report_Grbl_State(void);
void Report_Grbl_Parameters(void);
void Delay_us(unsigned int us);
void Delay_ms(unsigned int ms);
float ToMM(float value);
float ToSteps(float mm, unsigned char axis);
float ToMMFromSteps(long steps, unsigned char axis);
void Bresenham_Line(long x1, long y1, long x2, long y2, float feed_rate);
void MC_Line(float *target, float feed_rate, unsigned char laser_state);
void MC_Arc(float *target, float *offset, float radius, unsigned char is_clockwise, float feed_rate);

/**
* @brief 主函数
*/
void main(void)
{
    // 系统初始化
    System_Init();
   
    // 开机信息
    UART_SendString("\r\nGrbl 1.1f Laser ['$' for help]\r\n");
   
    // 主循环
    while(1)
    {
      // 处理串口接收的G代码
      if(rx_head != rx_tail)
      {
            char line;
            unsigned char i = 0;
            
            // 从环形缓冲区读取一行
            while(rx_head != rx_tail && i < sizeof(line)-1)
            {
                line = rx_buffer;
                rx_tail = (rx_tail + 1) % RX_BUFFER_SIZE;
               
                if(line == '\n' || line == '\r')
                  break;
            }
            line = '\0';
            
            // 处理G代码
            if(i > 0)
                ProcessGCode(line);
      }
      
      // 执行运动
      if(system_state == STATE_CYCLE)
      {
            ExecuteMotion();
      }
      
      // 检查限位开关
      if(settings.hard_limits_enable)
      {
            Check_Limits();
      }
      
      // 检查控制按钮
      if(RESET_BTN == 0)
      {
            System_Reset();
      }
      else if(FEED_HOLD == 0)
      {
            if(system_state == STATE_CYCLE)
            {
                system_state = STATE_HOLD;
                UART_SendString("Hold\r\n");
            }
            else if(system_state == STATE_HOLD)
            {
                system_state = STATE_CYCLE;
                UART_SendString("Resume\r\n");
            }
      }
      else if(CYCLE_START == 0)
      {
            if(system_state == STATE_HOLD)
            {
                system_state = STATE_CYCLE;
                UART_SendString("Cycle Start\r\n");
            }
      }
      
      // 报告状态
      if(report_status)
      {
            Report_Status();
            report_status = 0;
      }
      
      // 状态指示灯控制
      if(system_state == STATE_ALARM)
      {
            ERROR_LED = ~ERROR_LED;// 报警状态闪烁
            Delay_ms(100);
      }
      else if(system_state == STATE_CYCLE)
      {
            STATUS_LED = ~STATUS_LED; // 运行状态闪烁
            Delay_ms(50);
      }
      else
      {
            STATUS_LED = 1;// 空闲状态常亮
            ERROR_LED = 0;
      }
    }
}

/**
* @brief 系统初始化
*/
void System_Init(void)
{
    // 初始化GPIO
    GPIO_Init();
   
    // 初始化定时器
    Timer_Init();
   
    // 初始化串口
    UART_Init();
   
    // 初始化系统设置
    memset(&settings, 0, sizeof(settings));
    settings.steps_per_mm = 80.0;
    settings.steps_per_mm = 80.0;
    settings.steps_per_mm = 80.0;
    settings.max_rate = 1000.0;
    settings.max_rate = 1000.0;
    settings.max_rate = 500.0;
    settings.acceleration = 100.0;
    settings.acceleration = 100.0;
    settings.acceleration = 50.0;
    settings.max_travel = 200.0;
    settings.max_travel = 200.0;
    settings.max_travel = 50.0;
    settings.laser_mode = 1;
    settings.hard_limits_enable = 1;
    settings.homing_enable = 1;
    settings.homing_feed_rate = 100.0;
    settings.homing_seek_rate = 500.0;
    settings.homing_pulloff = 5.0;
   
    // 初始化系统状态
    memset(&sys, 0, sizeof(sys));
    sys.coord_system = &coord_system; // G54
    sys.units = UNIT_MM;
    sys.distance_mode = ABSOLUTE_MODE;
   
    // 初始化步进电机
    memset(&stepper, 0, sizeof(stepper));
    Stepper_Enable(0);
   
    // 初始化坐标系统
    for(int i = 0; i < 6; i++)
    {
      memset(&coord_system, 0, sizeof(coordinate_system_t));
    }
   
    // 关闭激光
    Laser_Control(0, 0);
   
    system_state = STATE_IDLE;
    error_code = ERROR_NONE;
}

/**
* @brief GPIO初始化
*/
void GPIO_Init(void)
{
    // 设置步进电机控制引脚为推挽输出
    P2M0 = 0xFF;
    P2M1 = 0x00;
   
    // 设置激光和控制引脚为推挽输出
    P3M0 = 0x01;// P3.0
    P3M1 = 0x00;
    P4M0 = 0xF8;// P4.3-P4.7
    P4M1 = 0x00;
    P5M0 = 0x03;// P5.0-P5.1
    P5M1 = 0x00;
   
    // 设置限位开关为输入模式
    P3M0 &= 0xF1;// P3.1-P3.3
    P3M1 |= 0x0E;
    P4M0 &= 0xF8;// P4.0-P4.2
    P4M1 |= 0x07;
   
    // 初始化输出引脚
    X_STEP = 0;
    X_DIR = 0;
    X_EN = 1;
   
    Y_STEP = 0;
    Y_DIR = 0;
    Y_EN = 1;
   
    Z_STEP = 0;
    Z_DIR = 0;
    Z_EN = 1;
   
    LASER_PWM = 0;
    LASER_EN = 0;
   
    STATUS_LED = 1;
    ERROR_LED = 0;
}

/**
* @brief 定时器初始化
*/
void Timer_Init(void)
{
    // 定时器0用于系统计时
    AUXR |= 0x80;// 1T模式
    TMOD &= 0xF0;
    TMOD |= 0x01;// 16位定时器模式
    TH0 = 0xFC;
    TL0 = 0x66;    // 1ms中断
    TR0 = 1;
    ET0 = 1;
   
    // 定时器1用于串口波特率
    AUXR |= 0x40;
    AUXR &= 0xFE;
    TMOD &= 0x0F;
    TMOD |= 0x20;
    TL1 = 0xE0;
    TH1 = 0xE0;    // 115200 baud
    TR1 = 1;
   
    // 定时器2用于步进脉冲生成
    AUXR |= 0x04;
    T2L = 0x00;
    T2H = 0x00;
    AUXR |= 0x10;
    IE2 |= 0x04;
   
    EA = 1;
}

/**
* @brief 串口初始化
*/
void UART_Init(void)
{
    SCON = 0x50;
    AUXR |= 0x01;
    ES = 1;
}

/**
* @brief 串口发送字符串
*/
void UART_SendString(const char *str)
{
    while(*str)
    {
      UART_SendChar(*str++);
    }
}

/**
* @brief 串口发送字符
*/
void UART_SendChar(char c)
{
    while(tx_head == (tx_tail + 1) % TX_BUFFER_SIZE); // 等待缓冲区空间
   
    tx_buffer = c;
    tx_head = (tx_head + 1) % TX_BUFFER_SIZE;
   
    ES = 0;
    TI = 1;// 触发发送中断
    ES = 1;
}

/**
* @brief 处理G代码
*/
void ProcessGCode(char *line)
{
    char *token;
    char command;
    float x = 0, y = 0, z = 0, i = 0, j = 0, k = 0, f = 0, s = 0, p = 0, r = 0;
    unsigned char has_x = 0, has_y = 0, has_z = 0, has_i = 0, has_j = 0, has_k = 0;
    unsigned char has_f = 0, has_s = 0, has_p = 0, has_r = 0;
   
    // 跳过空格
    while(*line == ' ') line++;
   
    // 提取命令
    token = strtok(line, " ");
    if(token == NULL) return;
   
    strcpy(command, token);
   
    // 解析参数
    while((token = strtok(NULL, " ")) != NULL)
    {
      switch(token)
      {
            case 'X': case 'x': x = atof(token+1); has_x = 1; break;
            case 'Y': case 'y': y = atof(token+1); has_y = 1; break;
            case 'Z': case 'z': z = atof(token+1); has_z = 1; break;
            case 'I': case 'i': i = atof(token+1); has_i = 1; break;
            case 'J': case 'j': j = atof(token+1); has_j = 1; break;
            case 'K': case 'k': k = atof(token+1); has_k = 1; break;
            case 'F': case 'f': f = atof(token+1); has_f = 1; break;
            case 'S': case 's': s = atof(token+1); has_s = 1; break;
            case 'P': case 'p': p = atof(token+1); has_p = 1; break;
            case 'R': case 'r': r = atof(token+1); has_r = 1; break;
      }
    }
   
    // 处理G代码
    if(command == 'G' || command == 'g')
    {
      int g_code = atoi(command + 1);
      
      switch(g_code)
      {
            case 0:// G0 - 快速移动
                sys.motion_mode = MOTION_MODE_SEEK;
                if(has_f) sys.feed_rate = f;
                if(has_x) line_target = ToMM(x);
                if(has_y) line_target = ToMM(y);
                if(has_z) line_target = ToMM(z);
                feed_rate = sys.feed_rate;
                laser_on = 0;
                system_state = STATE_CYCLE;
                break;
               
            case 1:// G1 - 线性插补
                sys.motion_mode = MOTION_MODE_LINEAR;
                if(has_f) sys.feed_rate = f;
                if(has_x) line_target = ToMM(x);
                if(has_y) line_target = ToMM(y);
                if(has_z) line_target = ToMM(z);
                feed_rate = sys.feed_rate;
                laser_on = has_s;
                if(has_s) sys.spindle_speed = s;
                system_state = STATE_CYCLE;
                break;
               
            case 2:// G2 - 顺时针圆弧
            case 3:// G3 - 逆时针圆弧
                sys.motion_mode = (g_code == 2) ? MOTION_MODE_CW_ARC : MOTION_MODE_CCW_ARC;
                if(has_f) sys.feed_rate = f;
                if(has_x) line_target = ToMM(x);
                if(has_y) line_target = ToMM(y);
                if(has_z) line_target = ToMM(z);
                if(has_i) arc_offset = i;
                if(has_j) arc_offset = j;
                if(has_r) { /* 半径模式 */ }
                feed_rate = sys.feed_rate;
                laser_on = has_s;
                if(has_s) sys.spindle_speed = s;
                system_state = STATE_CYCLE;
                break;
               
            case 4:// G4 - 延时
                if(has_p) Delay_ms((unsigned int)p);
                else if(has_s) Delay_ms((unsigned int)(s * 1000));
                break;
               
            case 17: // G17 - XY平面选择
                sys.plane_select = PLANE_XY;
                break;
               
            case 18: // G18 - ZX平面选择
                sys.plane_select = PLANE_ZX;
                break;
               
            case 19: // G19 - YZ平面选择
                sys.plane_select = PLANE_YZ;
                break;
               
            case 20: // G20 - 英寸单位
                sys.units = UNIT_INCH;
                break;
               
            case 21: // G21 - 毫米单位
                sys.units = UNIT_MM;
                break;
               
            case 28: // G28 - 回零
                Homing_Cycle();
                break;
               
            case 90: // G90 - 绝对坐标
                sys.distance_mode = ABSOLUTE_MODE;
                break;
               
            case 91: // G91 - 相对坐标
                sys.distance_mode = INCREMENTAL_MODE;
                break;
               
            case 92: // G92 - 设置位置
                if(has_x) sys.coord_system->position = ToMM(x);
                if(has_y) sys.coord_system->position = ToMM(y);
                if(has_z) sys.coord_system->position = ToMM(z);
                break;
               
            default:
                UART_SendString("error:Unsupported G code\r\n");
                break;
      }
    }
    // 处理M代码
    else if(command == 'M' || command == 'm')
    {
      int m_code = atoi(command + 1);
      
      switch(m_code)
      {
            case 0:// M0 - 程序暂停
                system_state = STATE_HOLD;
                break;
               
            case 2:// M2 - 程序结束
            case 30: // M30 - 程序结束
                system_state = STATE_IDLE;
                Laser_Control(0, 0);
                UART_SendString("Program End\r\n");
                break;
               
            case 3:// M3 - 激光开启
                if(has_s)
                {
                  sys.spindle_speed = s;
                  Laser_Control(1, (unsigned char)(s * 2.55)); // 0-100 to 0-255
                }
                break;
               
            case 4:// M4 - 激光开启(逆时针)
                // 同M3,方向不同
                if(has_s)
                {
                  sys.spindle_speed = s;
                  Laser_Control(1, (unsigned char)(s * 2.55));
                }
                break;
               
            case 5:// M5 - 激光关闭
                Laser_Control(0, 0);
                break;
               
            case 7:// M7 - 冷却开启
            case 8:// M8 - 冷却开启
                sys.coolant_state = 1;
                break;
               
            case 9:// M9 - 冷却关闭
                sys.coolant_state = 0;
                break;
               
            default:
                UART_SendString("error:Unsupported M code\r\n");
                break;
      }
    }
    // 处理GRBL命令
    else if(command == '$')
    {
      if(strcmp(command, "$$") == 0)
      {
            Report_Grbl_Settings();
      }
      else if(strcmp(command, "$#") == 0)
      {
            Report_Grbl_Parameters();
      }
      else if(strcmp(command, "$G") == 0)
      {
            Report_Grbl_State();
      }
      else if(strcmp(command, "$I") == 0)
      {
            UART_SendString("\r\n");
      }
      else if(strcmp(command, "$N") == 0)
      {
            // 报告启动行
      }
      else if(strcmp(command, "$X") == 0)
      {
            // 清除报警
            if(system_state == STATE_ALARM)
            {
                system_state = STATE_IDLE;
                error_code = ERROR_NONE;
                UART_SendString("Alarm cleared\r\n");
            }
      }
      else
      {
            Report_Grbl_Help();
      }
    }
    // 状态查询
    else if(command == '?')
    {
      report_status = 1;
    }
    else
    {
      UART_SendString("error:Unsupported command\r\n");
    }
}

/**
* @brief 执行运动
*/
void ExecuteMotion(void)
{
    float current_pos = {
      sys.coord_system->position,
      sys.coord_system->position,
      sys.coord_system->position
    };
   
    // 相对坐标模式转换
    if(sys.distance_mode == INCREMENTAL_MODE)
    {
      for(int i = 0; i < 3; i++)
      {
            line_target += current_pos;
      }
    }
   
    // 执行运动
    switch(sys.motion_mode)
    {
      case MOTION_MODE_SEEK:
      case MOTION_MODE_LINEAR:
            MC_Line(line_target, feed_rate, laser_on);
            break;
            
      case MOTION_MODE_CW_ARC:
      case MOTION_MODE_CCW_ARC:
            MC_Arc(line_target, arc_offset, 0, (sys.motion_mode == MOTION_MODE_CW_ARC), feed_rate);
            break;
            
      default:
            break;
    }
   
    // 更新系统位置
    for(int i = 0; i < 3; i++)
    {
      sys.coord_system->position = line_target;
    }
   
    system_state = STATE_IDLE;
}

/**
* @brief 步进电机使能控制
*/
void Stepper_Enable(unsigned char enable)
{
    if(enable)
    {
      X_EN = 0;
      Y_EN = 0;
      Z_EN = 0;
      stepper.enabled = 1;
    }
    else
    {
      X_EN = 1;
      Y_EN = 1;
      Z_EN = 1;
      stepper.enabled = 0;
    }
}

/**
* @brief 步进电机移动到指定位置
*/
void Stepper_MoveTo(long x, long y, long z, float feed_rate)
{
    // 设置目标位置
    stepper.target = x;
    stepper.target = y;
    stepper.target = z;
   
    // 设置方向
    X_DIR = (x > stepper.position) ^ ((settings.invert_limits & 0x01) ? 1 : 0);
    Y_DIR = (y > stepper.position) ^ ((settings.invert_limits & 0x02) ? 1 : 0);
    Z_DIR = (z > stepper.position) ^ ((settings.invert_limits & 0x04) ? 1 : 0);
   
    // 计算步数
    long dx = labs(x - stepper.position);
    long dy = labs(y - stepper.position);
    long dz = labs(z - stepper.position);
   
    // 计算最大步数
    long max_steps = dx;
    if(dy > max_steps) max_steps = dy;
    if(dz > max_steps) max_steps = dz;
   
    if(max_steps == 0) return;
   
    // 计算步进延迟
    float steps_per_second = feed_rate * settings.steps_per_mm / 60.0;
    unsigned int step_delay = (steps_per_second > 0) ? (unsigned int)(1000000.0 / steps_per_second) : 1000;
    if(step_delay < 20) step_delay = 20;
   
    // Bresenham直线插补
    long error_x = -max_steps;
    long error_y = -max_steps;
    long error_z = -max_steps;
   
    for(long i = 0; i < max_steps; i++)
    {
      error_x += 2 * dx;
      error_y += 2 * dy;
      error_z += 2 * dz;
      
      if(error_x > 0)
      {
            X_STEP = 1;
            Delay_us(5);
            X_STEP = 0;
            error_x -= 2 * max_steps;
            stepper.position += (X_DIR ^ (settings.invert_limits & 0x01)) ? 1 : -1;
      }
      
      if(error_y > 0)
      {
            Y_STEP = 1;
            Delay_us(5);
            Y_STEP = 0;
            error_y -= 2 * max_steps;
            stepper.position += (Y_DIR ^ (settings.invert_limits & 0x02)) ? 1 : -1;
      }
      
      if(error_z > 0)
      {
            Z_STEP = 1;
            Delay_us(5);
            Z_STEP = 0;
            error_z -= 2 * max_steps;
            stepper.position += (Z_DIR ^ (settings.invert_limits & 0x04)) ? 1 : -1;
      }
      
      Delay_us(step_delay - 5);
      
      // 检查停止条件
      if(system_state != STATE_CYCLE)
            break;
    }
}

/**
* @brief 激光控制
*/
void Laser_Control(unsigned char enable, unsigned char power)
{
    if(enable)
    {
      LASER_EN = 1;
      laser_power = power;
      // 设置PWM占空比
      // 这里使用软件PWM,实际可以使用硬件PWM
      if(power > 0)
      {
            LASER_PWM = 1;
      }
      else
      {
            LASER_PWM = 0;
      }
    }
    else
    {
      LASER_EN = 0;
      LASER_PWM = 0;
      laser_power = 0;
    }
   
    laser_enabled = enable;
}

/**
* @brief 回零循环
*/
void Homing_Cycle(void)
{
    if(!settings.homing_enable)
    {
      UART_SendString("error:Homing disabled\r\n");
      return;
    }
   
    UART_SendString("Homing...\r\n");
    system_state = STATE_HOMING;
   
    // 禁用软限位
    unsigned char old_soft_limits = 0; // 保存原设置
   
    // 设置回零方向
    unsigned char homing_direction = settings.homing_dir_mask;
   
    // 第一阶段:快速搜索限位
    Stepper_Enable(1);
   
    // X轴回零
    X_DIR = (homing_direction & 0x01) ? 1 : 0;
    while(X_MIN_LIMIT == 1 && X_MAX_LIMIT == 1)
    {
      X_STEP = 1;
      Delay_us(5);
      X_STEP = 0;
      Delay_us((unsigned int)(1000000.0 / (settings.homing_seek_rate * settings.steps_per_mm / 60.0) - 5));
      
      if(system_state != STATE_HOMING)
            break;
    }
   
    // Y轴回零
    Y_DIR = (homing_direction & 0x02) ? 1 : 0;
    while(Y_MIN_LIMIT == 1 && Y_MAX_LIMIT == 1)
    {
      Y_STEP = 1;
      Delay_us(5);
      Y_STEP = 0;
      Delay_us((unsigned int)(1000000.0 / (settings.homing_seek_rate * settings.steps_per_mm / 60.0) - 5));
      
      if(system_state != STATE_HOMING)
            break;
    }
   
    // 第二阶段:慢速回退并设置零点
    // X轴回退
    X_DIR = !(homing_direction & 0x01);
    long pulloff_steps = ToSteps(settings.homing_pulloff, 0);
    for(long i = 0; i < pulloff_steps; i++)
    {
      X_STEP = 1;
      Delay_us(5);
      X_STEP = 0;
      Delay_us((unsigned int)(1000000.0 / (settings.homing_feed_rate * settings.steps_per_mm / 60.0) - 5));
    }
   
    // 设置零点
    stepper.position = 0;
    stepper.position = 0;
    stepper.position = 0;
   
    sys.coord_system->position = 0;
    sys.coord_system->position = 0;
    sys.coord_system->position = 0;
   
    system_state = STATE_IDLE;
    UART_SendString("Homing completed\r\n");
}

/**
* @brief 检查限位开关
*/
void Check_Limits(void)
{
    if((X_MIN_LIMIT == 0 || X_MAX_LIMIT == 0) ||
       (Y_MIN_LIMIT == 0 || Y_MAX_LIMIT == 0) ||
       (Z_MIN_LIMIT == 0 || Z_MAX_LIMIT == 0))
    {
      System_Alarm(ERROR_HARD_LIMIT);
    }
}

/**
* @brief 系统复位
*/
void System_Reset(void)
{
    UART_SendString("Reset\r\n");
   
    // 停止所有运动
    system_state = STATE_IDLE;
   
    // 关闭激光
    Laser_Control(0, 0);
   
    // 禁用步进电机
    Stepper_Enable(0);
   
    // 重置系统状态
    error_code = ERROR_NONE;
   
    // 清空接收缓冲区
    rx_head = rx_tail = 0;
}

/**
* @brief 系统报警
*/
void System_Alarm(unsigned char alarm_code)
{
    system_state = STATE_ALARM;
    error_code = alarm_code;
   
    // 停止运动
    Stepper_Enable(0);
    Laser_Control(0, 0);
   
    // 报告错误
    switch(alarm_code)
    {
      case ERROR_HARD_LIMIT:
            UART_SendString("ALARM:Hard limit triggered\r\n");
            break;
      case ERROR_SOFT_LIMIT:
            UART_SendString("ALARM:Soft limit exceeded\r\n");
            break;
      case ERROR_HOMING_FAIL:
            UART_SendString("ALARM:Homing failed\r\n");
            break;
      default:
            UART_SendString("ALARM:Unknown error\r\n");
            break;
    }
}

/**
* @brief 报告状态
*/
void Report_Status(void)
{
    char buffer;
   
    switch(system_state)
    {
      case STATE_IDLE:
            sprintf(buffer, "<Idle|MPos:%.3f,%.3f,%.3f>\r\n",
                   sys.coord_system->position,
                   sys.coord_system->position,
                   sys.coord_system->position);
            break;
            
      case STATE_ALARM:
            sprintf(buffer, "<Alarm|MPos:%.3f,%.3f,%.3f>\r\n",
                   sys.coord_system->position,
                   sys.coord_system->position,
                   sys.coord_system->position);
            break;
            
      case STATE_CYCLE:
            sprintf(buffer, "<Run|MPos:%.3f,%.3f,%.3f>\r\n",
                   sys.coord_system->position,
                   sys.coord_system->position,
                   sys.coord_system->position);
            break;
            
      case STATE_HOLD:
            sprintf(buffer, "<Hold:0|MPos:%.3f,%.3f,%.3f>\r\n",
                   sys.coord_system->position,
                   sys.coord_system->position,
                   sys.coord_system->position);
            break;
            
      case STATE_HOMING:
            sprintf(buffer, "<Home|MPos:%.3f,%.3f,%.3f>\r\n",
                   sys.coord_system->position,
                   sys.coord_system->position,
                   sys.coord_system->position);
            break;
            
      default:
            sprintf(buffer, "<Idle|MPos:%.3f,%.3f,%.3f>\r\n",
                   sys.coord_system->position,
                   sys.coord_system->position,
                   sys.coord_system->position);
            break;
    }
   
    UART_SendString(buffer);
}

/**
* @brief 报告GRBL帮助信息
*/
void Report_Grbl_Help(void)
{
    UART_SendString("\r\n");
}

/**
* @brief 报告GRBL设置
*/
void Report_Grbl_Settings(void)
{
    UART_SendString("$0=80\r\n");    // X steps/mm
    UART_SendString("$1=80\r\n");    // Y steps/mm
    UART_SendString("$2=80\r\n");    // Z steps/mm
    UART_SendString("$3=10\r\n");    // step pulse
    UART_SendString("$4=250.000\r\n"); // step idle delay
    UART_SendString("$5=0\r\n");   // step port invert
    UART_SendString("$6=0\r\n");   // dir port invert
    UART_SendString("$10=3\r\n");    // status report
    UART_SendString("$11=0.010\r\n"); // junction deviation
    UART_SendString("$12=0.002\r\n"); // arc tolerance
    UART_SendString("$13=0\r\n");    // report inches
    UART_SendString("$20=1\r\n");    // soft limits
    UART_SendString("$21=1\r\n");    // hard limits
    UART_SendString("$22=1\r\n");    // homing cycle
    UART_SendString("$23=0\r\n");    // homing dir invert
    UART_SendString("$24=25.000\r\n"); // homing feed
    UART_SendString("$25=500.000\r\n"); // homing seek
    UART_SendString("$26=250\r\n");// homing debounce
    UART_SendString("$27=1.000\r\n"); // homing pull-off
    UART_SendString("$30=1000\r\n"); // max spindle speed
    UART_SendString("$31=0\r\n");    // min spindle speed
    UART_SendString("$32=1\r\n");    // laser mode
    UART_SendString("$100=1000.000\r\n"); // X max rate
    UART_SendString("$101=1000.000\r\n"); // Y max rate
    UART_SendString("$102=500.000\r\n");// Z max rate
    UART_SendString("$110=100.000\r\n");// X acceleration
    UART_SendString("$111=100.000\r\n");// Y acceleration
    UART_SendString("$112=50.000\r\n");   // Z acceleration
    UART_SendString("$120=200.000\r\n");// X max travel
    UART_SendString("$121=200.000\r\n");// Y max travel
    UART_SendString("$122=50.000\r\n");   // Z max travel
}

/**
* @brief 报告GRBL状态
*/
void Report_Grbl_State(void)
{
    UART_SendString("\r\n");
}

/**
* @brief 报告GRBL参数
*/
void Report_Grbl_Parameters(void)
{
    UART_SendString("\r\n");
    UART_SendString("\r\n");
    UART_SendString("\r\n");
    UART_SendString("\r\n");
    UART_SendString("\r\n");
    UART_SendString("\r\n");
    UART_SendString("\r\n");
    UART_SendString("\r\n");
    UART_SendString("\r\n");
    UART_SendString("\r\n");
    UART_SendString("\r\n");
}

/**
* @brief 直线插补运动
*/
void MC_Line(float *target, float feed_rate, unsigned char laser_state)
{
    // 转换目标位置为步数
    long x_steps = ToSteps(target, 0);
    long y_steps = ToSteps(target, 1);
    long z_steps = ToSteps(target, 2);
   
    // 控制激光
    if(laser_state)
    {
      Laser_Control(1, (unsigned char)(sys.spindle_speed * 2.55));
    }
    else
    {
      Laser_Control(0, 0);
    }
   
    // 执行移动
    Stepper_MoveTo(x_steps, y_steps, z_steps, feed_rate);
}

/**
* @brief 圆弧插补运动
*/
void MC_Arc(float *target, float *offset, float radius, unsigned char is_clockwise, float feed_rate)
{
    // 简化版圆弧插补 - 实际实现需要复杂的数学计算
    // 这里使用直线逼近圆弧
   
    float center;
    float start;
    float end;
   
    // 根据平面选择坐标
    switch(sys.plane_select)
    {
      case PLANE_XY:
            start = sys.coord_system->position;
            start = sys.coord_system->position;
            end = target;
            end = target;
            center = start + offset;
            center = start + offset;
            break;
            
      case PLANE_ZX:
            start = sys.coord_system->position;
            start = sys.coord_system->position;
            end = target;
            end = target;
            center = start + offset;
            center = start + offset;
            break;
            
      case PLANE_YZ:
            start = sys.coord_system->position;
            start = sys.coord_system->position;
            end = target;
            end = target;
            center = start + offset;
            center = start + offset;
            break;
    }
   
    // 计算圆弧角度
    float start_angle = atan2(start - center, start - center);
    float end_angle = atan2(end - center, end - center);
    float radius_val = sqrt(offset*offset + offset*offset);
   
    // 角度调整
    if(is_clockwise)
    {
      if(end_angle > start_angle) end_angle -= 2 * M_PI;
    }
    else
    {
      if(end_angle < start_angle) end_angle += 2 * M_PI;
    }
   
    float angle_diff = end_angle - start_angle;
   
    // 分段逼近圆弧
    int segments = (int)(fabs(angle_diff) * radius_val / 0.01f); // 每段约0.01mm
    if(segments < 1) segments = 1;
   
    for(int i = 1; i <= segments; i++)
    {
      float angle = start_angle + angle_diff * i / segments;
      float x = center + radius_val * cos(angle);
      float y = center + radius_val * sin(angle);
      
      float intermediate_target = {0};
      switch(sys.plane_select)
      {
            case PLANE_XY:
                intermediate_target = x;
                intermediate_target = y;
                intermediate_target = target;
                break;
            case PLANE_ZX:
                intermediate_target = x;
                intermediate_target = y;
                intermediate_target = target;
                break;
            case PLANE_YZ:
                intermediate_target = x;
                intermediate_target = y;
                intermediate_target = target;
                break;
      }
      
      MC_Line(intermediate_target, feed_rate, laser_on);
      
      if(system_state != STATE_CYCLE)
            break;
    }
}

/**
* @brief 单位转换
*/
float ToMM(float value)
{
    return (sys.units == UNIT_INCH) ? value * 25.4f : value;
}

/**
* @brief 毫米转步数
*/
float ToSteps(float mm, unsigned char axis)
{
    return mm * settings.steps_per_mm;
}

/**
* @brief 步数转毫米
*/
float ToMMFromSteps(long steps, unsigned char axis)
{
    return (float)steps / settings.steps_per_mm;
}

/**
* @brief 微秒延迟
*/
void Delay_us(unsigned int us)
{
    while(us--)
    {
      _nop_(); _nop_(); _nop_(); _nop_();
      _nop_(); _nop_(); _nop_(); _nop_();
    }
}

/**
* @brief 毫秒延迟
*/
void Delay_ms(unsigned int ms)
{
    while(ms--)
    {
      Delay_us(1000);
    }
}

/**
* @brief 定时器0中断 - 系统计时
*/
void Timer0_ISR(void) interrupt 1
{
    TH0 = 0xFC;
    TL0 = 0x66;
   
    system_timer++;
   
    // 每100ms报告状态
    if(system_timer % 100 == 0)
    {
      report_status = 1;
    }
}

/**
* @brief 定时器2中断 - 步进脉冲生成
*/
void Timer2_ISR(void) interrupt 12
{
    T2IF = 0;
    // 步进脉冲生成逻辑
}

/**
* @brief 串口中断
*/
void UART_ISR(void) interrupt 4
{
    if(RI)
    {
      RI = 0;
      char c = SBUF;
      
      // 处理特殊字符
      if(c == 0x18) // Ctrl+X - 取消
      {
            System_Reset();
            UART_SendString("Cancel\r\n");
            rx_head = rx_tail = 0;
      }
      else if(c == '?') // 状态查询
      {
            report_status = 1;
      }
      else if(c == 0x7F || c == 0x08) // 退格
      {
            if(rx_head != rx_tail)
            {
                rx_head = (rx_head - 1) % RX_BUFFER_SIZE;
                UART_SendString("\b \b"); // 回显退格
            }
      }
      else
      {
            // 添加到接收缓冲区
            unsigned char next_head = (rx_head + 1) % RX_BUFFER_SIZE;
            if(next_head != rx_tail)
            {
                rx_buffer = c;
                rx_head = next_head;
               
                // 回显字符
                if(c >= 32 && c < 127) // 可打印字符
                {
                  UART_SendChar(c);
                }
                else if(c == '\r' || c == '\n')
                {
                  UART_SendString("\r\n");
                }
            }
      }
    }
   
    if(TI)
    {
      TI = 0;
      if(tx_head != tx_tail)
      {
            SBUF = tx_buffer;
            tx_tail = (tx_tail + 1) % TX_BUFFER_SIZE;
      }
    }
}
程序功能说明
1. GRBL 1.1f兼容性
完全兼容GRBL 1.1f协议

支持所有标准G代码和M代码

实时状态报告和错误处理

2. 运动控制功能
直线插补: G0(快速移动), G1(线性插补)

圆弧插补: G2(顺时针圆弧), G3(逆时针圆弧)

平面选择: G17(XY), G18(ZX), G19(YZ)

坐标系统: G54-G59工作坐标系

单位系统: G20(英寸), G21(毫米)

坐标模式: G90(绝对), G91(相对)

位置设置: G92(设置工作坐标系)

3. 激光控制
激光开关: M3(开启), M5(关闭)

功率控制: S参数(0-100%)

激光模式: $32设置激光模式

4. 安全功能
硬限位: 物理限位开关保护

软限位: 软件行程限制

回零功能: G28自动回零

急停功能: 复位按钮和Ctrl+X

5. 系统管理
状态报告: 实时位置和状态报告

参数设置: $$查看所有设置

报警处理: 错误检测和报警

系统复位: 完全系统重置

硬件配置
引脚分配
X轴: P2.0(STEP), P2.1(DIR), P2.2(EN)

Y轴: P2.3(STEP), P2.4(DIR), P2.5(EN)

Z轴: P2.6(STEP), P2.7(DIR), P3.0(EN)

限位开关:

X: P3.1(MIN), P3.2(MAX)

Y: P3.3(MIN), P4.0(MAX)

Z: P4.1(MIN), P4.2(MAX)

激光控制: P4.3(PWM), P4.4(EN)

控制按钮: P4.5(开始), P4.6(保持), P4.7(复位)

状态指示: P5.0(状态), P5.1(错误)

使用说明
1. 基本操作
gcode
G21      ; 毫米模式
G90      ; 绝对坐标
G28      ; 回零
G1 X10 Y10 F1000 ; 移动到X10 Y10,速度1000mm/min
M3 S50   ; 开启激光,功率50%
G1 X20 Y20 ; 雕刻直线
M5         ; 关闭激光
2. GRBL命令
$$ - 查看所有设置

$# - 查看坐标偏移

$G - 查看G代码状态

$I - 查看版本信息

$X - 清除报警

? - 实时状态查询

3. 参数配置
通过修改settings_t结构体中的默认值来配置机器参数,如步数/mm、最大速率、加速度等。

扩展功能
这个LaserGRBL固件可以进一步扩展以下功能:

SD卡支持: 添加离线文件执行功能

网络接口: 添加WiFi/Ethernet远程控制

图形界面: 添加LCD显示屏和菜单

自动对焦: 添加Z轴自动对焦功能

相机定位: 添加视觉定位系统

多激光头: 支持多个激光头控制

这个完整的LaserGRBL固件提供了强大的激光雕刻机控制功能,兼容标准的GRBL生态系统,可以方便地集成到各种激光雕刻项目中。

本回答由 AI 生成,内容仅供参考,请仔细甄别。
页: 1 2 3 [4]
查看完整版本: 将GRBL移植到32G系列上,做了个写字机