简体   繁体   English

从Raspberry从属设备读取带有Raspberry Pi 2的Raspberry PI SPI?

[英]Raspberry PI SPI read from Arduino slave with wiringPI2?

I've got wiringpi2 and the the wiringpi2 python wrapper installed on the NOOBS Raspbian PI distro. 我已经在NOOBS Raspbian PI发行版上安装了connectionpi2connectionpi2 python包装器 The Adafruit 4 channel logic level converter kept the PI safe from 5v and sending data to the Arduino was as simple as this on the PI side: Adafruit 4通道逻辑电平转换器使PI不受5v的影响,并且在PI端向Arduino发送数据非常简单:

import wiringpi2
wiringpi2.wiringPiSPISetup(1,5000)
wiringpi2.wiringPiSPIDataRW(1,'HELLO WORLD\n')

and the corresponding Arduino code[3]. 以及相应的Arduino代码[3]。

EDIT: Apologies - from this point on, I can't post any more of the links I carefully added to show my working, sources and example code. 编辑:道歉-从现在开始,我不能再张贴我精心添加的链接以显示我的工作,源代码和示例代码。 You'll have to Google it and thank the 2-link rule. 您必须使用Google并感谢2链接规则。

So, I know the wiring works. 因此,我知道接线有效。 But that's not the way round I actually want - I want to read a pin from the Arduino to the PI. 但这不是我真正想要的方式-我想读取Arduino到PI的引脚。

The Arduino SPI reference states: Arduino SPI参考指出:

This library allows you to communicate with SPI devices, with the Arduino as the master device. 该库允许您以Arduino为主要设备与SPI设备进行通信

The PI must be the master device. PI必须是主设备。 I thought I was doomed until I read Nick Gammon's excellent page about SPI which demonstrates 2 Arduinii talking to each other. 我以为自己注定要失败,直到阅读了Nick Gammon关于SPI的精彩页面,该页面演示了2 Arduinii互相交谈。

Also, the SPI transfer() command would suggest you CAN write from the Arduino. 另外, SPI transfer()命令将建议您可以从Arduino进行写入。

I'm now at the stage where all the links of the the first 4 result pages of Google show as "followed" - so it's not for lack of Googling! 我现在处于Google的前4个结果页面的所有链接都显示为“跟随”的阶段-因此,并不是因为缺乏谷歌搜索功能!

In theory, shouldn't this work if I use the READ method on the PI end? 从理论上讲,如果我在PI端使用READ方法,那么这行不通吗? (Note: this is just one of many, many attempts, not the only one!) (注意:这只是许多尝试中的一种,而不是唯一的一种!)

On the Arduino: 在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
}
}

And on the PI end of things: 在PI方面:

import wiringpi2
wiringpi2.wiringPiSPISetup(1,5000)
stuff = wiringpi2.wiringPiSPIDataRW(1,'\n')
print stuff

WiringPI says the incoming data will overwrite my data, and the SPIDataRW takes exactly 2 inputs, so shouldn't I be getting "test" back? WiringPI说传入的数据将覆盖我的数据,而SPIDataRW恰好接受2个输入,所以我不应该重新获得“测试”吗?

What am I missing here? 我在这里想念什么? Any pointers greatly appreciated. 任何指针,不胜感激。

The SPI library assumes you want the arduino to act as a master. SPI库假定您要让arduino充当主机。 You can't use it to get an arduino to act as a slave. 您不能使用它来使arduino充当奴隶。 Sometimes you have to dive past the libraries into the chip's datasheet and see how things work. 有时,您不得不从库中潜入芯片的数据表中,并查看其工作原理。 (and then, ideally, make a library from all your troubles) (然后,理想情况下,让您摆脱所有麻烦)

An SPI slave device has to react to the master initiating the communication. SPI从设备必须响应主设备才能启动通信。

So the Pi, as the SPI master, will have to send dummy bytes over the MOSI line and read what the Arduino replies on the MISO line. 因此,作为SPI主设备的Pi必须通过MOSI线路发送虚拟字节,并​​读取Arduino在MISO线路上的答复。 ie, master initiate communication. 即,主人发起沟通。

On the arduino side you can turn on the SPI interrupt with: 在arduino端,您可以使用以下命令打开SPI中断:

SPCR |= _BV(SPIE);

It's built into the atmega328 chip. 它内置在atmega328芯片中。 So include this next bit on the arduino side to see incoming messages and set the response for the next message. 因此,请在arduino端添加下一个位,以查看传入消息并设置下一条消息的响应。 The data that the arduino SPI slave responds with is whatever is in the data register when the master sends the message. 当主机发送消息时,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.
}

And remember, you GOTTAGOFAST. 记住,您是GOTTAGOFAST。 If the arduino doesn't exit that interrupt service routine before the next SPI message comes it, it all goes to hell. 如果arduino在下一条SPI消息到来之前没有退出该中断服务程序,则一切都会陷入困境。

Also also, check to make sure the clock's polarity and phase are the same between the Pi and the Arduino (otherwise known as modes 0-3). 另外,还要检查以确保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)

So to turn on SPI, the SPI interrupt, and to set the polarity to... whatever that is... 因此要打开SPI,SPI中断并将极性设置为...无论是什么...

SPCR |= _BV(SPIE) | _BV(SPE) | _BV(CPOL) ;

Anyway, I spent a couple days banging around with the Arduino SPI and that's what I learned. 无论如何,我花了几天时间来学习Arduino SPI,这就是我学到的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM