Fireduino 开源创意平台 立即购买

拥有双核Cortex-M3处理器,集成高质量音频Codec和WiFi模组,拥有良好的IOT扩展性能,完美兼容Arduino IDE和Arduino标准接口,并支持FireBlock图形化编程软件,是一款首选的编程启蒙教学平台,更是一款开源的创意原型平台。

Spi

更新时间:2017-08-08 阅读:1990

Serial Peripheral Interface(SPI)

SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,在主芯片的管脚上主要占用四根线。

MOSI – 主设备数据输出,从设备数据输入;

MISO – 主设备数据输入,从设备数据输出;

SCLK – 时钟信号,由主设备产生;

SS – 从设备使能信号,由主设备控制

其中MOSI/MISO/SCLK三根线实现全双工的通信,简单高效了,由于器件的寻址通过一个SS片选脚来指定,当连接多台SPI设备时,需要多个片选信号。

SCLK提供时钟脉冲,MOSI,MISO则基于此脉冲完成数据传输。数据输出通过 MOSI线,数据在时钟上升沿/下降沿时改变,在紧接着的下降沿/上升沿被读取。完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟的改变(上沿和下沿为一次),就可以完成8位数据的传输。

SS线是用于一根使能线,特别是接多个外围设备的时候,可以通过控制SS线,对不同的外围设备进行通信

FireDuino 02125425.jpg


写一个程序关于SPI必须注意的问题有:

1. 字节的传输是从最高位(MSB)传输,还是从最低位(LSB)传输呢?这是由SPI.setBitOrder()函数进行设置的。

2. 当数据不传输时,时钟线是高还是低?

3. 触发方式是上升沿触发还是下降沿触发呢?这个由SPI.setDataMode()函数进行设置。

4. SPI运行的速度是多快呢?这个由SPI.setClockDivider()函数进行设置

Fireduino SPI API

SPISettings(speed, dataOrder, dataMode)

   speed:CLK 时钟速率
dataOrder: MSBFIRST or LSBFIRST
dataMode : SPI_MODE0, SPI_MODE1, SPI_MODE2, or SPI_MODE3

begin()

   说明
       根据参数初始化SPI总线。
语法 SPI.begin() SPI.begin(10) 参数 1.无 2.片选 返回 无

beginTransaction()

   说明 
       使用定义SPISettings 初始化 SPI总线。

   语法 
       SPISettings  mySettings = SPISettings(14000000, MSBFIRST, SPI_MODE0); 
       SPI.beginTransaction(mySettings);
or
SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0)) 参数 mySettings: SPISettings 类型设置参数
返回 无

endTransaction()

   说明 
       停止使用SPI总线。

   语法 
       SPI.endTransaction()

   参数 
       无

返回 无

transfer(...)

transfer16(...)

   说明 
       用于在SPI总线上传输数据,包括发送与接收。

   语法 
       receivedVal = SPI.transfer(val)
       receivedVal16 = SPI.transfer16(val16)
       SPI.transfer(buffer, size)

   参数 
       val:在总线上传输的字节
       val16:在总线上传输的半字
       buffer:在总线上传输的buffer

   返回 
       从SPI总线上接收的数据值

end()

   说明 
       停止SPI总线的使用(保持引脚的模式不改变)。

   语法 
       SPI.end()

   参数 
       无

   返回 
       无

setBitOrder(...)

   说明 
       设置串行数据传输时,先传输高位还是低位,有LSBFIRST(最低位在前)和MSBFIRST(最高位在前)两种类型可选。

   语法 
       SPI.setBitOrder(order)

   参数 
       order:LSBFIRST(最低位在前)或MSBFIRST(最高位在前)

   返回 
       无

setDataMode(...)

   说明 
       设置SPI的数据模式,即:时钟极性和时钟相位。 
       时钟极性:表示时钟信号在空闲时是高电平还是低电平; 
       时钟相位:决定数据是在SCK的上升沿采样还是在SCK的下降沿采样。 
       包含四种数据模式(详见参数),采样时,应先准备好数据,再进行采样。

   语法 
       SPI.setDataMode(mode)

   参数 
       mode: 
           SPI_MODE0(上升沿采样,下降沿置位,SCK闲置时为0),
           SPI_MODE1(上升沿置位,下降沿采样,SCK闲置时为0),
           SPI_MODE2(下降沿采样,上升沿置位,SCK闲置时为1),
           SPI_MODE3(下降沿置位,上升沿采样,SCK闲置时为1)。
   返回 
       无   

setClockDivide(...)

   说明
       设置SPI串行通信的时钟。通信时钟是由系统时钟分频而得到,分频值有2,4,8,16,32,64或128。默认设置是SPI_CLOCK_DIV4,设置SPI串行通信时钟系统时钟的四分之一,即400000。

   语法 
       SPI.setClockDivider(divider)

   参数 
       divider: 
           SPI_CLOCK_DIV2
           SPI_CLOCK_DIV4
           SPI_CLOCK_DIV8
           SPI_CLOCK_DIV16
           SPI_CLOCK_DIV32
           SPI_CLOCK_DIV64
           SPI_CLOCK_DIV128
   返回 
       无   

SPI 示例程序

#include <Arduino.h>
#include "SPI.h"
#define SPI_CS
const int chipSelectPin = 10;
const int chipResetPin = 9;
void setup() {
	Serial.begin(115200);
#ifdef SPI_CS
	Serial.print("\r\nSPI_CS  YES...\r\n");
	SPI.begin(10);
#else
	Serial.print("\r\nSPI_CS  NO...\r\n");
	SPI.begin();
	pinMode(chipSelectPin, OUTPUT);
	digitalWrite(chipSelectPin, LOW);
#endif
	SPI.setBitOrder(MSBFIRST);
	SPI.setClockDivider(2);
	SPI.setDataMode(SPI_MODE0);
 
	pinMode(chipResetPin, OUTPUT);
	digitalWrite(chipResetPin, LOW);	
	delay(10);
	digitalWrite(chipResetPin, HIGH);	
	delay(10);
}
void loop() {
	unsigned char version;
#ifdef SPI_CS
	SPI.transfer(0x00,SPI_CONTINUE);
	SPI.transfer(0x39,SPI_CONTINUE);
	SPI.transfer(0x00,SPI_CONTINUE);
	version = SPI.transfer(0x00);
#else
	digitalWrite(chipSelectPin, LOW);
	SPI.transfer(0x00);
	SPI.transfer(0x39);
	SPI.transfer(0x00);
	version = SPI.transfer(10,0x00);
	digitalWrite(chipSelectPin, HIGH);
#endif
 
	Serial.print("version:");
	Serial.println(version);
	delay(1000);
}