我想知道在微控制器上使用GPIO调用(bitbanging)是否有任何特别快速的方法来读取或写入串行协议(如SPI)。最快的可能是某种特定于体系结构的,但是在任何体系结构中,较少数量的操作可能更快。假设端口读/写和任何按位整数操作在单个cpu时钟中发生是公平的。比较和跳跃可能是几个时钟。
举一个简单的例子,假设使用传统SPI写一个字节,给定一个端口(寄存器),带有用于串行时钟,miso(输入),mosi(输出)引脚的位掩码。要在时钟port |= CLOCK|OUTPUT; port &= ~CLOCK;
的下降沿输出1位,写入一个字节将包括对该字节中的每个位(输出0或1)进行循环。
这样的事情:
uint8_t data;
// for each bit, msb first
for (i = 7; i >= 0; i--)
{
if ((data >> i) & 0x01)
{
// set output pin to 1
port |= OUTPUT;
}
else
{
// set output pin to 0
port &= ~OUTPUT;
}
// strobe clock
port |= CLOCK;
port &= ~CLOCK;
}
对此的一些优化是显而易见的,例如展开循环。
某些优化可能不那么明显:是否可以根据要写入的字节(或仅仅是其中的一部分)进行切换,从而避免每一位移位和屏蔽?如何让这个分支免费?如何利用0或0的运行? (在这种情况下,无需更改输出,只需更改时钟)如何在一次操作中更改输出和时钟?
使用其中一些技巧的示例(尽可能在一个操作中更改输出和时钟,展开循环,但不是无分支): https://github.com/FastLED/FastLED/blob/master/fastspi_bitbang.h