#include "grbl.h" // Declare system global variable structure system_t sys; int32_t sys_position[N_AXIS]; // Real-time machine (aka home) position vector in steps. int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. volatile uint8_t sys_probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. volatile uint8_t sys_rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides. volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides. #ifdef DEBUG volatile uint8_t sys_rt_exec_debug; #endif int main(void) { // Initialize system upon power-up. serial_init(); // Setup serial baud rate and interrupts settings_init(); // Load Grbl settings from EEPROM stepper_init(); // Configure stepper pins and interrupt timers system_init(); // Configure pinout pins and pin-change interrupt memset(sys_position,0,sizeof(sys_position)); // Clear machine position. sei(); // Enable interrupts // Initialize system state. #ifdef FORCE_INITIALIZATION_ALARM // Force Grbl into an ALARM state upon a power-cycle or hard reset. sys.state = STATE_ALARM; #else sys.state = STATE_IDLE; #endif // Check for power-up and set system alarm if homing is enabled to force homing cycle // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the // startup scripts, but allows access to settings and internal commands. Only a homing // cycle '$H' or kill alarm locks '$X' will disable the alarm. // NOTE: The startup script will run after successful completion of the homing cycle, but // not after disabling the alarm locks. Prevents motion startup blocks from crashing into // things uncontrollably. Very bad. #ifdef HOMING_INIT_LOCK if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } #endif // Grbl initialization loop upon power-up or a system abort. For the latter, all processes // will return to this loop to be cleanly re-initialized. for(;;) { // Reset system variables. uint8_t prior_state = sys.state; memset(&sys, 0, sizeof(system_t)); // Clear system struct variable. sys.state = prior_state; sys.f_override = DEFAULT_FEED_OVERRIDE; // Set to 100% sys.r_override = DEFAULT_RAPID_OVERRIDE; // Set to 100% sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; // Set to 100% memset(sys_probe_position,0,sizeof(sys_probe_position)); // Clear probe position. sys_probe_state = 0; sys_rt_exec_state = 0; sys_rt_exec_alarm = 0; sys_rt_exec_motion_override = 0; sys_rt_exec_accessory_override = 0; // Reset Grbl primary systems. serial_reset_read_buffer(); // Clear serial read buffer gc_init(); // Set g-code parser to default state spindle_init(); coolant_init(); limits_init(); probe_init(); plan_reset(); // Clear block buffer and planner variables st_reset(); // Clear stepper subsystem variables. // Sync cleared gcode and planner positions to current system position. plan_sync_position(); gc_sync_position(); // Print welcome message. Indicates an initialization has occured at power-up or with a reset. report_init_message(); // Start Grbl main loop. Processes program inputs and executes them. protocol_main_loop(); } return 0; /* Never reached */ }
时间: 2025-07-12 12:32:23 浏览: 9
<think>嗯,用户让我分析这个Grbl的main函数代码,首先我得先理解Grbl是什么。Grbl是用于CNC机床的嵌入式固件,通常运行在Arduino这样的微控制器上。用户可能是在开发或定制自己的CNC控制器,或者在学习Grbl的源码结构。需要了解代码的初始化和主循环流程。
首先看头文件#include "grbl.h",这应该是包含了所有Grbl相关的定义和函数声明。接下来声明了系统全局变量结构体system_t sys,以及一些位置、状态变量。这些变量用于跟踪机器位置、探针状态、实时执行状态等。volatile关键字说明这些变量可能在中断服务例程中被修改,需要防止编译器优化。
main函数开始后,首先进行一系列的初始化:串口、设置、步进电机、系统。memset清空sys_position数组,确保机器位置从零开始。sei()启用中断,这是AVR单片机的指令,允许处理中断。
接下来根据编译宏FORCE_INITIALIZATION_ALARM决定系统初始状态是ALARM还是IDLE。如果是HOMING_INIT_LOCK启用,并且设置了回零使能标志,系统状态会被设为ALARM,强制用户进行回零操作,避免开机后意外运动。
然后进入无限循环,循环内首先重置系统变量,恢复之前的状态,覆盖参数设为默认值。之后复位各个子系统:串口缓冲区、G代码解析器、主轴、冷却液、限位开关、探针、运动计划和步进控制。plan_sync_position和gc_sync_position确保位置信息同步,避免累积误差。
报告初始化信息后,进入protocol_main_loop()主循环,处理输入指令。整个结构是初始化后进入永久循环,处理各种任务。
用户可能需要了解各个初始化的具体作用,或者如何修改Grbl的启动行为,比如是否强制回零。也可能遇到启动问题,想通过代码分析排查原因。需要解释每个函数的作用,全局变量的用途,以及主循环的工作机制。此外,注意代码中的条件编译部分,说明不同配置下的行为差异,比如调试模式和回零锁定的处理。</think>这个代码是Grbl固件的`main()`函数,Grbl是一个针对AVR微控制器的开源CNC运动控制固件。我们逐步分析其结构和功能:
### 一、全局变量声明
```c
system_t sys; // 系统状态结构体
int32_t sys_position[N_AXIS]; // 实时机械坐标(步进单位)
int32_t sys_probe_position[N_AXIS]; // 探针最后接触位置
volatile uint8_t sys_probe_state; // 探针状态(用于与步进中断协调)
volatile uint8_t sys_rt_exec_*; // 实时执行状态标志组(通过位掩码管理)
```
这些volatile变量用于在中断服务例程(ISR)与主程序间共享数据,保证实时性。
### 二、主函数流程
#### 1. 初始化阶段
```c
serial_init(); // 初始化串口通信
settings_init(); // 从EEPROM加载配置
stepper_init(); // 步进电机驱动初始化
system_init(); // GPIO引脚配置
memset(sys_position,0); // 清零机械坐标
sei(); // 启用全局中断(AVR指令)
```
#### 2. 系统状态初始化
```c
#ifdef FORCE_INITIALIZATION_ALARM
sys.state = STATE_ALARM; // 强制进入报警状态
#else
sys.state = STATE_IDLE; // 默认空闲状态
#endif
#ifdef HOMING_INIT_LOCK
if (settings.flags & HOMING_ENABLE)
sys.state = STATE_ALARM; // 启用回零锁
```
通过编译宏控制初始状态,安全机制强制回零操作后才能运动。
#### 3. 主循环结构
```c
for(;;) {
// 复位子系统
serial_reset_read_buffer();
gc_init(); // G代码解析器复位
spindle_init(); // 主轴控制初始化
plan_reset(); // 运动规划器复位
st_reset(); // 步进控制器复位
// 位置同步
plan_sync_position(); // 同步规划器坐标
gc_sync_position(); // 同步G代码解析器坐标
report_init_message(); // 发送启动信息
protocol_main_loop(); // 进入主命令循环
}
```
这是一个永久循环,在系统异常复位后会重新初始化各子系统。
### 三、关键设计特点
1. **实时性保障**:
- 通过`volatile`变量和中断标志实现硬实时控制
- 步进定时器中断优先级最高
2. **安全机制**:
- 上电默认需要回零操作(HOMING_INIT_LOCK)
- 状态机管理(STATE_ALARM/IDLE等)
3. **模块化设计**:
```mermaid
graph TD
MAIN-->|调用| SERIAL[串口模块]
MAIN-->|调用| STEPPER[步进控制]
MAIN-->|调用| PLAN[运动规划]
MAIN-->|调用| GC[G代码解析]
```
### 四、典型工作流程
1. 接收G代码指令
2. 解析并生成运动路径
3. 步进电机按规划路径运动
4. 实时监控限位/探针等输入
5. 通过串口反馈状态信息
这个代码结构体现了典型的嵌入式实时系统特征,通过状态标志和中断机制实现精确的时序控制,是理解CNC控制器底层运作的良好范例。
阅读全文
相关推荐
















