
4.9 Arduino SPI
串行外设接口(Serial Peripheral Interface,SPI)是一种高速的、全双工、同步的通信总线,并且在芯片的管脚上只占用4根线,节约了芯片的管脚,同时为PCB的布局节省空间,提供方便。
SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。
(1)MOSI(Master In Slave Out):主器件数据输出,从器件数据输入。
(2)MISO(Master Out Slave In):主器件数据输入,从器件数据输出。
(3)SCK(Serial Clock):时钟信号,由主器件产生,最大为fPCLK/2,从模式频率最大为fCPU/2。
(4)SS:从器件使能信号,由主器件控制,有的IC会标注为CS(Chip Select)。
其中,SS是控制芯片是否被选中的,也就是说,只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效。这就允许在同一总线上连接多个SPI设备成为可能。
Arduino开发板ICSP接口中包含MOSI、MISO、SCK为SPI接口,如图4-4所示,有的开发板D11、D12、D13管脚默认和SPI接口连接(如UNO PLUS)。

图4-4 Arduino UNO开发板ICSP
不同的Arduino开发板的SPI引脚如表4-1所示。
表4-1 不同的Arduino开发板的SPI引脚

注意:MOSI、MISO、SCK的使用必须与ICSP的物理位置一致才有效。
Arduino IDE自带的SPI例程,在Arduino IDE的菜单中选择“文件”>“示例”>“SPI”>“DigitalPotControl”命令,打开工程,如图4-5所示。
这个例程介绍如何使用串行外设接口(SPI)来控制AD5206数字电位器,当需要用电而不是用手来改变电路中的电阻时,数字电位器是有用的。示例应用包括LED调光、音频信号调节和音频生成。在这个例子中,将使用一个6通道的数字电位器来控制6个LED的亮度。

图4-5 Arduino自带的SPI例程
AD5206是一个6通道数字电位器。这就意味着有6个可变电阻(电位器)内置在个人电子控制。有6个内部可变电阻的三引脚芯片,独特的可变电阻引脚标记为Ax,Bx和Wx,即A1、B1和W1。例如,在本教程中,我们将用每个可变电阻作为一个电压分压器,把一个引脚(引脚B)拉高,另一侧引脚(引脚A)拉低,并采取可变电压输出的中心引脚(Wiper)。在这种情况下,该AD5206提供一个最大值10000欧姆的电阻,分为255个等级(255是最大,0最小)。
例程的接线图如图4-6所示。

图4-6 例程的接线图
例程的代码如下:


程序先引入SPI头文件SPI.h。SPI接口包含MOSI、MISO、SCK、CS四根线。其中MOSI、MISO、SCK已经固定引脚。而CS为片选引脚,可随意选择某个引脚作为CS。程序中const int slaveSelectPin=10,定义D10作为片选信号。
程序先引入SPI头文件SPI.h。SPI接口包含MOSI、MISO、SCK、CS四根线。其中MOSI、MISO、SCK已经固定引脚。而CS为片选引脚,可随意选择哪个引脚作为CS。程序中const int slaveSelectPin=10,定义D10作为片选信号。
setup()函数调用SPI.begin()初始化SPI接口。此处为默认设置。若要设置具体参数可使用如下语句初始化SPI:

SPISettings()函数设置SPI传输模式,SPI.beginTransaction()函数根据SPISettings()初始化SPI。
此处设置SPI速率为14MHz,高位先传输,模式0。
传输SPI前先拉低片选管脚,使能SPI设备,语句如下:

使用SPI传输函数,参数val为要发送的字节,函数返回值为接收到的数据,语句如下:

SPI传输结束后释放片选管脚,语句如下:

Arduino开发板也可以通过SPI接口读写存储模块,例如Micro SD卡,读写Micro SD卡模块如图4-7所示。

图4-7 Micro SD卡SPI接口读写模块
TF卡模块使用SPI总线连接方式实现与Arduino控制器的通信,稳压芯片输出的3.3V为电平转换芯片、Micro SD卡进行供电,电平转换电路往Micro SD卡方向的信号转换成3.3V,Micro SD卡往控制接口方向的MISO信号也转换成了3.3V,一般AVR单片机系统都可以读取该信号,产品使用自弹式卡座,方便卡的插拔。
注意:Arduino的sd.h库文件目前对2GB及其以下的支持比较好,对2GB以上的支持不好,所以在使用时,建议选用2GB或以下的内存卡。
TF卡模块共引出6个引脚,其中DO、CK、DI是SPI总线接口,“+”为电源正,“-”为电源GND,CS为片选端,实际使用时按照下面的接线图连接即可,使用Arduino IDE自带的例子程序就可以进行测试。
连接示意图如图4-8所示。

图4-8 SPI总线读写存储模块Micro SD卡连接示意图