![创客机器人实战:基于Arduino和树莓派](https://wfqqreader-1252317822.image.myqcloud.com/cover/903/33892903/b_33892903.jpg)
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)。
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/56_01.jpg?sign=1738936794-JACO1jnwN7zkivDJmJqxFGOIjFGIJSk8-0-7f48378bb1d2606d4deadd9219d641c5)
图4-4 Arduino UNO开发板ICSP
不同的Arduino开发板的SPI引脚如表4-1所示。
表4-1 不同的Arduino开发板的SPI引脚
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/56_02.jpg?sign=1738936794-UJ3mPRKUlegJh5fJud4Q2hghBHrNt29K-0-c315893adcd2c667d365350a5f6b2b66)
注意:MOSI、MISO、SCK的使用必须与ICSP的物理位置一致才有效。
Arduino IDE自带的SPI例程,在Arduino IDE的菜单中选择“文件”>“示例”>“SPI”>“DigitalPotControl”命令,打开工程,如图4-5所示。
这个例程介绍如何使用串行外设接口(SPI)来控制AD5206数字电位器,当需要用电而不是用手来改变电路中的电阻时,数字电位器是有用的。示例应用包括LED调光、音频信号调节和音频生成。在这个例子中,将使用一个6通道的数字电位器来控制6个LED的亮度。
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/57_01.jpg?sign=1738936794-b3eiLoitSsh729FyPMhvr5u7fOws1zJk-0-6bf17d3bc1745cab6535da1cc1662489)
图4-5 Arduino自带的SPI例程
AD5206是一个6通道数字电位器。这就意味着有6个可变电阻(电位器)内置在个人电子控制。有6个内部可变电阻的三引脚芯片,独特的可变电阻引脚标记为Ax,Bx和Wx,即A1、B1和W1。例如,在本教程中,我们将用每个可变电阻作为一个电压分压器,把一个引脚(引脚B)拉高,另一侧引脚(引脚A)拉低,并采取可变电压输出的中心引脚(Wiper)。在这种情况下,该AD5206提供一个最大值10000欧姆的电阻,分为255个等级(255是最大,0最小)。
例程的接线图如图4-6所示。
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/57_02.jpg?sign=1738936794-3D70hjaH1awaHkF0rhYFlczOTTzyZFrU-0-078a90f44d1ebb2c900c8c82ea5f2cc9)
图4-6 例程的接线图
例程的代码如下:
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/57_03.jpg?sign=1738936794-Sd848VFeR42Hf0Qz61BmoUJP13wVKIcs-0-fb08a90bc6a5b68f54645e24cf288725)
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/58_01.jpg?sign=1738936794-pJFLiH9925c1sqxzqRV9APxTSVvijibC-0-48ba07723dbc20a1f13daa71b6ff9773)
程序先引入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:
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/58_02.jpg?sign=1738936794-i4lJCyfYXKpYPwODUw1GDgZAsKRnUSCl-0-e178986e4354bf7ba4fcc7b50919de24)
SPISettings()函数设置SPI传输模式,SPI.beginTransaction()函数根据SPISettings()初始化SPI。
此处设置SPI速率为14MHz,高位先传输,模式0。
传输SPI前先拉低片选管脚,使能SPI设备,语句如下:
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/58_03.jpg?sign=1738936794-sOlLxXw5HrtsyoT7NlUp1mZGLSbtcxdC-0-071a56f3781ac66e872fb89e578c7938)
使用SPI传输函数,参数val为要发送的字节,函数返回值为接收到的数据,语句如下:
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/58_04.jpg?sign=1738936794-PCM1ZhWhU73TpjhpF8KKGrDoF7kIDgxL-0-5f14cae5ce598fb5802d87a94afc8a5d)
SPI传输结束后释放片选管脚,语句如下:
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/59_01.jpg?sign=1738936794-C0E8VaWNPbtoa14ZeoRzpjvcBRDKyU7a-0-3c87d7d8340a1b0f7185744d22b9e6c0)
Arduino开发板也可以通过SPI接口读写存储模块,例如Micro SD卡,读写Micro SD卡模块如图4-7所示。
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/59_02.jpg?sign=1738936794-z21yT3xmp1h2F0T8SKVRI7YCBrOPSApC-0-41f7b6a7985f43578394f08e4ff4137a)
图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所示。
![](https://epubservercos.yuewen.com/DAB405/18123624701958606/epubprivate/OEBPS/Images/59_03.jpg?sign=1738936794-ybBTOPn1ooISR2NAG4alchgwBbcAElGH-0-425c2221bf5a4e9b35a04d9744c4702c)
图4-8 SPI总线读写存储模块Micro SD卡连接示意图