【FPGA】FPGA实现SPI协议读写FLASH(一)----- M25P16操作概述

本文详细介绍了M25P16串行Flash存储器的工作原理和操作,包括其存储结构、SPI模式、指令集及时间参数。在FPGA项目中,通过SPI协议实现对M25P16的读写,涉及的主要指令有写使能、页编程、扇区擦除、读ID和读数据等。M25P16支持高速SPI接口,具有先进写保护功能,适用于各种存储需求。

写在前面:
FPGA实现SPI协议读写FLASH系列相关文章:
SPI通信协议

本项目中所使用的开发板型号:Cyclone IV E (EP4CE6F17C8),FLASH型号:M25P16

一、FLASH介绍(M25P16)

1、M25P16概述

M25P16是一款带有先进写保护机制和高速SPI总线访问的串行Flash存储器。M25P16特点如下:

  • 存储结构:16M Bit(2M Byte)的存储空间,一共32个扇区(sector),每个扇区256页,每页256字节。
  • SPI总线兼容的串行接口。
  • 可以单扇区擦除,也可以整块擦除。
  • 可以同时编程1~256字节,页编程速率高达256Byte/1.4ms,即写入一页数据需要1.4ms。
  • 数据保存至少20年。
  • 支持SPI工作模式0和3。

M25P16引脚图如下:

在这里插入图片描述
在这里插入图片描述
C: 时钟信号,相当于SPI总线的SCLK。
D: 数据输入,相当于SPI总线的主机输出、从机输入MOSI。
Q: 数据输出,相当于SPI总线的主机输入、从机输出MISO。
S#: 片选信号,相当于SPI总线的片选信号CS_N。
HOLD: 在选中期间期间输出高阻态,实际上比较像SDRAM的“掩码”。
W#: 写保护,低电平有效,在写保护有效时无法写入数据。
VCC: 电源。
VSS : 电源地。

2、SPI模式

在这里插入图片描述
在这里插入图片描述

3、存储结构

M25P16一共2M Byte字节的存储空间,分32个扇区(SECTOR),每个扇区256页(PAGE),每页256字节(BYTE)。每个字节的的存储地址由扇区地址(8bit)+页地址(8bit)+字节地址(8bit)构成。
在这里插入图片描述

4、指令集

在本项目中只用到WREN指令、SE指令、RDSR指令、PP指令、RDID指令、READ指令即可。

在这里插入图片描述

5、时间参数

M25P16支持频率如下:
在这里插入图片描述
页写, 全擦除,扇区擦除等指令在发出后,仍需要一定的时间才能真正执行完,各个指令所需的时间如下:
在这里插入图片描述
两个指令之间需要间隔一定的时间(比如发送全擦除指令前需要发送写使能指令,在这两个指令之间就需要间隔一定的时间),具体时间如下:
在这里插入图片描述

二、M25P16工作原理

M25P16写入一个字节数据需写使能(WREN)和写入(PP)指令,采用这两个指令实现单页编程。对于某个单字节空间的操作,在使用PP指令之前需要对其擦除(FFh)。擦除操作可通过单块擦除指令(SE)和整块擦除(BE)来完成。擦除之前需要先执行WREN指令。

当片选信号被拉为低电平,在时钟信号的第一个下降沿开始采样数据输入信号。每个指令序列都是以单字节指令代码开头,紧接着就是地址或数据。在读取数据、快速读取数据、读状态寄存器、读标识和读电子签名时,数据输出序列紧随输入指令序列。当数据输出序列的所有数据位都输出后,片选信号置为高电平。而在页数据写入、单块擦除、整块擦除、写状态寄存器、写使能和写无效时,片选信号必须在一个字节内置为高电平。否则,指令不执行。也就是说,拉低片选信号后,时钟信号必须是8的整数倍。在写状态寄存器间期、数据写入周期或者擦除周期,则忽略任何对存储空间的访问,并不会对这些周期产生影响。

三、M25P16指令操作

1、页编程 (PP)

要发送一个数据字节,需要两个指令:写使能指令(WREN)和页编程指令(PP),然后是内部页编程周期(持续时间为tPP)。Page Program (PP)指令允许一次编程最多256字节(将位从1改为0),前提是它们位于同一内存页上的连续地址中。

2、扇区擦除和整块擦除 (SE and BE)

页程序(PP)指令允许位从1重置为0。在此之前,需要将内存字节全部擦除为FFh。这既可以使用扇区擦除指令(SE)实现擦除一个扇区,也可以使用整块擦除指令(BE)实现整块擦除。发送完擦除指令后就进入擦除周期(持续时间tSE或tBE)。发送擦除指令之前必须先发送写使能指令。

3、写使能 (WREN)

写使能(WREN) 指令用于设置内部写使能锁存器位。在页编程(PP)、扇区擦除(SE)、整块擦除(BE)和写状态寄存器(WRSR)之前,必须先执行写使能。当片选信号拉低后,就开始执行写使能指令,接着传输指令。指令发送完后,片选信号置为高电平。

写使能时序图如下:

在这里插入图片描述

4、读ID(RDID)

Read Identification (RDID)指令允许读取8位的制造商标识,然后读取两个字节的设备标识。设备标识由设备制造商指定,第一个字节表示内存类型(20h),第二个字节表示内存类型(20h),第三个字节表示设备的内存容量(15h)。
在这里插入图片描述
读ID时序图如下:

在这里插入图片描述

5、读状态寄存器(RDSR)

读取状态寄存器(RDSR)指令允许读取状态寄存器。状态寄存器可以在任何时候被读取,即使是在页编程、擦除或写状态寄存器周期正在进行。当其中一个循环正在进行时,建议检查WIP位,然后再向设备发送新指令。
在这里插入图片描述
WIP: WIP (Write In Progress)位表示内存是否处于写状态寄存器、页编程或擦除周期。当设置为1时,表示设备处于工作状态,当设置为0时,表示设备处于空闲状态。
WEL: WEL (Write Enable Latch)位表示内部Write Enable Latch的状态。当设置为1时,内部写使能被设置,当设置为0时,表示没有接收写状态寄存器,页编程或擦除指令。
BP2、BP1、BP0: 块保护(BP2,BP1, BP0)位是非易失性的。它们定义了被软件保护的区域的大小
编程和擦除指令。这些位是用写状态寄存器(WRSR)指令写的。

读状态寄存器时序图如下:

在这里插入图片描述

6、读数据(READ)

首先通过驱动片选信号来选择设备,片选信号低有效。读取数据的指令字节(READ)指令后面跟着一个3字节的地址(A23-A0),每个位在串行时钟(SCLK)的上升沿期间被锁存。然后,在串行数据输出(Q)上输出数据。

读数据时序图如下:

在这里插入图片描述

### FPGA SPI Flash接口设计与读写操作 FPGA通过SPI协议Flash存储器进行通信是种常见的应用。以下将详细介绍如何在FPGA实现SPI协议以完成对Flash存储器的读写操作。 #### 1. SPI协议基础 SPI(Serial Peripheral Interface)是种同步串行通信接口,通常用于短距离通信。它包含四根主要信号线:MOSI(Master Out Slave In)、MISO(Master In Slave Out)、SCLK(Serial Clock)和CS(Chip Select)。在FPGAFlash存储器的交互中,FPGA作为主设备控制SPI时钟和数据传输[^1]。 #### 2. FPGA SPI控制器设计 FPGA中的SPI控制器可以通过硬件描述语言(如Verilog或VHDL)实现。以下是个基本的SPI控制器模块设计框架: ```verilog module spi_controller ( input wire clk, // 系统时钟 input wire reset_n, // 复位信号,低电平有效 output reg sclk, // SPI时钟 output reg mosi, // 主设备输出 input wire miso, // 从设备输出 output reg cs_n, // 片选信号,低电平有效 input wire [7:0] tx_data,// 发送数据 output reg [7:0] rx_data // 接收数据 ); reg [3:0] bit_count; // 位计数器 reg [7:0] shift_reg; // 移位寄存器 always @(posedge clk or negedge reset_n) begin if (!reset_n) begin sclk <= 1'b0; mosi <= 1'b0; cs_n <= 1'b1; bit_count <= 4'd0; shift_reg <= 8'd0; rx_data <= 8'd0; end else begin if (cs_n == 1'b0) begin // 当片选信号激活时 if (bit_count < 8) begin sclk <= ~sclk; // 切换时钟 if (sclk == 1'b1) begin // 在时钟上升沿处理数据 mosi <= tx_data[7 - bit_count]; // 发送数据 shift_reg <= {shift_reg[6:0], miso}; // 接收数据 bit_count <= bit_count + 1; end end else begin rx_data <= shift_reg; // 数据接收完成 cs_n <= 1'b1; // 解除片选 end end end end endmodule ``` 上述代码展示了个简单的SPI控制器模块,支持单字节的数据发送和接收[^2]。 #### 3. Flash存储器的操作指令 Flash存储器通常需要特定的命令序列来执行读写操作。例如,常见的读取命令为`0x03`(Read Data),写入命令为`0x02`(Write Data)。在实际设计中,需要根据Flash的具体型号查阅其数据手册以获取准确的指令集[^3]。 #### 4. FPGA SPI读写Flash流程 以下是通过FPGA实现SPI读写Flash的基本流程: - 初始化SPI控制器并设置片选信号。 -Flash发送指令字节(如`0x03`表示读取操作)。 - 根据指令要求发送地址信息。 - 执行数据传输阶段,读取或写入数据。 对于写入操作,还需要确保Flash处于写使能状态,这通常通过发送`0x06`(Write Enable)指令实现[^4]。 #### 5. 注意事项 - 确保SPI时钟频率符合Flash存储器的要求。 - 在设计中加入适当的等待时间,以避免因Flash忙而导致的数据错误。 - 使用状态机来管理复杂的读写流程,提高设计的可维护性和可靠性。 ### 示例代码 以下是个简单的状态机设计,用于管理SPI读写Flash操作: ```verilog typedef enum logic [2:0] { IDLE, SEND_CMD, SEND_ADDR, TRANSFER_DATA, WAIT_BUSY } state_t; state_t state; always @(posedge clk or negedge reset_n) begin if (!reset_n) begin state <= IDLE; end else begin case (state) IDLE: begin if (start_read) begin state <= SEND_CMD; end end SEND_CMD: begin if (spi_busy == 1'b0) begin state <= SEND_ADDR; end end SEND_ADDR: begin if (spi_busy == 1'b0) begin state <= TRANSFER_DATA; end end TRANSFER_DATA: begin if (spi_busy == 1'b0) begin state <= IDLE; end end WAIT_BUSY: begin if (flash_busy == 1'b0) begin state <= IDLE; end end endcase end end ``` 此代码片段展示了个基于状态机的SPI读写控制逻辑[^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值