Uart串口通讯只能满足点对点的通讯,无法满足一对多的通讯要求,另外,在传输速度上也比较受限,不能满足高速传输的要求,于是人们又设计出了新的通讯方式,即SPI(Serial Peripheral Interface,串行外围设备接口)。
SPI通讯需要使用4条数据线:主机输出/从机输入(MOSI)、主机输入/主机输出(MISO)、串行时钟SCK和外设芯片选择(CS)。对于SPI通讯来说,提供时钟信号的一方为主机,另外一方为从机,主机还需要负责提供芯片选择信号以确认主机和谁通讯,而从机需要有SPI接口专用的芯片选择管脚,称为从机选择(SS)管脚,其目的是使MCU处于SPI从机模式。
SPI通讯可以实现一对多的连接和数据传输,但在一确定的时刻,它的通讯方式还是1对1的,也就是一个主机对应一个从机,而具体的从机是谁,是有片选信号决定的,主机负责提供片选信号,从机负责提供片选引脚。其中SPI的四个引脚意义具体描述如下:
(1) MOSI – 主器件数据输出,从器件数据输入
(2) MISO – 主器件数据输入,从器件数据输出
(3) SCK – 时钟信号,由主器件产生
(4) /SS – 从器件使能信号,由主器件控制
对于SPI来说,我们还要理解以下它的不同工作模式,下图是一个典型的SPI时序:
这里列出了两种时钟信号,一个在周期内由低向高跳变,另外一个则是由高向低跳变,这就是工作模式的决定因素之一,另外一个因素则是数据信号是在上升沿采集还是下降沿采集,则是,SPI就有四种工作模式了,具体SPI的工作原理可以参考产品的Datasheet。
SPI支持以下类名及方法:
类名 | | | | SPI(PinName mosi, PinName miso, PinName sclk, PinName _unused=NC); | 构造函数,用mosi,miso,sclk三个管脚用作SPI主机通讯管脚,同样需要注意的是,只有特定的几个管脚能用作SPI通讯管脚,具体定义在spi_api.c中 | void format(int bits, int mode = 0); | 设置SPI工作的模式,bits表示SPI帧的bit数,取值为4-16,mode取值为0-3 | void frequency(int hz = 1000000); | | virtual int write(int value); | | | SPISlave(PinName mosi, PinName miso, PinName sclk, PinName ssel); | 构造函数,用mosi,miso,sclk三个管脚用作SPI从机通讯管脚,ssel用作片选管脚 | void format(int bits, int mode = 0); | 设置SPI工作的模式,bits表示SPI帧的bit数,取值为4-16,mode取值为0-3 | void frequency(int hz = 1000000); | | | 判断SPI从机是否接收到数据,0表示没有,1表示有 | | | | |
下边的程序是从SAMR21的第一扩展口读RF233的版本号,注意一下管脚一定要写对就行。
类名
方法
用途
SPI
SPI(PinName mosi, PinName miso, PinName sclk, PinName _unused=NC);
构造函数,用mosi,miso,sclk三个管脚用作SPI主机通讯管脚,同样需要注意的是,只有特定的几个管脚能用作SPI通讯管脚,具体定义在spi_api.c中
void format(int bits, int mode = 0);
设置SPI工作的模式,bits表示SPI帧的bit数,取值为4-16,mode取值为0-3
void frequency(int hz = 1000000);
设置SPI时钟的频率
virtual int write(int value);
主机通过SPI发送数据,返回值为从机德返回值
SPISlave
SPISlave(PinName mosi, PinName miso, PinName sclk, PinName ssel);
构造函数,用mosi,miso,sclk三个管脚用作SPI从机通讯管脚,ssel用作片选管脚
void format(int bits, int mode = 0);
设置SPI工作的模式,bits表示SPI帧的bit数,取值为4-16,mode取值为0-3
void frequency(int hz = 1000000);
设置SPI时钟的频率
int receive(void);
判断SPI从机是否接收到数据,0表示没有,1表示有
int read(void);
读取SPI从机接收缓冲区中的数据
void reply(int value);
SPI从机向SPI主机发送数据value
以下是运行的截图:
|