STM32学习笔记15-SPI通信软件控制
SPI通信-串行外设接口
- SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线,主控和外设之间通信与I2C一样
I2C:拥有以最少的通信线实现硬件功能和最全的软件实现功能;但是默认是开漏输出,弱上拉的电路结构,导致由低电平到高电平的时间功耗很大,所以速度很慢,最多400KHz,标准是100KHz,现通过优化电路,速度可达到3.4MHz,可远远不够实际的应用。
SPI:传输速度快,速度限制取决于本身厂家的芯片制造;结构简单直接,功能少;硬件开销大,通信线多。
- 四根通信线:SCK/SCLK/CK(串行时钟线:Serial Clock)、MOSI/DO(主机输出从机输入:Master Output Slave Input)、MISO/DI(主机输入从机输出:Master Input Slave Output)、SS/NSS/CS(从机选择:Slave Select)
- 同步(SCK),全双工(两条线,独占输入输出,互不影响,MOSI+MISO=SDA)
- 支持总线挂载多设备(只支持一主多从),会专门开出一条与从机的通信线SS(一条从机一根线),不像I2C要写入从机的相关信息
- 没有应答的机制
硬件电路
- 所有SPI设备的SCK、MOSI、MISO分别连在一起
- 主机另外引出多条SS控制线,分别接到各从机的SS引脚,低电平有效,只能选择一个从机。在从机中,MISO接口,默认从机为高阻态,通过SS低电平后才为推挽输出。
- 输出引脚配置为推挽输出,能够快速的识别出高低电平的变化,使传输频率变快;输入引脚配置为浮空或上拉输入
移位示意图(硬件电路设计的核心)
工作流程:
规定:发生器时钟的上升沿,所有移位寄存器向左移动一位,移出去的位放到引脚上;波特率发生器时钟的下降沿,引脚上的位采样输入到移位寄存器的最低位。
假设主机有个数据10101010要发送到从机,同时从机也有个数据01010101要发送到主机。此时驱动时钟(波特率发生器时钟)为上升沿,这时所有位向左移动一次,被移动到引脚的数据,会放到MOSI通信线和MISO通信线上(实际上是放在输出数据寄存器中);之后时钟继续执行,下降沿,引脚上的存储数据会被移位寄存器采样输入到其中的最低位。循环即可。
SPI的数据收发,都是基于字节交换,以发送同时接收的模式执行;
SPI时序基本单元
开始&结束
- 起始条件:SS从高电平切换到低电平
- 终止条件:SS从低电平切换到高电平
数据传输
CPOL——时钟极性和CPHA——时钟相位,二者不同数据组合就有4种模式,但是功能都差不多,主要学习一种即可。
- 交换一个字节(模式0)——与模式1相比CPHA相反,导致其中的数据需要先在SCK首次变化前移出一位,常用时序
- CPOL=0:空闲状态时,SCK为低电平
- CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据
- 交换一个字节(模式1)——最标准的逻辑
- CPOL=0:空闲状态时,SCK为低电平
- CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据
- 交换一个字节(模式2)
- CPOL=1:空闲状态时,SCK为高电平——与模式0,SCK的极性取反
- CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据
- 交换一个字节(模式3)
- CPOL=1:空闲状态时,SCK为高电平——与模式1,SCK的极性取反
- CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据
SPI时序——以W25Q64
SPI时序:通常采用指令码(第一个字节:表功能)+读写数据的模型
模式0
- 发送指令
- 向SS指定的设备,发送指令(0x06:写使能)
- 指定地址写
- 向SS指定的设备,发送写指令(0x02),
随后在指定地址(Address[23:0])下,写入指定数据(Data)
- 指定地址读
- 向SS指定的设备,发送读指令(0x03),
随后在指定地址(Address[23:0])下,读取从机数据(Data)
W25Q64简介
- W25Qxx系列是一种低成本、小型化、使用简单的非易失性存储器,常应用于数据存储、字库存储、固件程序存储等场景
- 存储介质:Nor Flash(闪存)
- 时钟频率:80MHz / 160MHz (Dual SPI:使两个线同时可以输入输出,2位) / 320MHz (Quad SPI:用4个线)
- 存储容量(24位地址-3个字节——最大寻址空间16MB):
W25Q40: 4Mbit / 512KByte
W25Q80: 8Mbit / 1MByte
W25Q16: 16Mbit / 2MByte
W25Q32: 32Mbit / 4MByte
W25Q64: 64Mbit / 8MByte
W25Q128: 128Mbit / 16MByte
W25Q256: 256Mbit / 32MByte
硬件电路
WP引脚:低电平有效,保护数据,不让写
HOLD:低电平有效,当时序种产生中断,此时去执行其他的操作,会导致时序终止,所以此时又不想终止总线,又想操作其他器件,置HOLD引脚,记录当前的状态。
(IOx):可以被作为数据收发引脚
补: 和
都是代表低电平有效
W25Q64框图
存储区的划分:
电路逻辑:
Flash操作注意事项
为了保证掉电不丢失的特性
写入操作时:
- 写入操作前,必须先进行写使能;保护的机制,防误写
- 每个数据位只能由1改写为0,不能由0改写为1;没有覆盖的作用
- 写入数据前必须先擦除,擦除后,所有数据位变为1,弥补第二条中的数据不对的情况
- 擦除必须按最小擦除单元(最小单元:扇区)进行
- 连续写入多字节时,最多写入一页的数据,超过页尾位置的数据,会回到页首覆盖写入,一个写入时序,最多只能写一页的数据256字节,因为RAM缓存区只有256字节
- 写入操作结束后或者擦除结束后,芯片进入忙状态,不响应新的读写操作
读取操作时:
- 直接调用读取时序,无需使能,无需额外操作,没有页的限制,读取操作结束后不会进入忙状态,但不能在忙状态时读取
状态寄存器:
状态寄存器1:
BUSY位:当正在写数据或擦除的操作时,寄存器BUSY位置1,此时机器会停止进一步的指令,除了读状态寄存器和擦除挂起指令。
WEL(写使能所存位)位:在执行写使能后,WEL置1,代表芯片可以进入写操作;当设备写使能时,置0:失能状态:1.上电后,芯片默认写失能;2.置WEL的值为0使;3.页编程、扇区擦除等写入操作后,会自动WEL=0。
状态寄存器2
指令集:
Write Enable :写使能指令,发送06h,不能再加其他字节
Write Disable:写失能指令,发送04h,同理
Read Status Register-1:读状态寄存器1,发送05h指令,后续交换一个字节
Page Program:页编程,发送02h,后续交换三个字节(A23–A16 ,A15–A8, A7–A0),之后写入数据(D7–D0)
Sector Erase (4KB):按4KB的扇区擦除,发送20h指令,再交换发送3个字节的地址
JEDEC ID:读取ID号,发送9Fh指令,后续交换读取3个字节(厂商ID,后两个设备ID)
Read Data:读取数据,发送03h指令,后续交换发送3个字节地址,之后交换数据
SSTM32