Arduino SPI 在传输过程中挂起
Arduino SPI hangs during transfers
我正在做一个项目,不知所措。我设法让 2 个 Arduinos 通过 SPI 相互交谈,但是从站在一系列传输过程中停止了,似乎没有理由。
真正令人不安的是,如果我从 master 发送更多传输,它会继续这个系列,就好像它在等待继续。
我认为有一些确认或标志停止代码执行,但我不知道。
#include <SPI.h>
boolean ack = 0;
#define ACK 2
byte buffer = 0;
byte rx = 0;
bool SSlast = HIGH;
byte clr = 0;
void stat_upd(byte dat, byte ric) {
Serial.println("---------------------------------------------");
Serial.println("Sent:");
Serial.println(dat, HEX);
Serial.println("Received:"); // 0x81 in teoria
Serial.println(ric, HEX);
return;
}
// Initialize SPI slave.
void SlaveInit(void) {
// Initialize SPI pins.
pinMode(SCK, INPUT);
pinMode(MOSI, INPUT);
pinMode(MISO, INPUT);
pinMode(SS, INPUT);
pinMode(ACK, OUTPUT);
// Enable SPI as slave.
SPCR = 0x6F;
clr = SPSR;
clr = SPDR;
SPI.begin();
}
// SPI Transfer.
byte SPItransfer(byte value) {
byte temp = 0;
SPDR = value;
// temp =SPI.transfer(value);
while (!(SPSR & (1 << SPIF)));
digitalWrite(ACK, LOW);
delay(1);
digitalWrite(ACK, HIGH);
delay(10);
return SPDR;
}
// The setup() function runs after reset.
void setup() { ///////////////// setup
Serial.begin(9600);
SlaveInit();
Serial.println("MC Initialized");
}
void loop() { ////////////// loop
// Slave Enabled?
if (!digitalRead(SS)) {
rx = SPItransfer(0x00);
stat_upd(0x00, rx);
rx = SPItransfer(0x08);
stat_upd(0x08, rx);
rx = SPItransfer(0x5a);
stat_upd(0x5a, rx);
rx = SPItransfer(0x5d);
stat_upd(0x5d, rx);
rx = SPItransfer(0x5c);
stat_upd(0x5c, rx);
rx = SPItransfer(0x5d);
stat_upd(0x5d, rx);
rx = SPItransfer(0x04);
stat_upd(0x04, rx);
rx = SPItransfer(0x00);
stat_upd(0x00, rx);
rx = SPItransfer(0x00);
stat_upd(0x00, rx);
rx = SPItransfer(0x80);
stat_upd(0x80, rx);
}
}
这是一个猜测,但我对 Arduino 代码的猜测往往是正确的。
检查您是如何通过 Master 发送数据的。
根据这段代码,从设备等待 SS 引脚变为低电平,然后与 SPI 通信,然后清除 ack 引脚 1 毫秒,然后通过串行端口将通信数据发送到 PC。
我在这里看到的问题是 1 毫秒对于主控器来说太短了,无法正确检测到它。
所以我的猜测是,您以这样的方式编写了主代码,它不查看 ACK 引脚。这意味着主机将清除 SS 引脚,进行通信,然后立即清除 SS 引脚。
这是一个问题,因为一旦通信完成,从站就会与串行端口通信。这意味着当主机再次将 SS 引脚设置为低电平时,从机可能正在向串行监视器发送数据,并且可能会完全错过通信。
要解决此问题,您需要更改从代码以在 SS 引脚为低电平时继续与主机通信,并且仅在 SS 引脚变为高电平时才将数据发送回串行监视器。
我正在做一个项目,不知所措。我设法让 2 个 Arduinos 通过 SPI 相互交谈,但是从站在一系列传输过程中停止了,似乎没有理由。
真正令人不安的是,如果我从 master 发送更多传输,它会继续这个系列,就好像它在等待继续。
我认为有一些确认或标志停止代码执行,但我不知道。
#include <SPI.h>
boolean ack = 0;
#define ACK 2
byte buffer = 0;
byte rx = 0;
bool SSlast = HIGH;
byte clr = 0;
void stat_upd(byte dat, byte ric) {
Serial.println("---------------------------------------------");
Serial.println("Sent:");
Serial.println(dat, HEX);
Serial.println("Received:"); // 0x81 in teoria
Serial.println(ric, HEX);
return;
}
// Initialize SPI slave.
void SlaveInit(void) {
// Initialize SPI pins.
pinMode(SCK, INPUT);
pinMode(MOSI, INPUT);
pinMode(MISO, INPUT);
pinMode(SS, INPUT);
pinMode(ACK, OUTPUT);
// Enable SPI as slave.
SPCR = 0x6F;
clr = SPSR;
clr = SPDR;
SPI.begin();
}
// SPI Transfer.
byte SPItransfer(byte value) {
byte temp = 0;
SPDR = value;
// temp =SPI.transfer(value);
while (!(SPSR & (1 << SPIF)));
digitalWrite(ACK, LOW);
delay(1);
digitalWrite(ACK, HIGH);
delay(10);
return SPDR;
}
// The setup() function runs after reset.
void setup() { ///////////////// setup
Serial.begin(9600);
SlaveInit();
Serial.println("MC Initialized");
}
void loop() { ////////////// loop
// Slave Enabled?
if (!digitalRead(SS)) {
rx = SPItransfer(0x00);
stat_upd(0x00, rx);
rx = SPItransfer(0x08);
stat_upd(0x08, rx);
rx = SPItransfer(0x5a);
stat_upd(0x5a, rx);
rx = SPItransfer(0x5d);
stat_upd(0x5d, rx);
rx = SPItransfer(0x5c);
stat_upd(0x5c, rx);
rx = SPItransfer(0x5d);
stat_upd(0x5d, rx);
rx = SPItransfer(0x04);
stat_upd(0x04, rx);
rx = SPItransfer(0x00);
stat_upd(0x00, rx);
rx = SPItransfer(0x00);
stat_upd(0x00, rx);
rx = SPItransfer(0x80);
stat_upd(0x80, rx);
}
}
这是一个猜测,但我对 Arduino 代码的猜测往往是正确的。
检查您是如何通过 Master 发送数据的。
根据这段代码,从设备等待 SS 引脚变为低电平,然后与 SPI 通信,然后清除 ack 引脚 1 毫秒,然后通过串行端口将通信数据发送到 PC。
我在这里看到的问题是 1 毫秒对于主控器来说太短了,无法正确检测到它。
所以我的猜测是,您以这样的方式编写了主代码,它不查看 ACK 引脚。这意味着主机将清除 SS 引脚,进行通信,然后立即清除 SS 引脚。
这是一个问题,因为一旦通信完成,从站就会与串行端口通信。这意味着当主机再次将 SS 引脚设置为低电平时,从机可能正在向串行监视器发送数据,并且可能会完全错过通信。
要解决此问题,您需要更改从代码以在 SS 引脚为低电平时继续与主机通信,并且仅在 SS 引脚变为高电平时才将数据发送回串行监视器。