Arduino SPI 通信
原文地址:http://www.gammon.com.au/forum/?id=10892
原文地址:http://www.geek-workshop.com/thread-4781-1-1.html
SPI的英文全称是:“Serial Peripheral Interface”,翻译成中文的意思是串口通信外围设备接口技术。也就是把数据用串口传输方式进行交换。它有一个主控制器,一般我们采用微处理器,比如常用的单片机,以及一些其它的外围设置,比如数码管,液晶显示频,SD卡等外围设备。
它一般是由5根线组成的:分别是MOSI,MISO,SCK, SS以及地线,电源线。
MOSI:是由主机向设备发出数据的。
MISO:是由设备向主机发送数据的。
SCK:是起到一个控制数据传输的校准,根据arduino官方的说法,好像还具备有对数据全能的控制作用。
SS线是用于一根使能线,特别是接多个外围设备的时候,可以通过控制SS线,对不同的外围设备进行通信。
在arduino2009板上,10脚是SS,11脚是MOSI, 12脚是MISO,13脚是时钟引脚。当然在同时用这几根引脚控制多个外围设备的时候,SS引脚可以是其它引脚,比如arduinoEhthernet模块,利用第4个引脚去控制SD卡的SS端。第10引脚控制Enthernet模块的SS端,下面是三种不同的硬件接法示意图:
写一个程序关于SPI必须注意的问题有:
1. 字节的传输是从最高位(MSB)传输,还是从最低位(LSB)传输呢?这是由SPI.setBitOrder()函数进行设置的。
2. 当数据不传输时,时钟线是高还是低?
3. 触发方式是上升沿触发还是下降沿触发呢?这个由SPI.setDataMode()函数进行设置。
4. SPI运行的速度是多快呢?这个由SPI.setClockDivider()函数进行设置。
#include <SPI.h>
void setup (void)
{
Serial.begin(9600); // 开始串口通讯
digitalWrite(SS, HIGH);
SPI.begin (); // PI通讯开始
//SPI.setClockDivider(SPI_CLOCK_DIV8); //??
}
void loop (void)
{
char c;
// 片选为从机
digitalWrite(SS, LOW); // SS - pin 10
// 发送字串
for (const char * p = "Hello, world!\n" ; c = *p; p++) {
SPI.transfer (c);
Serial.print(c);
}
// 取消从机
digitalWrite(SS, HIGH);
delay (1000);
}
#include <SPI.h>
char buf [100];
volatile byte pos;
volatile boolean process_it;
void setup (void)
{
Serial.begin (9600);
// have to send on master in, *slave out*
pinMode(MISO, OUTPUT);
// 设置为接收状态
SPCR |= _BV(SPE);
// 准备接受中断
pos = 0; // 清空缓冲区
process_it = false;
// 开启中断
SPI.attachInterrupt();
}
// SPI 中断程序
ISR (SPI_STC_vect)
{
byte c = SPDR; // 从 SPI 数据寄存器获取数据
if (pos < sizeof(buf))
{
buf [pos++] = c;
if (c == '\n')
process_it = true;
}
}
void loop (void)
{
if (process_it)
{
buf [pos] = 0;
Serial.println (buf);
pos = 0;
process_it = false;
}
}