SPI 通信

片选信号

大多数从器件具有有效的低芯片选择输入。因此,初始化和使用芯片选择引脚的正确代码是:

#define CSPIN 1 // or whatever else your CS pin is
// init:
pinMode(CSPIN, OUTPUT);
digitalWrite(CSPIN, 1); // deselect

// use:
digitalWrite(CSPIN, 0); // select
... perform data transfer ...
digitalWrite(CSPIN, 1); // deselect

取消选择从站与选择它同样重要,因为从站可以在选择时驱动 MISO 线。可能有很多 slave,但只有一个可能会推动 MISO。如果未正确取消选择从站,则两个或多个从站可能正在驱动 MISO,这可能导致其输出之间出现短路并可能损坏设备。

交易

交易有两个目的:

  • 告诉 SPI 什么时候我们想要在特定的上下文中开始和结束使用它
  • 为特定芯片配置 SPI

时钟线在不同的 SPI 模式下具有不同的空闲状态。选择从器件时更改 SPI 模式可能会使从器件混淆,因此在选择从器件之前始终要设置 SPI 模式。可以使用传递给 SPI.beginTransactionSPISettings 对象设置 SPI 模式:

SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
digitalWrite(CSPIN, 0);
... perform data transfer ...
digitalWrite(CSPIN, 1);
SPI.endTransaction();

SPISettings 也可以存储在别处:

SPISettings mySettings(1000000, MSBFIRST, SPI_MODE0);
SPI.beginTransaction(mySettings);

如果代码的另一部分试图在对 beginTransaction()endTransaction() 的一对调用之间使用 SPI,则可能会引发错误 - 如何完成取决于实现。

另见 Arduino 参考:SPISettings

在中断服务程序中使用 SPI

如果必须在 ISR 中使用 SPI,则不能同时进行其他事务。SPI 库提供了 usingInterrupt(interrupt_number) 来促进这一点。它通过在调用 beginTransaction() 时禁用给定的中断来工作,因此中断不能在调用 beginTransaction()endTransaction() 之间触发。

另请参阅 Arduino 参考:SPI:usingInterrupt