Grbl学习(6)--重要源码介绍(2)

  本篇将介绍stepper.c源码以及PWM,该部分主要负责步进电机控制

  大量专用词汇笔者已经在上一篇介绍serial.c时说明,所以本篇直接展示重要函数的功能



1.stepper_init() :步进电机初始化

2.ISR(TIMER1_COMPA_vect):定时器1中断处理,比较中断,可以在设置任意数值

3.ISR(TIMER0_OVF_vect):定时器0中断处理,溢出中断,溢出中断只能在计数器达到最大值或最小值时触发

  注:比较中断和溢出中断的比较

      在某些情况下,溢出中断可能会因为中断服务程序(ISR)的执行时间而产生误差。如果ISR执行时间较长,可能会导致下一个溢出中断延迟,从而影响定时精度。而比较中断由于可以在任意时刻设置,因此可以减少这种误差

4.st_go_idle():步进电机进入空闲状态

5.st_resst():步进电机变量重置

6.st_get_realtime_rate():获取当前正在执行的速度

7.st_prep_buffer():准备步进电机的运动缓冲区,将G-code命令转换为步进电机的运动指令

8.st_parking_setup_buffer():设置步进电机的停车缓冲区,用于在运动完成后将步进电机移动到安全的位置

9.st_generate_step_dir_invert_masks():生成步进电机步进和方向信号的反转掩码


PWM

  在介绍stepper.c如何进行步进控制前,首先需要了解PWM,全称脉冲宽度调制。是一种通过调节数字信号的脉冲宽度(高电平持续时间)来控制模拟效果的常用技术。充分利用了数字信号相比与模拟信号更不易受噪声影响的优点,其核心思想是:用数字信号的开关比例,模拟不同的“等效电压”。

  也就是说PWM本质是数字信号,只有0和1两种状态,但通过快速开关和占空比(占空比=高电平时间/周期时间)来模拟出如可变电压的模拟信号(如下)。举个例子:可以通过改变占空比控制LED的亮度,人眼感知的是平均光强

  


  Grbl的步进控制并没有完全直接使用PWM,而是采用了一种“间接PWM”的操作。

  为追求高实时性和低资源占用,牺牲了标准PWM的连续性,选择更灵活的中断驱动方式。每个脉冲都由中断精确计数,避免连续输出导致的累积误差,使得对电机的控制中更高效可靠,但需要深入理解硬件定时器的底层行为,接下来将结合上图详细介绍。

  我们知道Grbl通常有timer0和timer1两个定时器。

  timer0用来控制脉冲宽度以保证有足够脉宽给步进电机驱动

  timer1用来控制脉冲频率以控制步进电机速度

  由timer1产生步进脉冲周期,然后在timer1的中断函数中开启timer0,在timer0的中断函数中拉低电平,产生一个很窄的步进脉冲信号。

  timer1决定了PWM中的Duration Time而timer0决定了Duty Cyle Time,这里与常规PWM不同的是Duration Time是可变的,如此允许了更灵活的频率调整,可以通过动态修改脉冲间隔实现复杂的加速度曲线。

  顺带一提,Grbl的主轴控制与步进控制不同,在不需要高动态频率调整和精确脉冲计数的情况下,依旧采用了“直接PWM”的方式控制主轴转速。


  下一篇将接着第三篇详细介绍其余的重要算法

  以上便是本篇的全部内容啦!

  欢迎大家一起交流学习!

 

ain()主函数首先执行下面初始化函数 serial_init(); // Setup serial baud rate and interrupts settings_init(); // Load Grbl settings from EEPROM stepper_init(); // 配置步进方向和中断定时器 system_init(); // 配置引脚分配别针和pin-change中断 memset(&sys, 0, sizeof(system_t)); // Clear all system variables sys.abort = true; // Set abort to complete initialization 完成初始化设置中止 sei(); // Enable interrupts #ifdef HOMING_INIT_LOCK //宏运算(settings.flags & (1 << 4)) != 0结果flags等于执行sys.state = STATE_ALARM //系统状态赋值为报警状态 if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } #endif _____________________________________________________________________________________________________________________________________ 接下来是一些主要初始化循环 for(;;) { 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. 同步清除gcode和策划师职位当前系统位置。 plan_sync_position(); gc_sync_position(); // Reset system variables. sys.abort = false; //系统中止标志 sys_rt_exec_state = 0; //系统执行标志状态变量状态位清零。 sys_rt_exec_alarm = 0; //系统执行警报标志变量清零。 sys.suspend = false; //系统暂停标志位,取消,和安全的门。 sys.soft_limit = false; //系统限制标志状态机复位。(布尔) protocol_main_loop(); //主协议循环 } // ___________________________________________________________________________
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值