Spi
更新时间:2017-08-08 阅读:14801
目录
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线,对不同的外围设备进行通信
写一个程序关于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); }