极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: oldbeginner

Arduino机械坊学习笔记04( 开始理解GRBL下位机)_2014_3_16

[复制链接]
 楼主| 发表于 2014-3-28 11:30:17 | 显示全部楼层
oldbeginner 发表于 2014-3-28 10:03
******************************
gcode.c 下

*************************
main.c

An embedded CNC Controller with rs274/ngc (g-code) support
可以提前理解的函数
*************************


内容1 引用的头文件                                                                                                    

#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "config.h"
#include "planner.h"
#include "nuts_bolts.h"
#include "stepper.h"
#include "spindle_control.h"
#include "coolant_control.h"
#include "motion_control.h"
#include "gcode.h"
#include "protocol.h"
#include "limits.h"
#include "report.h"
#include "settings.h"
#include "serial.h"

唯一需要理解的头文件,pgmspace.h

在程序中访问FLASH 程序存储器,avr-libc 支持头文件:pgmspace.h,FLASH 区整数常量和数组应用
http://zhidao.baidu.com/link?url=dBUvav4dbX7xjYwSkJZ87KQKo2dvoG2WOTitK5XreXwL0jyd2iZIaKgIJke2FK7EPs_gy65ivdIANFe9bmNYIq

************************************
内容2 定义全局变量                                                                                    

system_t sys;

system_t 结构定义在nuts_bolts.h 文件中,表示GRBL 状态

**************************************
内容3 主函数                                                                                    

int main(void)
{
           初始化系统();

           系统变量设定();

  for(;;) {

         系统是否需要重启判断并执行();

        protocol_execute_runtime();

        protocol_process(); // ... process the serial protocol
   
       }
    return 0;   /* never reached */
}

简直不敢相信,main 函数是 这么容易理解。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-29 10:54:40 | 显示全部楼层
oldbeginner 发表于 2014-3-28 11:30
*************************
main.c

*******************************
主函数 初始化系统

*******************************


// Setup serial baud rate and interrupts

serial_init();

// Load grbl settings from EEPROM

settings_init();


// Setup stepper pins and interrupt timers

st_init();

// Enable interrupts

sei();


Setup serial baud rate and interrupts                                                                       

serial_init() 是定义在 serial.c 中的函数,并且 设置 波特率 和使能 tx rx 字节接收中断

具体用法曾经理解过,不完整,放在 avr 里理解。


Load grbl settings from EEPROM                                                      

Load grbl settings from EEPROM 定义在 setting.c 中,引用了很多函数,但目的就是 读出 EEPROM中保存的系统设置数据。

Setup stepper pins and interrupt timers                                         

st_init() Initialize and start the stepper motor subsystem,定义在 stepper.c 中,使用了定时器配置。

Enable interrupts                                                                                                    

sei()

************************************************************
回复 支持 反对

使用道具 举报

发表于 2014-3-29 16:24:30 | 显示全部楼层
本帖最后由 GeeMing 于 2014-3-29 16:30 编辑

加油啊,楼主,之前也打算弄grbl,可惜太艰涩了,因为inskape出来的插补只有直线和圆弧两种,所以弄了个破破的解方程算法凑合弄了个玩具,不过grbl还是好好玩的样子,但得要两个月后才有时间折腾了。迟点再来看看进度,不要放弃哦
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-30 12:05:02 | 显示全部楼层
oldbeginner 发表于 2014-3-29 10:54
*******************************
主函数 初始化系统

******************
系统变量设定

*****************


// Clear all system variables

memset(&sys, 0, sizeof(sys));

// Set abort to complete initialization

sys.abort = true;

// Set alarm state to indicate unknown initial position

sys.state = STATE_INIT;



也是比较容易理解的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-30 14:17:55 | 显示全部楼层
本帖最后由 oldbeginner 于 2014-3-30 14:23 编辑
oldbeginner 发表于 2014-3-30 12:05
******************
系统变量设定

**********************
再来看 protocol_execute_runtime

**********************


Executes run-time commands, when required.
This is called from various check points in the main program, primarily where there may be a while loop waiting for a buffer to clear space or any point where the execution time from the last check point may be more than a fraction of a second.

This is a way to execute runtime commands asynchronously (aka multitasking) with grbl's g-code parsing and planning functions. This function also serves as an interface for the interrupts to set the system runtime flags, where only the main program handles them, removing the need to define more computationally-expensive volatile variables.

This also provides a controlled way to execute certain tasks without having two or more instances of the same task, such as the planner recalculating the buffer upon a feedhold or override.

NOTE: The sys.execute variable flags are set by any process, step or serial interrupts, pinouts, limit switches, or the main program.

System alarm. Everything has shutdown by something that has gone severely wrong.


Execute system abort.                              



Execute and serial print status                                   



Initiate stepper feed hold                           



Reinitializes the stepper module running state                     



Issue cycle start command to stepper subsystem



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-31 13:28:17 | 显示全部楼层
本帖最后由 oldbeginner 于 2014-3-31 14:16 编辑
oldbeginner 发表于 2014-3-30 14:17
**********************
再来看 protocol_execute_runtime


*******************************
再来看 protocol_process

*******************************


Process and report status one line of incoming serial data.
Performs an initial filtering by removing spaces and comments and capitalizing all letters.

理解代码,其实前面干扰很多(出于理解目的),最核心的就是最后两句话,前面的都是检查是否符合输入要求;
就像安全检查。



**********************************

至此,学习思路要发生变化了。以主函数的 双雄 为导向。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-1 13:18:32 | 显示全部楼层
oldbeginner 发表于 2014-3-31 13:28
*******************************
再来看 protocol_process

**************************
protocol_execute_runtime

调用了 stepper 相关的函数

**************************


在学习stepper motor driver 之前,先做一下准备工作,pin_map.h 中的设置



  // NOTE: All step bit and direction pins must be on the same port.
  #define STEPPING_DDR      DDRA
  #define STEPPING_PORT     PORTA
  #define STEPPING_PIN      PINA
  #define X_STEP_BIT        2 // MEGA2560 Digital Pin 24
  #define Y_STEP_BIT        3 // MEGA2560 Digital Pin 25
  #define Z_STEP_BIT        4 // MEGA2560 Digital Pin 26
  #define X_DIRECTION_BIT   5 // MEGA2560 Digital Pin 27
  #define Y_DIRECTION_BIT   6 // MEGA2560 Digital Pin 28
  #define Z_DIRECTION_BIT   7 // MEGA2560 Digital Pin 29


然后,
需要了解一个结构(stepper.c中),



需要学习的外部函数

// Initialize and setup the stepper motor subsystem
void st_init();

// Enable steppers, but cycle does not start unless called by motion control or runtime command.
void st_wake_up();

// Immediately disables steppers
void st_go_idle();

// Reset the stepper subsystem variables      
void st_reset();
            
// Notify the stepper subsystem to start executing the g-code program in buffer.
void st_cycle_start();

// Reinitializes the buffer after a feed hold for a resume.
void st_cycle_reinitialize();

// Initiates a feed hold of the running program
void st_feed_hold();

看起来,像是一个状态机, init, wakeup, go idle, reset, cycle start, cycle reinitialize, feed hold.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-3 13:05:19 | 显示全部楼层
oldbeginner 发表于 2014-4-1 13:18
**************************
protocol_execute_runtime

*************************
stepper.c

stepper motor driver: executes motion plans using stepper motors
*************************


内容1

Initialize and start the stepper motor subsystem


void st_init()
{
  Configure directions of interface pins();

  waveform generation = 0100 = CTC();

  output mode = 00 (disconnected)();

  Configure Timer 2();

  Start in the idle state();

}



Configure directions of interface pins()                                               

  STEPPING_DDR |= STEPPING_MASK;
  STEPPING_PORT = (STEPPING_PORT & ~STEPPING_MASK) | settings.invert_mask;
  STEPPERS_DISABLE_DDR |= 1<<STEPPERS_DISABLE_BIT;

其中,
  #define STEPPERS_DISABLE_DDR    DDRB
  #define STEPPERS_DISABLE_BIT    0  // Uno Digital Pin 8



waveform generation = 0100 = CTC()                                       

  TCCR1B &= ~(1<<WGM13);
  TCCR1B |=  (1<<WGM12);
  TCCR1A &= ~(1<<WGM11);
  TCCR1A &= ~(1<<WGM10);

In Clear Timer on Compare Match mode, the counter resets itself automatically when it reaches the value that’s stored in the OCRnA register instead of waiting until it hits 255 or 65,535.
So by writing to the output compare register, we control the frequency of the cycles.

// WGM13,WGM12,WGM11,WGM10:波型发生模式:
    //            比较输出模式(CTC模式),非PWM
    //                  00普通端口操作,OC1A/OC1B/OC1C未连接
    //                  01比较匹配时OC1A/OC1B/OC1C电平取反
    //                  10比较匹配时清零OC1A/OC1B/OC1C(输出低电平)
    //                  11比较匹配时置位OC1A/OC1B/OC1C(输出高电平)
    //            比较输出模式(CTC模式),快速PWM
    //                  00普通端口操作,OC1A/OC1B/OC1C未连接
    //                  01WGM13为0时同上,为1时 比较匹配时 OC1A电平取反,OC1B/OC1C保留
    //                  10比较匹配时OC1A/OC1B/OC1C清零,在TOP时OC1A/OC1B/OC1C置位
    //                  11比较匹配时OC1A/OC1B/OC1C置位,在TOP时OC1A/OC1B/OC1C清零
    //            比较输出模式(CTC模式),相位修正及相频修正PWM
    //                  00普通端口操作,OC1A/OC1B/OC1C未连接
    //                  01WGM13为0:同上,为1时 比较匹配时 OC1A电平取反,OC1B/OC1C保留
    //                  10升序计数匹配时将OC1A/OC1B/OC1C清零,降序计数匹配时将OC1A/OC1B/OC1C置位
    //                  11升序计数匹配时将OC1A/OC1B/OC1C置位,降序计数匹配时将OC1A/OC1B/OC1C清零


output mode = 00 (disconnected)                                                                     

  TCCR1A &= ~(3<<COM1A0);
  TCCR1A &= ~(3<<COM1B0);

    // COM1A1,COM1A0:通道A的比较输出模式
    // COM1B1,COM1B0:通道B的比较输出模式


Configure Timer 2()                                                                                          

  TCCR2A = 0; // Normal operation
  TCCR2B = 0; // Disable timer until needed.
  TIMSK2 |= (1<<TOIE2); // Enable Timer2 Overflow interrupt     
  #ifdef STEP_PULSE_DELAY
    TIMSK2 |= (1<<OCIE2A); // Enable Timer2 Compare Match A interrupt
  #endif

Start in the idle state()                                                                                       

but first wake up to check for keep steppers enabled option.

  st_wake_up();
  st_go_idle();

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-4 14:22:51 | 显示全部楼层
oldbeginner 发表于 2014-4-3 13:05
*************************
stepper.c

*********************
st_wake_up()

Stepper state initialization.
*********************


Cycle should only start if the st.cycle_start flag is enabled.
Startup init and limits call this function but shouldn't start the cycle.

void st_wake_up()
{
  
  if (bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)) {
    STEPPERS_DISABLE_PORT |= (1<<STEPPERS_DISABLE_BIT);
  } else {
    STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT);
  }

  if (sys.state == STATE_CYCLE) {
   
    out_bits = (0) ^ (settings.invert_mask);
  
    #ifdef STEP_PULSE_DELAY
   
      step_pulse_time = -(((settings.pulse_microseconds+STEP_PULSE_DELAY-2)*TICKS_PER_MICROSECOND) >> 3);
     
      OCR2A = -(((settings.pulse_microseconds)*TICKS_PER_MICROSECOND) >> 3);
    #else // Normal operation

      step_pulse_time = -(((settings.pulse_microseconds-2)*TICKS_PER_MICROSECOND) >> 3);
    #endif

    TIMSK1 |= (1<<OCIE1A);
  }
}


pin8 是使能 stepper 的控制点


Initialize step pulse timing from settings.
Enable stepper driver interrupt

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-4 15:08:57 | 显示全部楼层
oldbeginner 发表于 2014-4-4 14:22
*********************
st_wake_up()

********************
void st_go_idle()

Stepper shutdown
********************


void st_go_idle()
{

  TIMSK1 &= ~(1<<OCIE1A);

  if ((settings.stepper_idle_lock_time != 0xff) || bit_istrue(sys.execute,EXEC_ALARM)) {

    delay_ms(settings.stepper_idle_lock_time);
    if (bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)) {
      STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT);
    } else {
      STEPPERS_DISABLE_PORT |= (1<<STEPPERS_DISABLE_BIT);
    }   
  }
}

  Disable stepper driver interrupt
  Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete stop and not drift from residual inertial forces at the end of the last movement.
回复 支持 反对

使用道具 举报

发表于 2014-4-18 11:55:30 | 显示全部楼层
楼主,我按教程把GRBL下位机源文件中的 *.h 和 *.c 文件加入,再加入 makefile 文件, 点击 make all报错.同时那个make all文件也不在grbl的第一位而是按顺序排列的,按网上的教程也弄好几天了,都是报错就是生不成.HEX文件,百忙之中帮看看?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-18 16:34:53 | 显示全部楼层
本帖最后由 oldbeginner 于 2014-4-18 16:36 编辑
随易而安 发表于 2014-4-18 11:55
楼主,我按教程把GRBL下位机源文件中的 *.h 和 *.c 文件加入,再加入 makefile 文件, 点击 make all报错.同 ...


参考
https://github.com/grbl/grbl/wiki/Compiling-Grbl

把GRBL目录放在根目录下,不要带中文,
然后,打开命令行界面,进入GRBL目录下,make clean,然后make grbl.hex 就可以了。


如果,make clean这些命令不能识别,
那是因为 环境变量 path 没有把 这些命令的路径加入,

例如,C:\arduino-00xx\hardware\tools\avr\bin;C:\arduino-00xx\hardware\tools\avr\avr\bin;C:\arduino-00xx\hardware\tools\avr\utils\bin

*****************************
第一页的方式,也可以。确保路径没有中文,多试几次应该可以。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2014-4-19 00:10:38 | 显示全部楼层
按你说的又重新设置文件名和地址 ,可是还是报错,make clean能执行,到make gebl.hex那一步又报错了.和一开始一样,是不是软件的问题?软件我也重新下载过几次了.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-19 08:23:42 | 显示全部楼层
随易而安 发表于 2014-4-19 00:10
按你说的又重新设置文件名和地址 ,可是还是报错,make clean能执行,到make gebl.hex那一步又报错了.和一开始 ...

我看到 usr/bin/sh ,可能 unix之类的,会冲突。

在 path 环境变量中,把avr gcc 路径放到最前面,再试试。如果不行,你要网上查找 和 arduino 冲突的相关内容。
回复 支持 反对

使用道具 举报

发表于 2014-4-20 11:10:50 | 显示全部楼层
oldbeginner 发表于 2014-4-19 08:23
我看到 usr/bin/sh ,可能 unix之类的,会冲突。

在 path 环境变量中,把avr gcc 路径放到最前面,再试 ...

重装电脑了,重装软件了,还是一样的错误提示,你说的那个path变量真弄不明白,刚接触单片机小小白,看来WinAVR真不是初学者能弄明白的.另和系统有没有关呢,我的是win8.1系统是不是不支持啊?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 14:11 , Processed in 0.046739 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表