打印
[APM32F1]

APM32F1xx GPIO模拟SPI读写外部Flash

[复制链接]
3473|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 lzh12a3nf 于 2023-9-5 11:01 编辑

#申请原创#@21小跑堂
1. APM32F1xx SPI 简介
  SPI,全称是 SerialPeripheral Interface,即串行外设接口。SPI接口通常运用于EEPROM,Flash,OLED等设备之间。APM32F1xx SPI接口可以配置为支持SPI协议和I2S音频协议,默认工作为SPI模式。串行外设接口(SPI)提供了基于SPI协议的数据收发功能,允许芯片与外部设备以半双工、全双工、同步和串行方式通信,可以工作于主机或从机模式。
1.1 SPI接口介绍
    SPI接口通常由MOSI(MasterOutput Slave Input)、MISO(Master InputSlave Output)、SCLK(Serial Clock)、CS(Chip Select)四条线组成,具体情况如下图:


1.2  SPI 传输模式
  SPI有四种传输模式,其中主要区别在于SPI_CTRL1寄存器的CPOL(时钟极性)和CPHA(时钟相位)。CPOL是指SPI处于空闲状态时,SCK信号线的电平信号。CPHA是指数据的采样时刻。根据二者的不同状态,可以将SPI分成四种模式,如下图:

  根据上面的图可知,当CPHA=0的时候,即表示会在时钟的奇数边沿开始对数据进行采样(第一个时钟边沿开始)。其中,当CPOL=0时,即表示SCK时钟空闲电平为低电平,由低电平变为高电平时,会在奇数边沿(上升沿)进行采样。反之,当CPOL=1时,即SCK时钟空闲时为高电平,由高电平变为低电平,会在偶数边沿(下降沿)进行采样。如下图:
   当CPHA=1的时候,即表示会在时钟的奇数边沿开始对数据进行采样(第一个时钟边沿开始)。其中,当CPOL=0时,即表示SCK时钟空闲电平为低电平,由低电平变为高电平在变为低电平时,会在奇数边沿(上升沿)进行采样。反之,当CPOL=1时,即SCK时钟空闲时为高电平,由高电平变为低电平在变为高电平,会在偶数边沿(下降沿)进行采样。如下图:
1.3  数据交换
   在SCK时钟周期下,MOSI和MISO同时处于工作状态。如下图:
   如上,SPI通信中,主机和从机都有属于自己的移位寄存器,其用于数据的传输。主机移位寄存器数据经过MOSI将数据写入从机的移位寄存器,同时,从机移位寄存器的数据页通过MISO传给主机,实现数据的交换。

2. SPI 实现方式
2.1  硬件SPI
   APM32F1xx系列开发板本身自带硬件电路设计而成的硬件SPI。在通信过程中,其依赖于内置的SPI外设,由硬件直接管理数据的传输过程,无需额外编程来控制SPI通信过程中的各个步骤。

2.1.1  硬件SPI使用的优缺点
   优点:
     1、 可以提供更高的通信速度和一致性
     2、 可以实现更高的通信模式。如DMA传输、中断处理和主机模式。
     3、 代码复杂度低,易于操作。

   缺点:
     1、 硬件SPI的配置和功能是固定的,不易修改。
     2、 硬件SPI依赖于特定的硬件控制器,不同平台开发存在兼容性问题。

2.2 GPIO模拟SPI
   在开发过程中,为了规避因硬件SPI不足而导致开发受阻的情况,可以通过GPIO口和软件控制来实现模拟SPI的通信过程。

2.2.1  GPIO模拟SPI使用的优缺点
   优点:
     1、 GPIO引脚配置灵活,可以任意选用开发板上的GPIO引脚来进行模拟操作。
     2、 成本低,软件模拟SPI不需要额外的硬件设计,只需要有GPIO引脚即可。

   缺点:
     1、 通信速度低,受困于mcu的处理能力。
     2、 代码复杂度高,需要更多的资源。



3.  Flash 介绍
   Flash,全称是 Flash Memory Controller,即闪存存储器控制器。FLASH通常用于存储程序代码、数据等信息。Flash包括内部Flash和外部Flash。在本文中采用到的W25Q64模块,便是一个SPI接口的外部Flash模块。在运行过程中,Flash存放的代码不会进行修改,且Flash按照扇区来进行操作。
Flash在写入之前数据前,通常需要进行擦除操作。因为Flash要写入数据时,其无法直接在已经被编程的扇区上进行修改,而是需要将整个扇区擦除成初始状态,然后在进行写入操作。

3.1  W25Q64 介绍
   W25Q64是一款基于外设接口(SPI)的闪存芯片,它具有8Mbyte的存储空间,是一款大容量的SPI Flash产品。W25Q64将8M的字节容量分为128个块,每个块大小为64K,每个块又分为16个扇区,每个扇区有4K大小。W25Q64的最小擦除单位是扇区,这需要给其开辟一个至少大小为4K的缓冲区。

3.1.1 W25Q64常见命令指令
   通过SPI向W25Q64发送指令,即可操作W25Q64。本文中操作所用到的一些指令表,如下图所示:
   以页编程为例。在操作之前,需要拉低CS片选,在8个CLK时钟周期里,DI发出指令0x02,随后,在剩下的24个CLK时钟周期里,发送24Bit的地址,最后256*8个CLK,发送256字节数据。其时序图如下:
3.1.2  W25Q64使用的优缺点
   优点:
     1、 存储空间大
     2、 支持高速的串行读写操作,具有较快的数据传输速率
     3、 功耗低
     4、 采用SPI接口进行通信,容易实现连接和控制。

   缺点:
     1、 价格高
     2、 有限的使用寿命
     3、 擦除操作慢

4  . APM32F1xx GPIO模拟SPI读写外部Flash例程讲解
   本例程功能介绍:下载程序后,对灯、串口、GPIO模拟SPI的管脚进行初始化和使能操作。之后,对FlashIDDeviceID进行读取操作,读取结束之后会根据判断条件进入不同的状态。如果FlashID读取的数值跟定义好的ID一致,将会进行Flash的读写操作。如果不一致,LED3将会常亮。在Flash的读写操作中,进入写操作之前,先进行一次擦除操作,之后会分别进行写和读数据。操作结束之后,将读取和写入的数据进行对比并放到一个变量1中。之后,进行一次擦除操作,并在进行一次读取操作,与OXFF进行一次对比,并将对比放在变量2中,用于判断是否擦除成功。最后,将变量所得进行一一对比,并且串口和灯会分别做出不同的输出。下面将会对本例程的硬件设计、软件设计框架以及软件设计中的重要函数进行讲解。
4.1   硬件设计
   本次实验所需要的硬件设计:
     1.外部Flash模块
     2.USB转TTL线

   外部 Flash模块使用的是 W25Q64型号,W25Q64模块和 APM32F1xx  连接图如下:
   USB转TTL线所使用到的GPIO管脚为PA9,PA10,利用USB转TTL线进行数据的接收和发送。其原理图如下:

4.2  软件设计
   通过 APM32F1xx 实现GPIO模拟SPI读写外部Flash,需要根据模块的型号配置好外部Flash的ID信息,并且完成GPIO的管脚配置设计以及SPI通信时序,完成之后即可进行读写操作,并对读写操作完成结果输出。代码实现流程图如下:

4.2.1  GPIO引脚配置
   对模拟SPI所使用到的GPIO管脚,将SCK、CS、MOSI管脚配置为推挽输出模式,MISO配置为下拉输入模式。参考代码如下:




4.2.2  模拟SPI时序读写操作
   本文前面的章节中提出,SPI的传输可以看作一个虚拟的环形拓扑结构,表示输入和输出是在同一时间下进行。参考代码如下:

   根据代码得知:
     1.在每次读和写一个Byte时,都会循环8次,每次接收和发送一个Bit。在循环中,每次将byte的最高位存放到temp变量中;
     2.byte左移一位,将次高位变为最高位,此操作用于下次取最高位。
     3.将rx_data右移一位,挪动其最低位,8次循环后,rx_data将高位在前。
     4.拉低时钟线,即将空闲电平设置为低电平。
     5.根据temp值设置MOSI的引脚电平。
     6.拉高时钟线,此时从设备读取MOSI的数据,并写数据到MISO。
     7.读取完MISO上的数据,会将其保存到rx_data的最低位。
     8.SPI读写结束后,拉低时钟线,进入空闲状态。

4.2.3 W25Q64设备信息读取操作
   W25Q64主要有三个ID:制造商编号ID(Manufacturer)、设备ID(Device ID)、唯一表示ID(Unique ID)。其中,制造商编号ID是由Winbond生产的,它的值MF[7:0]为0xEF。设备ID包含两部分,ID[15:0]是芯片类型,为0x4017。ID[7:0]是存储容量。最后,唯一标识ID表示芯片的唯一性,常用于加密。如下图所示:



   在代码实现过程中,使用0xAB指令获取设备ID[7:0],使用0x9F指令获取JEDEC ID(MF[7:0] +ID[15:0])。在实现过程中,均要先把/CS引脚拉低,然后分别把”ABh”、”9Fh”通过DI发送到芯片。在发送完”ABh”后,会经过一段tRES1时间间隔,芯片便恢复正常工作。在这当中,编程、擦除和写状态寄存器指令执行周期内,执行该指令无效。在发送完”9Fh”后,3个ID信息会分别从DO管脚在SCK的下降沿发送出去。参考代码如下图所示:


4.2.4  扇区擦除操作
   根据芯片手册可知,发送0xD8指令,在发送24位的扇区地址,对整个块里面的扇区内容进行全擦除,在擦除完之后,所有字节均变为”FFh”,参考代码如下图所示:

4.2.5  页写入数据操作    
   W25Q64只能按页写数据,每页数据为256字节,因此一次最多写256字节。进行写入数据时,需要先发送0x02指令,在发送24位的扇区地址,即可对该扇区进行写入操作。参考代码如下图所示:


4.2.6  读取数据操作
   进行读取数据时,需要先发送0x03指令,在发送24位的扇区地址,即可对该扇区进行读取操作。参考代码如下图所示:

4.2.7 等待Flash写完成操作
   W25Q64有三个状态寄存器,bit[0]代表的是擦除/写入状态标志位。当写入或者读取操作结束时,需要对状态寄存器进行判断,发送”05h”数据获取状态寄存器的数据,当状态寄存器bit[0]的值为1时,还在进行擦除或者写入操作,当该位为0时,表示这时没有任何操作在进行,可以对W25Q64进行擦除或者写入操作。参考代码如下图所示

5. APM32F1xx GPIO模拟SPI读写外部Flash Demo例程附件
SoftWareSPI_Flash_Demo.rar (168.23 KB)

欢迎大家下载一起学习,如有问题,也请在评论指出,谢谢!




图片15.png (69.4 KB )

图片15.png

使用特权

评论回复
沙发
lzh12a3nf|  楼主 | 2023-9-5 11:02 | 只看该作者
修改了部分文字表述

使用特权

评论回复
板凳
tpgf| | 2023-9-5 17:06 | 只看该作者
如果不去关注通讯方式的话 flash能接收的最大操作速度是多少啊

使用特权

评论回复
地板
coshi| | 2023-9-5 17:22 | 只看该作者
四线制的spi可以有一主多从吗

使用特权

评论回复
5
drer| | 2023-9-5 19:11 | 只看该作者
使用io模拟spi和正经的spi模块相比 速度大概能相差多少呢

使用特权

评论回复
6
qcliu| | 2023-9-5 19:44 | 只看该作者
现在主流外部flash芯片的接口是不是都是串口呢

使用特权

评论回复
7
kxsi| | 2023-9-6 08:50 | 只看该作者
coshi 发表于 2023-9-5 17:22
四线制的spi可以有一主多从吗

应该是不能  只能决定哪个是主设备哪个是从设备 但是应该是一主一从的

使用特权

评论回复
8
wiba| | 2023-9-6 10:16 | 只看该作者
因为是使用io模拟的 所以是不是对时钟频率的要求就比较高呢

使用特权

评论回复
9
chenjun89| | 2023-9-6 21:18 | 只看该作者
这个SPI速率没有达到极限

使用特权

评论回复
10
lzh12a3nf|  楼主 | 2023-9-7 14:59 | 只看该作者
tpgf 发表于 2023-9-5 17:06
如果不去关注通讯方式的话 flash能接收的最大操作速度是多少啊

以APM32F103为例,扇区页大小为2K,页擦除(1K)时间最小值为1.34ms,在不考虑其他操作的情况下,理论最大速度为1024除以1.34 = 764.18字节/毫秒

使用特权

评论回复
11
lzh12a3nf|  楼主 | 2023-9-7 15:59 | 只看该作者
drer 发表于 2023-9-5 19:11
使用io模拟spi和正经的spi模块相比 速度大概能相差多少呢

硬件SPI大约20us,软件SPI大约90us

使用特权

评论回复
12
lzh12a3nf|  楼主 | 2023-9-7 16:10 | 只看该作者
qcliu 发表于 2023-9-5 19:44
现在主流外部flash芯片的接口是不是都是串口呢

我现在接触到的都是

使用特权

评论回复
13
lzh12a3nf|  楼主 | 2023-9-7 16:30 | 只看该作者
wiba 发表于 2023-9-6 10:16
因为是使用io模拟的 所以是不是对时钟频率的要求就比较高呢

我认为是的。

使用特权

评论回复
14
lzh12a3nf|  楼主 | 2023-9-7 16:43 | 只看该作者
coshi 发表于 2023-9-5 17:22
四线制的spi可以有一主多从吗

结合手册来说的话,我认为是可以有的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

37

帖子

0

粉丝