SPI通信协议
AI summary
本文详细介绍了SPI通信协议的操作,包括读取ID、块擦除(BE)、读状态寄存器(RDSR)和其他指令的实现过程。每个指令的执行步骤、时序和必要的信号变化都进行了详细描述,强调了在发送新命令之前需要检查WIP位的状态。
Last edited time
Oct 11, 2024 02:48 PM
Last edited by
Tags
Serial Communication
Communication Protocols
Data Transmission Methods
第一部分:SPI协议
一:常用的串行通信协议
通信协议 | 通信接口 | 通信方式 | 通信方向 | 说明 |
UART:通用异步收发器 | TXD,RXD | 异步通信 | 全双工 | |
SPI:串行外设接口 | CS_N,SCLK,MISO,MOSI | 同步通信 | 全双工 | |
IIC:集成电路总线 | SCL,SDA | 同步通信 | 半双工 |
- SPI:Serial Peripheral Interface:串行外设接口
SPI,是一种高速的,全双工,同步通信总线,并且在芯片的管脚上只占用4根线,线路简单,利用这一特点,使得越来越多的芯片集成了这种通信协议。
- SPI的通信原理比较简单,往往以主从方式进行工作,这种模式通常有1个主设备和1个/多个从设备,之间靠四线连接(三线:数据线为双向传输)。
CS_N是从芯片是否被主芯片选中的控制信号,也就是说只有片选信号为预先设定的使能信号时(低有效),主芯片对此从芯片的操作才有效,输出对应的数据;没有选择中的从芯片,输出高阻态;这就使得在同一条数据线上连接多个SPI设备成为可能。
选择中的外围器件,在总线上会进行输出;没有选择中的外围器件,会在总线上输出高阻态。
数据传输时:由主设备发出时钟线SCLK,数据线MOSI,回收数据线MISO 。
通过时钟线和数据线完成数据的传输。
数据输出会通过MOSI线,数据是在时钟上升沿/下降沿时改变;在紧接着的下降沿/上升沿时读取,从而来完成一位数据的传输。
数据输入会通过MISO线,数据是在时钟上升沿/下降沿时改变;在紧接着的下降沿/上升沿时读取,从而来完成一位数据的传输。
- SPI通信模式
SPI通信有4种不同的模式:通信的双方必须工作在同一模式下,所以大家可以对主设备的SPI模式进行配置,通过CPOL(时钟极性)和CPHA(时钟相位)来控制主设备的通信模式。
Mode0:CPOL=0 CPHA=0; //00/0模式
Mode1:CPOL=0 CPHA=1; //01/1模式
Mode2:CPOL=1 CPHA=0; //10/2模式
Mode3:CPOL=1 CPHA=1; //11/3模式
CPOL是用来配置SCLK在空闲时处于的状态,如果CPOL=0,表示空闲状态时时钟为低电平;如果CPOL=1,表示空闲状态时时钟为高电平。
CPHA是用来配置在第几个边沿进行采样,如果CPHA=0,表示数据采样在第一个沿;如果CPHA=1,表示数据采样在第二个沿。
//00/0模式
CPOL=0,CPHA=0:时钟空闲时,SCLK处于低电平,数据采样是在第一个沿,也就是SCLK由低到高的跳变,所以数据采样是在时钟上升沿,数据改变是在时钟下降沿。
//01/1模式
CPOL=0,CPHA=1:时钟空闲时,SCLK处于低电平,数据采样是在第二个沿,也就是SCLK由高到低的跳变,所以数据采样是在时钟下降沿,数据改变是在时钟上升沿。
//10/2模式
CPOL=1,CPHA=0:时钟空闲时,SCLK处于高电平,数据采样是在第一个沿,也就是SCLK由高到低的跳变,所以数据采样是在时钟下降沿,数据改变是在时钟上升沿。
//11/3模式
CPOL=1,CPHA=1:时钟空闲时,SCLK处于高电平,数据采样是在第二个沿,也就是SCLK由低到高的跳变,所以数据采样是在时钟上升沿,数据改变是在时钟下降沿。
- SPI通信协议
00/11模式:数据改变都是在时钟下降沿,数据读取都是在时钟上升沿。
01/10模式:数据改变都是在时钟上升沿,数据读取都是在时钟下降沿。
常用的SPI模式为00/11模式。
第二部分:M25P16器件手册
一:ZX-1板卡原理图和M25P16封装图
ZX-1原理图信号 | M25P16封装图信号 | 管脚位置(BANK) |
1:nCS(NCSO) | 1:CS_N | D2(多功能管脚) |
2:DATA(DATA0) | 2:Q | H2(多功能管脚) |
3:VCC | 3:W_N | |
4:GND | 4:Vss | |
5:ASDI(ASDO) | 5:D | C1(多功能管脚) |
6:DCLK(DCLK) | 6:C | H1(多功能管脚) |
7:VCC | 7:HOLD_N | |
8:VCC | 8:VCC |
二:M25P16组成
- Flash(M25P16)闪存,属于非易失性存储器。
- M25P16(16Mbit)有32个扇区,每一个扇区(512Kbit)有256页,每一页有256个字节,一共有8192页或者2M个字节。
1sec:512Kbit 1Page:256byte
512*1024bit/8=2^9*2*10/2^3=2^16byte(65,536Byte)
256byte=2^8byte
1sec/1page=2^16byte/2^8byte=2^8=256
32*256*256=2^5*2^8*2^8=2^21= 2,097,152=2M
三:端口描述
C/D/Q/S需要关注SPI协议。
00/11模式即可
四:M25P16指令集
五:M25P16常用的指令
- WREN指令
- WREN仿真测试
- WREN下板验证
在PP/SE/BE/WRSR指令之前,都必须首先打开写使能。打开写使能时发送写使能指令码(8’h06)。
当片选(CS_N=0)拉低后,就开始执行写使能指令,传输指令码(8’h06),通过D数据线进行传输,在传输数据时Q数据线为高阻,直到写使能指令码发送完成后,片选信号(CS_N=1)拉高。
在测试写使能功能过程中,规定C(SCLK:时钟线)采用5MHZ。
设计时采用线性序列机实现。
节拍 | LSM_1S:节拍计数 | LSM_2S:节拍上发生动作 | 说明 |
(sys_rst_n==0):cnt=0 | (sys_rst_n==0):spi_sclk=0,spi_d=0,spi_cs_n=1 | 初始值 | |
0 | cnt=0 | spi_sclk=0,spi_d=0,spi_cs_n=1 | 0节拍 |
1 | cnt=cnt+1 | spi_cs_n=0, spi_sclk=0,spi_d=WREN[7] | 数据:MSB(WREN=8’h06):将CS_N拉低 |
1+1*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[7] | HALF:5个节拍 |
1+2*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[6] | 下降沿改变数据,上升沿保持数据 |
1+3*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[6] | HALF:5个节拍 |
1+4*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[5] | HALF:5个节拍 |
1+5*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[5] | HALF:5个节拍 |
1+6*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[4] | HALF:5个节拍 |
1+7*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[4] | HALF:5个节拍 |
1+8*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[3] | HALF:5个节拍 |
1+9*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[3] | HALF:5个节拍 |
1+10*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[2] | HALF:5个节拍 |
1+11*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[2] | HALF:5个节拍 |
1+12*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[1] | HALF:5个节拍 |
1+13*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[1] | HALF:5个节拍 |
1+14*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[0] | HALF:5个节拍 |
1+15*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[0] | 数据:LSB |
1+16*HALF | cnt=cnt+1 | spi_sclk=0,spi_d=0,spi_cs_n=1 | 将CS_N拉高 |
- RDID指令
- RDID仿真测试
- RDID下板验证
首先需要通过D线发送读ID指令码(8’h9F),等待发送完成后,需要通过Q线往回收3个字节数据(24’h202015),在整个数据传输器件,CS_N持续为低电平。
注1:D线发送数据期间,Q线为高阻。
注2:Q线接收数据期间,D线为初值。
在测试读ID功能过程中,规定C(SCLK:时钟线)采用5MHZ。
设计时采用线性序列机实现。
节拍 | LSM_1S:节拍计数 | LSM_2S:节拍上发生动作 | 说明 |
(sys_rst_n==0):cnt=0 | (sys_rst_n==0):spi_sclk=0,spi_d=0,spi_cs_n=1 | 初始值 | |
0 | cnt=0 | spi_sclk=0,spi_d=0,spi_cs_n=1 | 0节拍 |
FPGA发送读ID指令 | ㅤ | ㅤ | ㅤ |
1 | cnt=cnt+1 | spi_cs_n=0, spi_sclk=0,spi_d=RDID[7] | 数据:MSB(RDID=8’h9F):将CS_N拉低 |
1+1*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=RDID[7] | HALF:5个节拍 |
1+2*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDID [6] | 下降沿改变数据,上升沿保持数据 |
1+3*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDID [6] | HALF:5个节拍 |
1+4*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDID [5] | HALF:5个节拍 |
1+5*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDID [5] | HALF:5个节拍 |
1+6*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDID [4] | HALF:5个节拍 |
1+7*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDID [4] | HALF:5个节拍 |
1+8*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDID [3] | HALF:5个节拍 |
1+9*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDID [3] | HALF:5个节拍 |
1+10*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDID [2] | HALF:5个节拍 |
1+11*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDID [2] | HALF:5个节拍 |
1+12*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDID [1] | HALF:5个节拍 |
1+13*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDID [1] | HALF:5个节拍 |
1+14*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDID [0] | HALF:5个节拍 |
1+15*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDID [0] | 数据:LSB |
1+16*HALF | cnt=cnt+1 | spi_sclk=0,spi_d=0 | D线发送读ID指令完成 |
FPGA发送完读ID指令完成后,需要开始接收Flash发送过来的3个字节ID:20 20 15 | ㅤ | ㅤ | ㅤ |
1+17*HALF | cnt=cnt+1 | spi_sclk=1, id[23]=spi_q | 读取Q线上3个字节数据:第一个字节(20) |
1+18*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+19*HALF | cnt=cnt+1 | spi_sclk=1, id[22]=spi_q | |
1+20*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+21*HALF | cnt=cnt+1 | spi_sclk=1, id[21]=spi_q | |
1+22*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+23*HALF | cnt=cnt+1 | spi_sclk=1, id[20]=spi_q | |
1+24*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+25*HALF | cnt=cnt+1 | spi_sclk=1, id[19]=spi_q | |
1+26*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+27*HALF | cnt=cnt+1 | spi_sclk=1, id[18]=spi_q | |
1+28*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+29*HALF | cnt=cnt+1 | spi_sclk=1, id[17]=spi_q | |
1+30*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+31*HALF | cnt=cnt+1 | spi_sclk=1, id[16]=spi_q | |
1+32*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+33*HALF | cnt=cnt+1 | spi_sclk=1, id[15]=spi_q | 读取Q线上3个字节数据:第二个字节(20) |
1+34*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+35*HALF | cnt=cnt+1 | spi_sclk=1, id[14]=spi_q | |
1+36*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+37*HALF | cnt=cnt+1 | spi_sclk=1, id[13]=spi_q | |
1+38*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+39*HALF | cnt=cnt+1 | spi_sclk=1, id[12]=spi_q | |
1+40*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+41*HALF | cnt=cnt+1 | spi_sclk=1, id[11]=spi_q | |
1+42*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+43*HALF | cnt=cnt+1 | spi_sclk=1, id[10]=spi_q | |
1+44*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+45*HALF | cnt=cnt+1 | spi_sclk=1, id[9]=spi_q | |
1+46*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+47*HALF | cnt=cnt+1 | spi_sclk=1, id[8]=spi_q | |
1+48*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+49*HALF | cnt=cnt+1 | spi_sclk=1, id[7]=spi_q | 读取Q线上3个字节数据:第三个字节(15) |
1+50*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+51*HALF | cnt=cnt+1 | spi_sclk=1, id[6]=spi_q | |
1+52*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+53*HALF | cnt=cnt+1 | spi_sclk=1, id[5]=spi_q | |
1+54*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+55*HALF | cnt=cnt+1 | spi_sclk=1, id[4]=spi_q | |
1+56*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+57*HALF | cnt=cnt+1 | spi_sclk=1, id[3]=spi_q | |
1+58*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+59*HALF | cnt=cnt+1 | spi_sclk=1, id[2]=spi_q | |
1+60*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+61*HALF | cnt=cnt+1 | spi_sclk=1, id[1]=spi_q | |
1+62*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+63*HALF | cnt=cnt+1 | spi_sclk=1, id[0]=spi_q | |
1+64*HALF | cnt=cnt+1 | spi_sclk=0,spi_cs_n=1’b1 | 拉高CS_N |
W25Q16读取ID(24’hEF4015)
- BE指令
- BE仿真测试
- BE下板验证
在执行BE指令之前,需要先发送WREN指令(8’h06),等待WREN指令发送完成后,需要将CS_N至少拉高100ns(Tshsl:min=100ns),再次发送BE指令(8‘hC7),等待BE指令完成,块擦除时需要时间TBE(13s:MAX=40s),等待块擦除时间周期后,来判断块擦除进程有没有结束(读状态寄存器中检测WIP),如果WIP=1,表明还处于擦除进程当中,如果WIP=0,表明擦除进行结束。
在测试块擦除(BE)功能过程中,规定C(SCLK:时钟线)采用5MHZ。
设计时采用线性序列机实现。
节拍 | LSM_1S:节拍计数 | LSM_2S:节拍上发生动作 | 说明 |
(sys_rst_n==0):cnt=0 | (sys_rst_n==0):spi_sclk=0,spi_d=0,spi_cs_n=1 | 初始值 | |
0 | cnt=0 | spi_sclk=0,spi_d=0,spi_cs_n=1 | 0节拍 |
1 | cnt=cnt+1 | spi_cs_n=0, spi_sclk=0,spi_d=WREN[7] | 数据:MSB(WREN=8’h06):将CS_N拉低 |
1+1*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[7] | HALF:5个节拍 |
1+2*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[6] | 下降沿改变数据,上升沿保持数据 |
1+3*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[6] | HALF:5个节拍 |
1+4*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[5] | HALF:5个节拍 |
1+5*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[5] | HALF:5个节拍 |
1+6*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[4] | HALF:5个节拍 |
1+7*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[4] | HALF:5个节拍 |
1+8*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[3] | HALF:5个节拍 |
1+9*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[3] | HALF:5个节拍 |
1+10*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[2] | HALF:5个节拍 |
1+11*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[2] | HALF:5个节拍 |
1+12*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[1] | HALF:5个节拍 |
1+13*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[1] | HALF:5个节拍 |
1+14*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=WREN[0] | HALF:5个节拍 |
1+15*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=WREN[0] | 数据:LSB |
1+16*HALF | cnt=cnt+1 | spi_sclk=0,spi_d=0,spi_cs_n=1 | 将CS_N拉高(持续200ns) |
BE指令之前先发送WREN指令,结束后需将CS_N拉高至少100ns,再发送BE指令 | ㅤ | ㅤ | ㅤ |
1+19*HALF | cnt=cnt+1 | spi_cs_n=0, spi_sclk=0,spi_d=BE[7] | BE=8’hC7 |
1+20*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=BE[7] | HALF:5个节拍 |
1+21*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=BE[6] | HALF:5个节拍 |
1+22*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=BE[6] | HALF:5个节拍 |
1+23*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=BE[5] | HALF:5个节拍 |
1+24*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=BE[5] | HALF:5个节拍 |
1+25*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=BE[4] | HALF:5个节拍 |
1+26*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=BE[4] | HALF:5个节拍 |
1+27*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=BE[3] | HALF:5个节拍 |
1+28*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=BE[3] | HALF:5个节拍 |
1+29*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=BE[2] | HALF:5个节拍 |
1+30*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=BE[2] | HALF:5个节拍 |
1+31*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=BE[1] | HALF:5个节拍 |
1+32*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=BE[1] | HALF:5个节拍 |
1+33*HALF | cnt=cnt+1 | spi_sclk=0, spi_d=BE[0] | HALF:5个节拍 |
1+34*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=BE[0] | 数据:LSB |
1+35*HALF | cnt=cnt+1 | spi_sclk=0,spi_d=0,spi_cs_n=1 | 将CS_N拉高 |
- RDSR指令
- RDSR仿真测试
- RDSR下板验证
在新的命令之前,都需要执行RDSR指令,用于检测WIP位,如果WIP=1,表明Flash处于繁忙(在写状态寄存器/页编程/擦除)状态;如果WIP=0,表明进程结束,可以执行新的命令。
在测试读状态寄存器(RDSR)功能过程中,规定C(SCLK:时钟线)采用5MHZ。
设计时采用线性序列机实现。
节拍 | LSM_1S:节拍计数 | LSM_2S:节拍上发生动作 | 说明 |
(sys_rst_n==0):cnt=0 | (sys_rst_n==0):spi_sclk=0,spi_d=0,spi_cs_n=1 | 初始值 | |
0 | cnt=0 | spi_sclk=0,spi_d=0,spi_cs_n=1 | 0节拍 |
FPGA发送读RDSR指令 | ㅤ | ㅤ | ㅤ |
1 | cnt=cnt+1 | spi_cs_n=0, spi_sclk=0,spi_d=RDID[7] | 数据:MSB(RDSR=8’h05):将CS_N拉低 |
1+1*HALF | cnt=cnt+1 | spi_sclk=1, spi_d=RDSR[7] | HALF:5个节拍 |
1+2*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDSR [6] | 下降沿改变数据,上升沿保持数据 |
1+3*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDSR [6] | HALF:5个节拍 |
1+4*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDSR [5] | HALF:5个节拍 |
1+5*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDSR [5] | HALF:5个节拍 |
1+6*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDSR [4] | HALF:5个节拍 |
1+7*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDSR [4] | HALF:5个节拍 |
1+8*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDSR [3] | HALF:5个节拍 |
1+9*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDSR [3] | HALF:5个节拍 |
1+10*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDSR [2] | HALF:5个节拍 |
1+11*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDSR [2] | HALF:5个节拍 |
1+12*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDSR [1] | HALF:5个节拍 |
1+13*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDSR [1] | HALF:5个节拍 |
1+14*HALF | cnt=cnt+1 | spi_sclk=0, spi_d= RDSR [0] | HALF:5个节拍 |
1+15*HALF | cnt=cnt+1 | spi_sclk=1, spi_d= RDSR [0] | 数据:LSB |
1+16*HALF | cnt=cnt+1 | spi_sclk=0,spi_d=0 | D线发送读ID指令完成 |
FPGA发送完RDSR指令完成后,需要开始接收Flash发送过来的1个字节(参考RDSR数据格式) | ㅤ | ㅤ | ㅤ |
1+17*HALF | cnt=cnt+1 | spi_sclk=1, data[7]=spi_q | 读取Q线上1个字节数据 |
1+18*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+19*HALF | cnt=cnt+1 | spi_sclk=1, data [6]=spi_q | |
1+20*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+21*HALF | cnt=cnt+1 | spi_sclk=1, data [5]=spi_q | |
1+22*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+23*HALF | cnt=cnt+1 | spi_sclk=1, data [4]=spi_q | |
1+24*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+25*HALF | cnt=cnt+1 | spi_sclk=1, data [3]=spi_q | |
1+26*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+27*HALF | cnt=cnt+1 | spi_sclk=1, data [2]=spi_q | |
1+28*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+29*HALF | cnt=cnt+1 | spi_sclk=1, data [1]=spi_q | |
1+30*HALF | cnt=cnt+1 | spi_sclk=0 | |
1+31*HALF | cnt=cnt+1 | spi_sclk=1, data [0]=spi_q | |
1+32*HALF | cnt=cnt+1 | spi_sclk=0,spi_cs_n=1’b1 | 拉高CS_N |
- PP指令
- READ指令
- SE指令
练习:PP/READ/SE指令仿真测试/下板验证
Loading...