SPI通信协议学习总结

SPI通信

1.简介

这里介绍STM32通过SPI实现对外部SPIFlash的读写功能,其中,SPI作为主设备,SPIFlash作为从设备。为了验证SPI Flash收到的数据是否是STM32通过SPI发送给它的数据,我们将SPIFlash读取的数据显示在屏幕上(TFTLCD)。

1.1 SPI简介

SPI就是串行外围设备接口,它是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,这四根线的定义分别是:

 MISO:主设备数据输入,从设备数据输出;

 MOSI:主设备数据输出,从设备数据输入;

 SCLK:时钟信号,由主设备产生;

 CS:从设备片选信号,由主设备控制;

SPI为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI总线数据传输时序图如下图:

SPI通信协议学习总结_第1张图片

数据传输过程如下:SCK的第一个时钟周期在时钟的前沿采样数据(上升沿,第一个时钟沿钟沿),在时钟的后沿输出数据(下降沿,第二个时钟沿)。首先来看主器件,主器件的输出口MOSI输出的数据,在时钟的前沿被从器件采样,那主器件是在何时刻输出数据的呢?数据的输出时刻实际上在SCK信号有效以前,比SCK的上升沿还要早半个时钟周期。数据的输出时刻与SSEL信号没有关系。再来看从器件,主器件的输入口MISO同样是在时钟的前沿采样从器件输出的数据,那从器件又是在何时刻输出数据的呢? 从器件是在SSEL信号有效后,立即输出数据,尽管此时SCK信号还没有起效。

1.2 SPI Flash简介

SPI Flash以W25Q64为例进行介绍,W25Q64将8M的容量分为128个块(Block ),每个块大小为64K字节,每个块又分为16个扇区(Sector),每个扇区4K个字节。W25Q64 的最少擦除单位为一个扇区,也就是每次必须擦除4K个字节。这样我们需要给W25Q64 开辟一个至少4K的缓存区。

SPI Flash的写入数据基本过程是:先获得首地址(WriteAddr)所在的扇区,并计算在扇区内的偏移,然后判断要写入的数据长度是否超过本扇区所剩下的长度,如果不超过,再先看看是否要擦除,如果不要,则直接写入数据即可,如果要则读出整个扇区,在偏移处开始写入指定长度的数据,然后擦除这个扇区,再一次性写入。当所需要写入的数据长度超过一个扇区的长度的时候,我们先按照前面的步骤把扇区剩余部分写完,再在新扇区内执行同样的操作,如此循环,直到写入结束。

2. 硬件设计

我们利用STM32自带的SPI和SPIFlash通信,通信过程中SPI是主设备,SPIFlash是从设备,硬件设计如下图所示:

SPI通信协议学习总结_第2张图片

3. 软件设计

3.1 SPI软件设计

(1)使能SPI时钟,且定义相关引脚的复用功能;

使能SPI时钟,且配置SPI占用的几个GPIO引脚的功能为复用功能;SPI和STM32共用一个时钟,可以对SPI频率进行设置,SPI时钟通过APB2进行分频,分频系数可以是2、4、8等,最低是256分频。

(2)设置SPI工作参数

主要对SPI以下几个工作参数进行设置:

设置SPI的通信方式,可以是全双工、半双工等方式;

设置SPI的主从模式;

设置SPI传输方式:8位传输还是16位传输;

设置SPI的时钟极性;

设置SPI的时钟相位;

设置SPI的分频系数;

设置SPI的CRC校验多项式;

(3)使能SPI外设;

(4)SPI发送接收数据;

(5)查看SPI传输状态;

3.2 SPI Flash软件设计

(1)SPIFlash读出数据;读取数据过程:由于W25Q64 支持以任意地址(但是不能超过W25Q64的地址范围)开始读取数据,在发送24 位地址之后,程序就可以开始循环读数据了,其地址会自动增加的,不过要注意,不能读的数据超过了W25Q64的地址范围。

(2)SPIFlash写入数据;写入数据基本过程:先获得首地址(WriteAddr)所在的扇区,并计算在扇区内的偏移,然后判断要写入的数据长度是否超过本扇区所剩下的长度,如果不超过,再先看看是否要擦除,如果不要,则直接写入数据即可,如果要则读出整个扇区,在偏移处开始写入指定长度的数据,然后擦除这个扇区,再一次性写入。当所需要写入的数据长度超过一个扇区的长度的时候,我们先按照前面的步骤把扇区剩余部分写完,再在新扇区内执行同样的操作,如此循环,直到写入结束。

你可能感兴趣的:(学习总结)