带你了解STM32:SPI通信(软件部分)

目录

0.SPI相交于I2C的优缺点

1.SPI通信

2.硬件电路

3.移位示意图(SPI硬件电路设计的核心)(下面的时序都是这个逻辑进行字节交换)

4.SPI时序基本单元

5.SPI时序(W25Q64)

6.W25Q64简介

7.硬件电路

8.W25Q64框图

9.Flash操作注意事项

10.参考资料(状态寄存器、框架图、指令集......)

11.软件SPI读写W25Q64代码

第一步:按图接线到面包板上

第二步:复制OLED显示屏代码

工程思路:

第三步:建立MySPI模块,完成通信引脚封装、初始化、时序:起始、终止、交换一个字节

模式0

模式1

模式2

模式3

第四步:MySPI头文件声明

第五步:新建立一个头文件,命名为W25Q64_Ins,封装指令码

第六步:建立W25Q64驱动模块,调用底层SPI,拼接各种指令和功能的完整时序,比如:写使能、擦除、页编程、读数据等等,模块函数功能实现参考手册,模块的建成也要看Flash操作注意事项

第七步:W25Q64头文件声明

第八步:主函数调用


0.SPI相交于I2C的优缺点

优点:1.SPI传输更快,SPI协议并没有严格规定最大传输速度,这个最大速度取决于芯片厂商的设计需求,比如:W25Q64存储器芯片,最大可达80MHz;2.设计比较简单粗暴,比I2C简单好学

缺点:1.因为设计比较简单粗暴,所以功能就没有I2C怎么多了;2.SPI的硬件资源开销多,通信线的个数比较多,并且通信过程中,经常会有资源浪费的现象


1.SPI通信

SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线
四根通信线:SCK(Serial Clock)(别名:SCLK、CLK、CK)、MOSI(Master Output Slave Input)(别名:DO)、MISO(Master Input Slave Output)(别名:DI)、SS(Slave Select)(别名:NSS、CS)

SCK:时钟信号,数据位的输出和输入,都是在SCK的上升沿和下降沿进行的,数据位的收发时刻就可以明确的确定;MOSI:主机输出从机输入,如果是主机接到这根线上,那就是MO,主机输出,如果是从机接到这条线上,就是SI,从机输入;MISO:主机从从机接收数据的线路;MOSI和MISO加在一起相当于I2C总线的SDA,但是SDA是半双工,这里是全双工;SS:从机选择线,直接连接到从机上,不用寻址,低电平呼叫从机,高电平释放从机
同步,全双工
支持总线挂载多设备(一主多从)

从左到右:W25Q64(Flash存储器芯片)、OLED、2.4G无线通信模块、Micro SD卡


2.硬件电路

所有SPI设备的SCK、MOSI、MISO分别连在一起

主机另外引出多条SS控制线,分别接到各从机的SS引脚

输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入


3.移位示意图(SPI硬件电路设计的核心)(下面的时序都是这个逻辑进行字节交换)

SPI一般是高位先行,每来一个时钟,移位寄存器会向左进行移位,移位寄存器时钟源主机提供(波特率发生器),主机移位寄存器左移数据,从左边出去通过MOSI引脚,移动到从机移位寄存器右边,从机移位寄存器左边移出去的数据,通过MISO引脚,输入到主机移位寄存器的右边

电路工程流程:波特率发生器时钟的上升沿,所以移位寄存器向左移动一位,移出去的位放在引脚上,波特率发生器时钟的下降沿,引脚上的位,采样输入到移位寄存器的最低位

假设,主机有个数据10101010要发送到从机,同时从机一个数据01010101要发送到主机,驱动时钟先产生一个上升沿,所有的位会往左移动一次(图1) ,移除去的数据会放在通信线上,实际是放在输出数据寄存器上,此时MOSI数据是1,所以MOSI的电平是高电平,MISO数据是0,所以MISO的电平是低电平,这就是第一个时钟上升沿执行的结果(图2) ;之后时钟置一个下降沿,在下降沿时,主机和从机内,都会进行数据采样输入,也就是MOSI的1,会采样输入到从机的最低位,MISO的0,会采样输入到主机的最低位。这就是一个时钟结束后的现象(上升沿和下降沿的组合)(图3);如此字节交换,最终8个时钟过后,主机的数据在从机里,从机的数据在主机里。

如果只发不收,仍然用交换字节的时序,接收的数据(一般给从机写入0x00或0xFF)不看即可;如果只收不发,同理,调用交换字节的时序,随便发一个数据,从机不会看这个随便发的数据(一般发0x00或0xFF)


4.SPI时序基本单元

起始条件:SS从高电平切换到低电平


终止条件:SS从低电平切换到高电平


交换一个字节(模式0)(最常用)

MISO因为有多个从机输出连在一起,如果同时开启输出,会造成冲突,所以解决方法是在SS未被选中的状态,从机的MISO引脚必须关断输出,即配置为高阻状态(就是图中的一根线),SS上升沿之后,从机的MISO必须置回高阻状态

CPOL(时钟极性)=0:空闲状态时,SCK为低电平

CPHA(时钟相位,决定第一个时钟采样移入还是第二个时钟采样移入)=0:SCK第一个边沿移入数据,第二个边沿移出数据,在SCK第一个边沿之前就把数据移出了(或者理解为在第0个边沿移出)。相较于模式1提前半个相位(时钟)将数据移出


交换一个字节(模式1)

MISO因为有多个从机输出连在一起,如果同时开启输出,会造成冲突,所以解决方法是在SS未被选中的状态,从机的MISO引脚必须关断输出,即配置为高阻状态(就是图中的一根线),SS上升沿之后,从机的MISO必须置回高阻状态

CPOL=0:空闲状态时,SCK为低电平

CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据。


交换一个字节(模式2)

将模式0的SCK极性取反,就是模式2

CPOL=1:空闲状态时,SCK为高电平

CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据


交换一个字节(模式3)

将模式1的SCK极性取反,就是模式3

CPOL=1:空闲状态时,SCK为高电平

CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据


5.SPI时序(W25Q64)

采用指令码加读写数据的模型。流程:SPI起始后,第一个交换发送给从机的数据,这个数据一般是指令码;在从机中对应的会定义一个指令集,不同指令,可以有不同的数据个数,有的指令,只需要一个字节的指令码就可以完成,如:W25Q64的写使能、写失能等指令,有的指令,后面就需要再跟要读写的数据,比如:W25Q64的写数据、读数据等
发送指令

向SS指定的设备,发送指令(0x06),0x06表示写使能,主机向从机发送写使能的指令,从机接收到指令后,控制硬件,进行写使能


指定地址写

向SS指定的设备,发送写指令(0x02),随后在指定地址(Address[23:0])(地址是24位的分为3个字节传输)下,写入指定数据(Data)

第一个字节,发送写数据的指令;第二个字节到第四个字节都是地址,0x12(23~16位)、0x34(15~8位)、0x56(7~0位);第五个字节:写入的数据,表示在0x123456地址下,写入0x55这个数据
指定地址读

向SS指定的设备,发送读指令(0x03), 随后在指定地址(Address[23:0])下,读取从机数据(Data)

第一个字节,发送读数据的指令;第二个字节到第四个字节都是地址,0x12(23~16位)、0x34(15~8位)、0x56(7~0位);第五个字节:读取的数据,表示在0x123456地址下的数据通过MISO发给主机


6.W25Q64简介

W25Qxx系列是一种低成本、小型化、使用简单的非易失性存储器,常应用于数据存储、字库存储、固件程序存储等场景

存储介质:Nor Flash(闪存)

时钟频率:80MHz / 160MHz (Dual SPI) / 320MHz (Quad SPI)


存储容量(24位地址):

W25Q40: 4Mbit / 512KByte

W25Q80: 8Mbit / 1MByte

W25Q16: 16Mbit / 2MByte

W25Q32: 32Mbit / 4MByte

W25Q64: 64Mbit / 8MByte

W25Q128: 128Mbit / 16MByte

W25Q256: 256Mbit / 32MByte


7.硬件电路


8.W25Q64框图

存储器的规划示意图

8MB的存储空间,先划分为若干的块(Block),其中每一块再划分为若干的扇区(Sector),对于每个扇区内部又可以分成很多页(Page)
SPI Command & Control Logic:SPI控制逻辑。芯片内部进行地址锁存、数据读写等操作,这个是芯片自行完成的
Status Register:状态寄存器。芯片是否处于忙状态、是否写使能、是否写保护等等都可以在这个寄存器里面体现
Write Conteol Logic:写控制逻辑。和外部的WP引脚相连,通过这个引脚实现硬件写保护
High Vollage Generators:高电压生成器。配合Flash进行编程
指定地址,通过SPI发过来3个字节的地址,所以一页内的字节地址,就取决于最低一个字节,而高位的2个字节,就对应的是页地址,所以发送的3个字节的地址,前两个字节会进入这个页地址锁存计数器里,最后一个字节会进入字节地址锁存计数器里。然后,页地址,通过写保护和行解码,选择要操作哪一页,字节地址,通过列解码和256字节页缓存区(RAM存储器),进行指定字节的读写操作

Page Address Latch/Counter:页地址锁存/计数器

Byte Address Latch/Counter:字节地址锁存/计数器

Column Decode And 256-Byte Page Buffer:256字节页缓冲区。一种RAM存储器,因为Flash的写入太慢,跟不上SPI的频率,所以写入的数据会先放在RAM里面暂存,等时序结束后,芯片在慢慢地把数据写入到Flash里


9.Flash操作注意事项

写入操作时:

写入操作前,必须先进行写使能

每个数据位只能由1改写为0,不能由0改写为1

写入数据前必须先擦除,擦除后,所有数据位变为1

擦除必须按最小擦除(一个扇区)(对于W25Q64是4096个字节)单元进行,如果不擦除,读出的数据=原始数据&写入的数据

连续写入多字节时,最多写入一页(对于W25Q64是256个字节)的数据,超过页尾位置的数据,会回到页首覆盖写入

写入操作结束后,芯片进入忙状态,不响应新的读写操作
读取操作时:

直接调用读取时序,无需使能,无需额外操作,没有页的限制,读取操作结束后不会进入忙状态,但不能在忙状态时读取


10.参考资料(状态寄存器、框架图、指令集......)


11.软件SPI读写W25Q64代码

第一步:按图接线到面包板上

第二步:复制OLED显示屏代码

工程思路:

首先建立一个MySPI模块,这个模块包含通信引脚封装、初始化、时序:起始、终止、交换一个字节

然后基于MySPI,建立一个W25Q64模块,这个模块调用底层SPI,拼接各种指令和功能的完整时序,比如:写使能、擦除、页编程、读数据等等,所以这个模块是W25Q64的硬件驱动层

最后,在主函数里,调用W25Q64的硬件驱动层的函数,完成想要实现的功能

第三步:建立MySPI模块,完成通信引脚封装、初始化、时序:起始、终止、交换一个字节

模式0

另外一种方法,但是最开始的ByteSend就没有了

模式1

模式2

在模式0的基础上,将所有的SCK,0改为1,1改为0

模式3

在模式1的基础上,将所有的SCK,0改为1,1改为0

第四步:MySPI头文件声明

第五步:新建立一个头文件,命名为W25Q64_Ins,封装指令码

第六步:建立W25Q64驱动模块,调用底层SPI,拼接各种指令和功能的完整时序,比如:写使能、擦除、页编程、读数据等等,模块函数功能实现参考手册,模块的建成也要看Flash操作注意事项

第七步:W25Q64头文件声明

第八步:主函数调用

相关推荐
无垠的广袤2 小时前
【工业树莓派 CM0 NANO 单板计算机】本地部署 EMQX
linux·python·嵌入式硬件·物联网·树莓派·emqx·工业物联网
雲烟4 小时前
嵌入式设备EMC安规检测参考
网络·单片机·嵌入式硬件
泽虞4 小时前
《STM32单片机开发》p7
笔记·stm32·单片机·嵌入式硬件
田甲4 小时前
【STM32】 数码管驱动
stm32·单片机·嵌入式硬件
up向上up5 小时前
基于51单片机垃圾箱自动分类加料机快递物流分拣器系统设计
单片机·嵌入式硬件·51单片机
纳祥科技14 小时前
Switch快充方案,内置GaN,集成了多个独立芯片
单片机
单片机日志15 小时前
【单片机毕业设计】【mcugc-mcu826】基于单片机的智能风扇系统设计
stm32·单片机·嵌入式硬件·毕业设计·智能家居·课程设计·电子信息
松涛和鸣16 小时前
从零开始理解 C 语言函数指针与回调机制
linux·c语言·开发语言·嵌入式硬件·排序算法
小曹要微笑1 天前
STM32F7 时钟树简讲(快速入门)
c语言·stm32·单片机·嵌入式硬件·算法
XINVRY-FPGA1 天前
XCVP1802-2MSILSVC4072 AMD Xilinx Versal Premium Adaptive SoC FPGA
人工智能·嵌入式硬件·fpga开发·数据挖掘·云计算·硬件工程·fpga