一、SPI总线简介
1.1 SPI总线
串口外设接口(Serial Peripheral Interface,SPI)总线是一种同步串行外设接口,允许MCU与各种外围设备进行全双工、同步串行通信
SPI总线有四根通信线:
①SCK(Serial Clock,串行时钟):作为主设备的输出、从设备的输入
②MOSI(Master Output Slave Input):主设备发送数据,从模式接收数据
③MISO(Master Input Slave Output):主设备接收数据,从模式发送数据
④SS(Slave Select,片选引脚,低电平有效):选择从机,让主设备可以单独地与特定从设备通信,避免数据线上地冲突
SPI总线采用主从模式(Master - Slave)架构,支持总线挂载多设备(一主多从),被广泛应用于MCU和外设模块(如E2PROM、ADC、显示驱动器等)
在大容量和互联型产品上,SPI可以配置为支持SPI协议或者支持I²S音频协议
1.2 SPI硬件电路
所有SPI设备的SCK、MOSI、MISO分别连在一起
主机另外引出多条SS控制线,分别接到各从机的SS引脚
输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入
为了避免一个主机输入,其他从机均为推挽输出,导致的总线冲突:SPI规定,当从机SS引脚为高电平时,其输出引脚必须切换为高阻态
1.3 SPI通信原理
SPI为环形总线结构。通信总是由主机发起,在同步SCK驱动下,主机移位寄存器的最高位数据通过MOSI移位到从机移位寄存器的最低位,而从机移位寄存器的最高位数据通过MISO移位到主机移位寄存器的最低位。循环上述过程8次,则通信一个字节数据
1.4 SPI通信时序
1.4.1 起始与终止
1.4.2 交换模式
根据CPOL(Clock Polarity,时钟极性 )和CPHA(Clock Phase,时钟相位)两位组合,共有四种组合模式
(1)模式0(常用)
CPOL = 0:空闲 时SCK为低电平
CPHA = 0:第一个边沿(上升沿)移入(采样)数据,第二个边沿(下降沿)移出数据
对于传输的首个数据的最高位 ,在SS的下降沿就将其移出,之后在SCL的(上升沿)移入(采样)
(2)模式1
CPOL = 0:空闲 时SCK为低电平
CPHA = 1:上升沿移出数据,下降沿移入(采样)数据
(3)模式2
CPOL = 1:空闲 时SCK为高电平
CPHA = 0:第一个边沿(上升沿)移入(采样)数据,第二个边沿(下降沿)移出数据
对于传输的首个数据的最高位 ,在SS的下降沿就将其移出,之后在SCL的(上升沿)移入(采样)
(4)模式3
CPOL = 1:空闲 时SCK为高电平
CPHA = 1:上升沿移出数据,下降沿移入(采样)数据
1.5 SPI数据格式
SPI:指令码(芯片厂商规定)+寄存器地址+数据
(1)发送指令
向SS指定的设备,发送指令(0x06)
(2)指定地址写
向SS指定的设备,发送写指令(0x02), 随后在指定地址(Address[23:0])下,写入指定数据(Data)
(3)指定地址读
向SS指定的设备,发送读指令(0x03),随后在指定地址(Address[23:0])下,读取从机数据(Data)
二、W25Q64存储器芯片
2.1 W2Q564简介
时钟频率:160MHz(Dual SPI,双重SPI等效的时钟频率),该存储器的芯片将SPI进行了改进:MOSI和MISO可以同时发送或者同时接收 ,数据传输速率相当于普通SPI通信模式的2倍
320MHz(Quad SPI,四重SPI等效的时钟频率),MOSI、MISO、WP(写保护)、HOLD,四个引脚同时收发数据 ,数据传输速率相当于普通SPI通信模式的4倍
2.2 硬件电路
2.3 W2Q564结构框图
存储空间的划分:先划分为若干的块(Block),其中每一块再划分为若干的扇区(Sector),对于一个扇区,内部还可以分成很多页(Page)
W2Q564一共有8MByte的存储空间(00 0000H ~ 7F FFFFH),其中,每块定义占用内存64KB,可分为128块;每扇区定义占用内存4KB,可分为16个扇区;每页定义占用内存256B,可分为16页
块Block(0~127,64KB):地址变化规律 :xx 0000H ~ xx FFFFH(xx:最高两位表示位于某一块,变化范围:00~7F)
扇区Sector(0~15,4KB):地址变化规律:xx k000H ~ xx kFFFH(k:第四位表示位于某一扇区,变化范围:0~F)
页Page(0~16,256B):地址变化规律:xx xj00H ~ xx xjFFH(k:第三位表示位于某一页,变化范围:0~F)
2.4 状态寄存器
写使能:WEL = 1,表示可以进行写操作
写失能:WEL = 0
(1)上电后,芯片默认写失能
(1)执行以下指令:写失能、页编程、扇区擦除
在任何写操作前,都需要来一遍写使能
一个写使能,只能保证后续的一条指令可以执行
2.5 指令集
三、SPI外设
STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担
(1)8位或16位传输帧格式选择
(2)可编程的时钟极性、时钟相位和数据传输顺序(高位先行 or 低位先行)
(3)时钟频率: fPCLK / (2, 4, 8, 16, 32, 64, 128, 256)
(4)支持全双工同步、或者半双工/单工同步通信
(5)支持多主机模式
(6)支持DMA功能的1字节发送和接收缓冲器,产生发送和接收请求
(7)支持可靠通信的硬件CRC
(8)兼容I²S协议(仅在大容量和互联型产品)
STM32F103C8T6 硬件SPI资源:SPI1、SPI2
SPI主模式:
数据发送:当写入数据至发送缓冲器时,发送开始。在发送第一个数据位时,数据字被并行地传入移位寄存器,而后串行的移出到MOSI引脚上,MSB(高位)在先还是LSB(低位)在先,取决于SPI_CR1中LSBFIRST位的设置。当时据从发送缓冲器传输到移位寄存器时,TXE置1,如果设置了SPI_CR1中的TXEIE,将产生中断
数据接收:当数据传输完成时,传送移位寄存器中的数据到接收缓冲器,并且RXNE被置1。如果设置了SPI_CR1中的RXNEIE,将产生中断。当读SPI_DR时,将返回接收缓冲器中的数据,同时RXNE被置0
主模式全双工连续传输:
在模式3下,TXE为1时,数据写入发送缓冲器,此时,发送缓冲器的数据并行传送到移位寄存器
TXE为0,数据开始传输,并将下一位数据写入发送缓冲器,等待第一个数据发送完成
当第一个数据发送完成,交换的数据被接收,放到了接收缓冲器中,并将RXNE置1。
当第二个数据发送完成,交换的数据被接收,放到了接收缓冲器中,并将RXNE置1。
简易流程:
(1)等待TXE为1,写入数据,之后TXE为0
(2)数据移入移位寄存器,TXE为1,下一个数据移入发送缓冲器等待,此时,TXE为1
(3)第一个数据发送完成后,交换的数据从移位寄存器,并行传送到接收缓冲器,将RXNE置1
(4)与此同时,第二个数据迅速转移到移位寄存器,此时TXE为1
(5)接着,将下一位数据写入发送缓冲器中,此时,TXE为1
主模式全双工非连续传输:
(1)等待TXE为1,写入发送数据
(2)等待RXNE为1,接收数据
连续传输优点:传输效率高,性能强大
缺点:软件设计复杂
非连续传输优点:软件设计简单,易于理解
缺点:传输效率相对较低,在字节与字节之间会出现间隙,且随着时钟频率的增快而变长
四、SPI相关库函数
(1)初始化:SPI_Init()
(2)传送数据:SPI_SendData ()
(3)接收数据:SPI_ReceiveData()
五、SPI外设基本配置
(1)开启SPI、GPIO的时钟
(2)配置GPIO的模式
(3)配置SPI外设,完成初始化
SPI_InitTypeDef SPI_InitStruct;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; //波特率分频系数
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; //时钟相位
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; //时钟极性
SPI_InitStruct.SPI_CRCPolynomial = 7; //CRC:未用,赋一个默认值
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; //数据帧大小:8位
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线双向全双工
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; //高位先行
SPI_InitStruct.SPI_Mode = SPI_Mode_Master; //主机
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_Init(SPI1,&SPI_InitStruct);
(4)使能SPI外设