Arduino AVR 中断掩码清除

Arduino AVR interrupts mask clearing

我正在使用 firmata 协议 (firmata protocol) 构建一些软件,以在 arduino 上提供一些功能并通过 USB 管理板。

我使用零交叉连接到 arduino 调光器并编写自定义协议命令来更改调光器的状态 (Dimmer library)。一切正常,但 lamp 有时会闪烁。

我认为问题是 firmata 正在使用 AVR cli() 宏来清除中断掩码 (code) 然后 lamp 闪烁。

有什么方法可以阻止清除中断屏蔽(安全吗?)? 有什么方法可以实现无中断调光?

您不能阻止特定指令的执行。

我不知道提到的任何图书馆,但可以根据原则回答:

通常,clisei 指令对用于确保在某些中断干扰例程时中断的代码片段的原子执行。

通常没有中断丢失,因为中断标志仍然设置并且 ISR 在 sei 指令之后执行。但是由于没有中断队列,每种中断只能保留一个。

如果您的 ISR 逻辑希望立即被调用,也可能会出现一些故障 - 例如因为在 Pin-Change-Interrupt 上检查当前 PIN-states,或者因为它期望某个定时器计数器的计数不超过几个周期并设置一个新的比较值(例如,在位角调制的情况下)。在这种情况下,计时器可能已经比 ISR 开始之前的新比较值计数得更多,并产生毛刺。

如果是这种情况,我认为您只有几个选择:

  • 查看 firmata 驱动程序的源代码并尝试缩小 cli() 和 sei()` 之间的源代码以减少中断被锁定的时间。
  • 尝试修复调光器库以处理 ISR 执行延迟的情况。也许可以去掉这个事件的视觉感知

但也许可以考虑以下事项之一:

  • 两个库的设计不兼容
  • AVR 对两者都进行适当处理的速度较慢,因此它总是会丢失一些 ISR

如果您坚持使用 AVR - 可以将外部协议解码留在一个上,并构建一个带有非常简单协议的小 UART/SPI 通道到另一个通道,并在其上 运行 调光灯控制逻辑。