本篇博客重点在于介绍SPI时序以及W25Q128操作的相关知识点以及注意事项。
1. SPI协议
SPI(Serial Peripheral interface),串行外围外设接口,属于一种高速全双工的通信总线。
1.1 SPI物理层
图1-1 SPI通讯接线
信号线名称 | 作用 |
---|---|
![]() | SPI和IIC不同,从设备没有自身地址,需要通过片选信号线选择从设备,同时片选信号线还有发送起始和终止通讯信号的作用 |
SCK(时钟信号线) | SPI属于同步通讯,需要主机提供时钟信号,统一数据交换时序 |
MOSI | Master Output, Slave Input,也就是主机输出,从机输入 |
MISO | Master Input, Slave Output |
1.2 SPI协议层
图1-2 SPI通讯时序
这个时序还是比较好分析的,1编号属于起始信号,也就是选择片选;和IIC相同,我们需要定义数据改变和数据保持的时刻,如图上的2、4属于准备数据,3、5属于数据保持以及数据交换的时刻,但是SPI提供四种数据交换的模式,主要是为了兼容不同的器件,只要对应设置就行。CPOL/CPHA 及通讯模式。(其实所有的通讯协议都一样,没有对错,只要统一就行)
CPOL和CPHA设置是独立的,其中CPOL决定了“时钟极性”,也就是空闲状态SCK的电平,所谓的空闲状态就是没有数据交互,没有从设备被选中,NSS属于高电平的时刻。图1-2显然时钟极性是低,也就是说CPOL为0;
图1-3 CPOL对应时钟极性
CPHA决定采样边缘,为0就是再奇数边缘采样(从1算起),为1从偶数边缘采样。
图1-4 CPHA对应采样边缘
这个和我们平常去定义下降沿上升沿采样习惯不一样,单最终来说都是设置采样时刻
图1-5 SPI四种模式
2. SPI操作W25Q128如何配置以及为什么
学习了SPI相关知识,我们就要根据特定的器件去配置,实现数据交互,如下结合STM32F4库函数开发去配置对应的SPI
SPI_Init初始化结构体,我就省略了GPIO以及复用功能的初始化了。
首先SPI_Direction我们需要对FLASH进行读写,选择全双工的模式,同时选择主机模式和八位数据位
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
下面比较有选择困难的就是时钟极性以及采样边沿的选择了,这个我们就必须查看W25Q128数据手册了
根据之前的表格,我们可以设置CPOL=0,CPHA=0或者CPOL=1,CPHA=1即可。(博主设置为(0, 0)读取不了,不知道为什么)
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
NSS我们为了方便控制逻辑,选择软件控制,就好像控制LED一样即可,控制逻辑需要软件实现
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI时钟速度,时钟决定了通讯速度,STM32 SPI速度决定于外设挂载的时钟线速度(APB1、APB2),其中APB1 42M, APB2 84M;同时也和分频因子有关,选择的是SPI1挂载在APB2,同时这个速度选择遵从短板效应,由最低速度的设备决定。我们看看W25Q128支持速度如何:
支持104MHZ,大大大于我们STM32 SPI外设最高速度
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //定义波特率预分频的值:波特率预分频值为2
数据传输顺序,这个也需要查看数据手册才能确定,当然,你也可以随便,只要系统统一,高位优先写进去就得高位优先读出来(博主做过实验,对于自身写的数据是没问题,但是对于常数,设备ID就会出现问题,还得自己转换,还是别这样搞,乖乖看数据手册)
对于奇偶校验的话,我们只需要设置大于1的值即可。
配置好SPI我们应该就可以传输一些数据了,首先应该去看看读出的ID是否正确,如果ID都不正确就说明配置出问题了,后面的写入数据读出数据就肯定不行了。SPI操作FLASH只要遵从数据手册的逻辑顺序就行了,和之前的AT24C02分析过程差不多,就是写入操作命令,写入地址,写入数据,都有一套标准的操作流程,不过需要注意,写是需要擦除以及自行换页的,读是可以直接读取,自动换页。
3. FLASH写入前为什么需要擦除
Flash 的编程原理都是只能将 1 写为 0,而不能将 0 写为 1。所以在 Flash 编程之前,必须将对应的块擦除,而擦除的过程就是把所有位都写为 1 的过程,块内的所有字节变为 0xFF
4.代码下载
https://github.com/oraSC/STM32-course/tree/master/SPI/SPI%E6%93%8D%E4%BD%9CW25Q128