从带有wiringPI2的Arduino slave读取Raspberry PI SPI?

lar*_*pts 2 arduino spi raspberry-pi raspbian

我已经在NOOBS Raspbian PI发行版上安装了wiringpi2wiringpi2 python包装器.Adafruit 4通道逻辑电平转换器将PI保持在5v以下,并且在PI端向Arduino发送数据就像这样简单:

import wiringpi2
wiringpi2.wiringPiSPISetup(1,5000)
wiringpi2.wiringPiSPIDataRW(1,'HELLO WORLD\n')
Run Code Online (Sandbox Code Playgroud)

和相应的Arduino代码[3].

编辑:道歉 - 从这一点开始,我不能发布任何我仔细添加的链接来显示我的工作,来源和示例代码.你必须谷歌它并感谢双链接规则.

所以,我知道布线工作.但这不是我真正想要的方式 - 我想读一个从Arduino到PI的引脚.

Arduino SPI参考指出:

该库允许您与SPI设备通信,Arduino作为主设备.

PI必须是主设备.我以为自己注定要失败,直到我读到Nick Gammon关于SPI的优秀网页,它展示了2个Arduinii互相交谈.

此外,SPI transfer()命令会建议您从Arduino写入.

我现在处于Google的前4个结果页面的所有链接显示为"跟随"的阶段 - 所以这不是因为缺少谷歌搜索!

理论上,如果我在PI端使用READ方法,这不应该工作吗?(注意:这只是众多尝试中的一种,而不是唯一的尝试!)

在Arduino上:

#include <SPI.h>
void setup (void)
{
  SPI.begin();
  pinMode(MISO, OUTPUT);

  // turn on SPI in slave mode
  SPCR |= _BV(SPE);
}

void loop  (void) {
byte data[] = {0x00, 0x00, 0x00, 0x00};  // this is 24 bits (8bits/byte * 4 bytes)
// Transfer 24 bits of data
for (int i=0; i<4; i++) {
   SPI.transfer(data[i]);   // Send 8 bits
}
}
Run Code Online (Sandbox Code Playgroud)

在PI的最后:

import wiringpi2
wiringpi2.wiringPiSPISetup(1,5000)
stuff = wiringpi2.wiringPiSPIDataRW(1,'\n')
print stuff
Run Code Online (Sandbox Code Playgroud)

WiringPI表示传入的数据会覆盖我的数据,而SPIDataRW只需要2个输入,所以我不应该再次"测试"了吗?

我在这里错过了什么?任何指针都非常感激.

Phi*_*lip 5

SPI库假设您希望arduino充当主设备.你不能用它来让arduino充当奴隶.有时你必须跳过这些库到芯片的数据表中,看看它是如何工作的.(然后,理想情况下,从你所有的烦恼中建立一个图书馆)

SPI从设备必须对主设备作出反应以启动通信.

因此,作为SPI主控制器的Pi必须在MOSI线上发送虚拟字节,并​​读取Arduino在MISO线上回复的内容.即主人发起沟通.

在arduino端,您可以使用以下命令打开SPI中断:

SPCR |= _BV(SPIE);
Run Code Online (Sandbox Code Playgroud)

它内置于atmega328芯片中.因此,在arduino端包含下一位,以查看传入消息并设置下一条消息的响应.arduino SPI从器件响应的数据是主器件发送消息时数据寄存器中的数据.

int gCurrentSpiByte;  //or set up your a buffer or whatever
ISR (SPI_STC_vect)
{
  gCurrentSpiByte = SPDR;  // grab byte from SPI Data Register
  SPDR = buf[messageCount++]; //Set the data to be sent out on the NEXT message.
}
Run Code Online (Sandbox Code Playgroud)

请记住,你GOTTAGOFAST.如果arduino在下一个SPI消息到来之前没有退出该中断服务程序,那么一切都会变成地狱.

另外,检查以确保Pi和Arduino之间的时钟极性和相位相同(也称为模式0-3).

| 7    | 6    | 5    | 4    | 3    | 2    | 1    | 0    |
| SPIE | SPE  | DORD | MSTR | CPOL | CPHA | SPR1 | SPR0 |

SPIE - Enables the SPI interrupt when 1
SPE - Enables the SPI when 1
DORD - Sends data least Significant Bit First when 1, most Significant Bit first when 0
MSTR - Sets the Arduino in master mode when 1, slave mode when 0
CPOL - Sets the data clock to be idle when high if set to 1, idle when low if set to 0
CPHA - Samples data on the falling edge of the data clock when 1, rising edge when 0
SPR1 and SPR0 - Sets the SPI speed, 00 is fastest (4MHz) 11 is slowest (250KHz)
Run Code Online (Sandbox Code Playgroud)

所以要打开SPI,SPI中断,并将极性设置为......无论是什么......

SPCR |= _BV(SPIE) | _BV(SPE) | _BV(CPOL) ;
Run Code Online (Sandbox Code Playgroud)

无论如何,我花了几天时间用Arduino SPI敲打,这就是我学到的东西.