开源改变世界

添加 SPI #748

推推 grbl 3年前 (2023-01-22) 81次浏览

关闭
J-Dunn 打开了这个问题 2015 年 6 月 25 日 · 32条评论
关闭

添加 SPI#748

J-Dunn 打开了这个问题 2015 年 6 月 25 日 · 32条评论

注释

添加 SPI #748

我正在尝试使用通过 SPI 编程的驱动芯片添加一些硬件。主要是初始化,但也有错误状态。通常的步骤和目录行。

Arduino SPI 库非常简单,因为其中大部分是由硬件完成的。它主要是将一个字节插入寄存器并等待状态标志,然后读取返回字节。

我需要稍微移动默认引脚以释放 MOSI 和朋友,所以我将没有主轴控制(不需要)并且限制引脚必须进入端口 A。

现在我知道 GRBL 已被压缩到最低限度以使其适合 UNO。在它开始出现问题之前我还有多少空间可以玩?我需要特别注意哪些限制?

谢谢京东。

添加 SPI #748
成员

@J-Dunn:您希望有大约 400 字节的空闲内存并且不想超过 31-31.5kB 的总闪存(引导加载程序驻留在 32kB 的最后 0.5kB 中)。或者您可以只使用 Mega2560 cpu 映射来获得额外的闪存、内存和引脚。

添加 SPI #748
作者

“二进制草图大小:27,962 字节(最大 32,256 字节)”

非常感谢。所以我还有一些喘息的空间,但不多。我一直怀疑草图大小不考虑存储在 pgmspace 中的字符串。你能评论吗?

添加 SPI #748
成员

它占了一切。Pgmspace 是闪存存储的。

添加 SPI #748

我正要构建我的第一个 GRBL 单元并注意到此线程中关于使用 Mega2560 的评论。当我查看物理 I/O 布局时,我正要订购一个。我打算将 CNC 屏蔽与插入式步进驱动器一起使用,但 Mega2560 却大不相同。我想涉及的 I/O 线数量不多,但值得付出努力吗?

添加 SPI #748
成员

@dgoadby: Mega2560 上的 Grbl 未得到官方支持,引脚映射与现有屏蔽不兼容(我认为)并且可能存在错误。所以小心行事。

添加 SPI #748

我猜是 L6474 之类的东西?
我不确定它会如何影响代码大小,但你可以稍微修改一下 spi,它的引出线更加灵活,速度应该不是一个大问题,因为你通常只将它用于设置和/或何时有警报,无论如何你必须停止一切

添加 SPI #748
作者

是的,L6474。感谢您的建议,但是…

Arduino 硬件处理所有 SPI 交互。只需写入一个寄存器并读回返回字节即可。手动完成会相当大并且基本上是在浪费开发时间。它将允许使用不同的引脚,但您仍然需要其中四个。我只需要移动限位开关并放弃一些额外的功能,如主轴速度。

无论如何,这是将整个事情转移到 stm32 的垫脚石。我只是不喜欢一次把所有的球都扔到空中。使用未知的驱动芯片、新的微处理器和移植 GRBL 一气呵成似乎解决了主要的调试难题。

添加 SPI #748
作者

我已经从 Michel_F 的 L6474 库和 SPI 库中删除了必要的位,转储了所有 cpp 类。
通过对每个 fn 进行令牌调用以确保链接,它出奇地轻巧。
二进制草图大小:27,962 字节(最大 32,256 字节)
二进制草图大小:28,726 字节(最大 32,256 字节)

这还没有与 GRBL 集成,但作为足迹可行性,它看起来很有希望。

现在我必须解决引出线问题。由于 ST 板旨在使用 PWM 进行简单的电机驱动。主要的担心是,虽然所有的 dir 引脚都在 portD 上,但其中一个 step 引脚在 portB 上。所以我要么必须弯曲一些别针,要么弯曲我的 GRBL。

我先试试后者。

// Define step pulse output pins. NOTE: All step bit pins must be on the same port.
这似乎是因为它允许在关键 ISR 中进行一些很好的优化。如果我在拆分端口上,它基本上会使代码加倍。

看起来主要的打击将出现在 ISR(TIMER0_OVF_vect) 中

ISR(TIMER1_COMPA_vect) 已经加载了一些,所以 %age 命中率可能较低。

这里有什么东西会成为真正的杀手并让人想要弯曲硬件吗?

谢谢。

添加 SPI #748
成员

@J-Dunn: 不需要。大多数这些 8 位掩码和寄存器设置每次操作只需要几个周期。如果您只坚持简单的 8 位操作,您可能不会注意到任何差异。我没有将它们分开的主要原因是没有必要并且它节省了一点闪存和几个周期。

添加 SPI #748
作者

尝试修改我发现包含链似乎没有集中结构。
例如 default.h 具有以下条件,但不包括定义它的 config.h。
#ifdef DEFAULTS_GENERIC
我还希望定义 N_AXIS=2 来做一些与代码中的一些#ifdefs 相关的事情。
我希望构建两条腿的 GRBL 来绕过引脚问题来测试我目前拥有的东西。

那种东西会很好,而且相当简单。

添加 SPI #748
成员

@J-Dunn: 是的。那种东西就好了。

添加 SPI #748
作者

也许至少 defaults.h 应该#include config.h

添加 SPI #748
作者

由于 pin shuffliing,我需要在 portC 和外部用户 i/p 引脚上设置限制引脚。

这意味着一些诡计,因为它们随后具有相同的 ISR。我制作了一个从真正的 ISR 调用的伪 ISR,它做的事情完全一样。

// if limit sw and Ext input pins are on same port , handle ext pins subroutine
#if  ( LIMIT_INT_vect == EXT_INPUT_INT_vect )

uint8_t  Ext_pin_peudo_ISR() 
{
  // Enter only if any  pin is actively low.
  if ((EXT_INPUT_PIN & EXT_INPUT_MASK) ^ EXT_INPUT_MASK) { 
    if (bit_isfalse(EXT_INPUT_PIN,bit(PIN_RESET))) {
      mc_reset();
    } else if (bit_isfalse(EXT_INPUT_PIN,bit(PIN_FEED_HOLD))) {
      bit_true(sys.execute, EXEC_FEED_HOLD); 
    } else if (bit_isfalse(EXT_INPUT_PIN,bit(PIN_CYCLE_START))) {
      bit_true(sys.execute, EXEC_CYCLE_START);
    } 
  }
  return 1;
}
#else 
uint8_t Ext_pin_peudo_ISR() { return 0; }
#endif
#ifndef ENABLE_SOFTWARE_DEBOUNCE
  ISR(LIMIT_INT_vect) // DEFAULT: Limit pin change interrupt process. 
  {
    // Ignore limit switches if already in an alarm state or in-process of executing an alarm.
    // When in the alarm state, Grbl should have been reset or will force a reset, so any pending 
    // moves in the planner and serial buffers are all cleared and newly sent blocks will be 
    // locked out until a homing cycle or a kill lock command. Allows the user to disable the hard
    // limit setting if their limits are constantly triggering after a reset and move their axes.
    if (sys.state != STATE_ALARM) { 
      if (bit_isfalse(sys.execute,EXEC_ALARM)) {
        mc_reset(); // Initiate system kill.
        bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate hard limit critical event
      }
    }
    if ( Ext_pin_peudo_ISR() ) { return;}
 }  

system.c 中真正的 ISR 被类似的#if 删除,
这意味着从 system.c 中提取几行代码到 limits.c 中,但这没什么大不了的。

逻辑看起来合理吗?

谢谢。

添加 SPI #748
作者

设置结构中似乎有死变量。我想知道它有什么用,结果发现:什么都没有;)

settings.dir_invert_mask

它由 report.c 打印,可以从命令行设置,但从未使用过。step masks 需要反转结束step pulse,但是方向是一个一个反转的。根据位置。

必要时可以进行一些清理工作。

添加 SPI #748
成员

你确定?检查 stepper.c 的初始化例程。我想你会发现这不是真的。

添加 SPI #748
作者

好吧,它确实存储在 EEPROM 中,但似乎没有用。我刚刚删除了所有提及它的内容并将其从结构中删除并编译,所以我必须检查所有用法。它节省了 132 个字节。

它似乎是从 st_generate_step_dir_invert_masks() 中的步骤掩码克隆而来的,但从未被使用过。

添加 SPI #748
成员

@J-Dunn:我没有看到任何这样的方向克隆到步骤蒙版中。它们是完全独立的实体。两者都正确地用于其特定目的。您能否指出您认为源代码中未使用 dir_invert_mask 的地方?

添加 SPI #748
作者

好的,我想我已经看到了我所缺少的东西。每次 ISR(TIMER1_COMPA_vect) 触发时,它都会反转处理哪些步进器:主要轴或从属 Bresenham 轴。

我被误导了,因为这些方向蒙版似乎无法以编程方式更改。似乎这些未定义常量的全部意义在于允许以交互方式设置和存储它。需要一段时间才能意识到其中的一些在做什么,而且很容易混淆,因为这些变量名中有几个是相似的。

希望我现在能接受它。对不起噪音。

添加 SPI #748
作者

我现在对 ISR 的内部工作原理有了更好的了解。您已经声明您的目标之一是使此代码易于改编,我同意它的评论和布局都很好。我发现的一个障碍是变量名,它常常令人困惑。一旦我更熟悉代码,我会提交一些建议。目前我正在本地进行更改并做笔记。

有一件事让我觉得有点冒险。
STEP_PORT = (STEP_PORT & ~STEP_MASK) | st.step_port_bits;

这将影响 DIRECTION_PORT 上的位,因为默认情况下 step 和 dir 都在同一个 Arduino 端口上,而 DIRECTION_PORT 上的位刚刚设置为“几个 ns”。此处输出的值是在上一次调用此 ISR 结束时确定的。:
st.step_port_bits ^= step_port_bit_mask;

准确地说,这条线应该只对相关位进行异或运算,或者输出线应该只对相关位进行异或运算。例如。
STEP_PORT = (STEP_PORT & ~STEP_MASK) | (st.step_port_bits & STEP_MASK );

它花费 2 个字节。

认识到 GRBL 是成熟且经过良好测试的软件,它似乎在现场工作,尽管它似乎在靠近电线飞行以在设置 STEP_PORT 输出的同时意外更改 dir 端口。它也无助于理解代码和对其他硬件的可移植性,因为其他硬件的时序不同。

相反,重置引脚的 ISR 可能做的比需要的更多。
STEP_PORT = (STEP_PORT & ~STEP_MASK) | (step_port_bit_mask & STEP_MASK);

如果通过手动命令行或 EEPROM 设置,step_port_bit_mask 可能包含比定义的常量 STEP_MASK 更多或更少的位。如果更多,STEP_MASK 将杀死额外的位(这很好),但这不应该在这里被捕获。如果更少,执行 & STEP_MASK 是多余的。

添加 SPI #748
作者
#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
    st.counter_x += st.steps[X_AXIS];
    st.counter_y += st.steps[Y_AXIS];
    st.counter_z += st.steps[Z_AXIS];
#else
    st.counter_x += st.exec_block->steps[X_AXIS];
    st.counter_y += st.exec_block->steps[Y_AXIS];
    st.counter_z += st.exec_block->steps[Z_AXIS];
#endif 

添加 SPI #748
成员

您正在进入语义学,这是受欢迎的,但这很容易成为时间浪费而没有太多好处。很好地抓住了台阶面罩部分。它暗示是正确的,但不像你说的那样可移植。大概是写的时候疏忽了。至于组合计数器,则无所谓。

添加 SPI #748
作者

counter 只是一个简单的整理,让它更容易阅读。很高兴我对 STEP_MASK 的看法是正确的,这意味着我正在掌握它在做什么。

#define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
这里的默认值为 6,它不是反转掩码。令人困惑。将其称为地图可能有助于将其与面具区分开来,它在功能上有所不同。当我通过时,我会建议更好的名字。

我很难理解为什么从属轴的方向与驱动轴相反。暗示?

添加 SPI #748
作者

@langwadt 您似乎熟悉 L6474,并且您说您更喜欢对 SPI 进行位爆炸。您看过 Michel F 发布的 L6474 库了吗?
https://github.com/MotorDriver/L6474

它看起来相当彻底,但我没有使用他提供的演示从 SPI 返回合理的状态字节。演示使电机移动,但我不确定 SPI 是否正常工作。

我希望将其用作将 L6474 引入 GRBL 的基础,并且有点假设它是工作代码。

添加 SPI #748

是的,我在工作的一个项目中使用了一个 L6474,我还有一个运行在 Nucleus stm32f411 + 3*L6474 上的 grbl 端口。
我看过该库,它具有此类库始终具有的优点和缺点,它们非常
通用。我做的更简单,一个函数写入设置所有
寄存器所需的字节,一个函数启用/禁用输出,一个函数读取状态

至于状态,请记住许多状态位都是低电平有效

添加 SPI #748
作者

谢谢 langwadt,你愿意分享 grbl 的 Nucleo 端口吗?Stm32f4 + 3*L6474 是我的目标。让这个在 Arduino 上工作只是掌握使用该库作为示例代码以菊花链方式连接三个板的第一步。在这种情况下用作库显然太笨重了。我已经删除了要添加到 grbl 的要点,并且初始构建只添加了大约 800 个字节。

我发现我没有从 SPI 获得正确的回报,所以回到图书馆演示,发现那里发生了同样的事情。所以我不确定这个库是有问题还是我有接线错误。

如果您已经在 stm32f4 上进行了这项工作,那么我将节省大量时间来重新发明那个特定的轮子。谢谢。

添加 SPI #748
作者

我即将让 GRBL + L6474 在 Arduino 上工作。

显然有一些额外的开销,而且 GRBL 已经非常紧张了。你们有我可以运行的压力测试吗?当我连接硬件并开始向它抛出一些 gcode 时,我特别想到堆栈和堆溢出。

这是一台很重的机器,我不希望在硬件测试期间出现这样的东西。

我可以发明一些测试,但随着项目的成熟,我想有人已经这样做了。有什么建议么?

谢谢。

添加 SPI #748
作者

我有一堆三个 L6474 使用 GRBL,代码大小 30440 字节。可以稍微修剪一下,但这完全在代码限制之内。

如果存在将输出置于 HiZ 状态的严重错误,它会像限制引脚一样硬停止;用于热警告的软停止;并且只清除非关键错误,如错误的命令字节。我使用了 INT0,因为这就是 L6474 的接线方式。通过在 ISR 的顶部重新打开 sei() ,它对 GRBL 时序的干扰最小。

所有这些都经过适当的测试,但简单的 circle.gcode 示例确认 GRBL 仍在运行。

感谢以上所有人的帮助。;)

添加 SPI #748

你好@J-Dunn:我也在尝试使用类似于 L6474 但具有更高额定电流的 powerSTEP01 来运行 GRBL。您能否分享您的代码或项目,适用于 Arduino+GRBL+L6474。我还计划将来使用 STM32。但只是想先尝试 Arduino,因为我已经使用 Arduino+GRBL_Easy Driver 来运行小型 CNC。

谢谢你和这里的其他人。你的讨论很有启发性。

-卡兹

添加 SPI #748
作者

嗨,我没有任何处于可发布状态的东西,它们都是 WIP。如果我在不久的将来有一点时间,我会考虑一下。

我目前正在移植 stm32 代码以与 STEP01 板一起工作,尽管我一直试图通过合适的编译器开关保留以前的代码库,但在它再次在 AVR 上工作之前可能会进行一些调试。

step01 代码已准备好在硬件上进行测试,我可以通过更改一个 #define 将其从 L6474 翻转到 Step01。

添加 SPI #748

好吧。谢谢@J-Dunn.
会定期检查您的帖子。

添加 SPI #748
作者
J-邓恩 评论了 2017 年 3 月 18 日  

为了不给你留下任何东西,这里是我认为是最新版本的 L6474 的 AVR 文件。以通常的方式将它们添加为库。我使用 arduino makefile 使用 Geany 编辑器构建和调试,以摆脱可怕的 Arduino 伪 IDE,但我认为它仍然可以在 IDE 中工作。

它为 Arduino 顶部的最多三个 L6474 板提供基本的 SPI 通信。3 板 get_status() 的往返时间约为 19us,足够快以适应 Arduino GRBL 通常的最高速度。该代码刚好适合大约 140b 备用 IIRC 的内存。

https://github.com/J-Dunn/grbl_stm32/blob/master/grbl_L6474_latest.bz2

您将需要更改基本 GRBL 代码以调用需要的库函数。抱歉,我手边没有完整的点击即走解决方案,但您有一个快速工作界面的胆量。其余部分应该相当明显:将 FLAG 引脚设置为 GRBL 限制输入等。

在 c 文件的末尾,您将找到一个用于 FLAG 引脚的中断处理程序,用于分类关键和非关键错误并提供一些 USB 输出。

当我完成对 STEP01 代码的调试后,我可能会有更完整的东西。

这不是为了发布而整理的,它是所见即所得的,“按原样”提供大量评论,可能还有一些不相关或神秘的调试说明。我希望它有用。

添加 SPI #748
马什菲克 评论了 2017 年 3 月 23 日 通过电子邮件
喜欢 (0)