W25Q64

1,986 阅读14分钟

1.W25Q64简介

非易失性存储器:数据不容易失去的存储器,数据掉电不丢失,存储在芯片中的数据在断电重启之后数据仍然保持原样。

    固件程序存储:相当于直接把程序文件下载到外挂芯片里,需要执行程序的时候,直接读取外挂芯片的程序文件来执行,这就是XIP(eXecute In Place)就地执行,比如电脑里的BIOS固件,就可以存储在这个W25Q系列的芯片里。

    芯片的存储介质是Nor Flash(闪存),像stm32的程序存储器、u盘、电脑里的固态硬盘等都是使用Flash闪存。闪存分为Nor Flash和Nand Flash。

    时钟频率80MHz比stm32快,后边写程序的时候翻转引脚无需加延时,因为不延时GPIO的频率也达不到80MHz,可放心使用。

    160MHz是双重SPI模式等效的频率,320MHz是四重SPI等效的频率。MISO和MOSI在全双工通信时只发或只收会有资源浪费,W25Q64的厂商为了防止资源浪费,设计了在收的时候可以同时使用MOSI和MISO接收,发送也可以同时发送,同时兼具发送和接收的功能,一个SCK时钟同时发送或接收2位数据。一个时钟收发两位,相比于一位一位的普通SPI,数据传输率就是2倍,即在双重SPI模式下,等效的时钟频率就是80MHz的2160MHz,实际上的SCK最大频率还80MHz,知识一个时钟发2位而已。

    四重SPI模式,很显然就是一个时钟发送或接收4位,等效的频率就是80*4=320MHz。在芯片中除了SPI通信引脚,还有两个引脚,一个是WP写保护,一个是HOLD,这两个引脚如果不需要的话,也可以拿来充当数据传输引脚,加上MISO和MOSI就可以四个数据位同时收发。相当于并行传输,串行传输是根据时钟一位一位的发送,并行是一个时钟8位同时发送,这个四重SPI模式其实就是4位并行的模式。

    容量习惯以字节为单位,一个字节对应8个二进制位,实际容量是64Mbit除以8也就是8MByte,bit对应到byte要除以8。

    芯片使用的是24位的地址,就是3个字节。在进行读写的时候每个字节都得分配一个地址。在指定地址时需要一次性指定3个字节即24位的地址,24位地址最大可分配的字节是: = 1677216位数,除以1024 = 16384kb,再除以1024 = 16MB,所以24位地址的最大寻址空间是16MB。W25Q40~W25Q128使用3字节24位的地址都是足够的。

    但是W25Q256不一样,24位地址对于32MB来说是不够的,W25Q256分为3字节地址模式和4字节地址模式,在3字节地址模式下,只能读写前16MB的数据,后面16MB,3个字节的地址够不着,要想读写到所有存储单元,可以进入4字节地址模式。

2.硬件电路

4脚和8脚是电源引脚,供电电压是3.3V,不能直接接入5V电压。

    1号脚CS 左边画了斜杠,代表的是低电平有效,或者CS上边画了横杠也是低电平有效,CS对应前边的就是SS片选引脚

    6号脚CLK对应的就是SCK时钟线

    5号脚DI对应的是MOSI主机输出从机输入,

    2号脚DO对应的是MISO主机输入从机输出,

    3号脚WP(Write Project)写保护,配合内部的寄存器配置,可以实现硬件的写保护,写保护低电平有效,WP接低电平,保护住不让写;WP接高电平,不保护,可以写。

    7号脚HOLD,数据保持,低电平有效。如果在进行读写时突然产生中断,想用SPI通信线去操控其他器件,这时将CS置回高电平,时序终止。如果此时不想终止总线,又想操作其他器件,这时候可以HOLD引脚置低电平,将芯片HOLD住,芯片释放总线,但是芯片的时序不会终止,会记住当前的状态,操作完其他器件时可以回过来将HOLD置高电平,继续HOLD之前的时序,相当于SPI进了一次中断。在中断里SPI可以做其他的事。

    DI、DO、WP和HOLD旁边都有括号,写了IO0、IO1、IO2、IO3,对应前边提及的双重SPI和四重SPI;如果是普通的SPI,括号中的不用看;如果是双重SPI那么DI和DO就变成IO0和IO1,也就是数据同时收和同时发的两个数据位;如果是四重SPI,那就再加上WP当做IO2,HOLD当做IO3,四个引脚都当做数据收发引脚,一个时钟4个数据位。

    图中的硬件电路中,HOLD和WP都接到了VCC,都是低电平有效,接到VCC意为着这两个功能不用。C1接VCC和GND,显然是电源滤波,R1和LED也接到VCC和GND,起电源指示灯的作用,通电就亮,

3.W25Q64框图

  • W25Q64的容量是8MB,如果不划分按照一整块使用的话容量太大不利于管理,后续设计到Flash擦除或写入的时候,会有个基本单元,得以基本单元为单位进行,因此需要对这8MB的存储空间进行划分。

将这一整块区域分解为若干个块Block

在这一个矩形空间里,是所有的存储器。存储器以字节为单位,每一个字节都有唯一的地址。W25Q64的地址宽度是3个字节24位,最下面第一个字节,地址是00 00 00h,h代表16进制,之后的空间地址依次递增,直到最后一个字节地址是7f ff ff h。最后一个地址是7F开头而不是FF开头,因为24位的地址最大的寻址范围是16MB,这个芯片只有8MB,所以地址空间只用了一半,8MB的空间排到最后一个字节就是7F FF FF。

 在这整个空间里,以64KB为一个基本单元,划分为若干的块block,从下往上依次是块0、块1、块2......一直到块127(8 * 1024 / 64 = 128,一共有128个,从0开始,到127)。

 块0的起始地址是00 00 00,结束地址是00 ff ff;块31起始地址是1f 00 00,结束地址是1f ff ff,观察后续的地址可以发现规律,在每一块内地址变化范围是最低的两个字节,每个块的起始是xx 00 00,结束是xx ff ff 。

###其中每一块再划分成若干的扇区Sector 对每一块进行更细的划分,这里的虚线指向了右边的各个块,意思是每个块里边都是这样子,每个块中起始地址是xx 00 00,结束是xx ff ff,对应图中的左下角和右上角的地址。在块里以4KB为一个单元进行切分,分成16(64 / 4 = 16)个扇区,扇区0~扇区15,每个扇区内的地址范围是xx x0 00到xx xf ff

###SPI控制逻辑

  • SPI Command&Control Logic是SPI的控制逻辑**,芯片内部进行地址锁存、数据读写等操作,都是由控制逻辑自动完成。控制逻辑的左边是SPI的通信引脚,这些引脚和主控芯片相连,主控芯片通过SPI协议,把指令和数据发送给控制逻辑,控制逻辑就会自动取操作内部电路实现功能。
  • Status Register状态寄存器芯片是否处于忙状态、是否写使能、是否写保护,都可以在这个状态寄存器中体现。
  • 写控制逻辑Write Control Register,和外部的WP引脚相连,配合WP引脚实现硬件写保护
  • 高电压生成器High Voltage Generators,是配合Flash进行编程的,Flash掉电不丢失,要想产生掉电不丢失的状态,一般需要一个比较高的电压去刺激,需要一个高压源,这里内部集成了一个高电压发生器,就不需要外接高电压,比较方便。

页地址缓存区

右边有个256字节的页缓存区Column Decode And 256-Byte Page Buffer,实际上是个256字节的RAM存储器,数据读写是通过这个RAM缓存区进行的,写入数据的时候会先放入缓存区里,在时序结束之后芯片再将缓存区的数据复制到对应的Flash里边,进行永久保存。

  • 设置缓存区的原因是,SPI写入频率极高,Flash写入需要掉电不丢失,写入较慢。所以写入的数据先在页缓存区存着,缓存区是RAM速度较快,跟得上SPI总线的速度,但是问题在于缓存区只有256字节,写入的时序有限制条件,写入一个时序的连续写入量不能超过256个字节,写完后芯片再将数据从缓存区转移到Flash存储器里边。

  • 数据转移到Flash需要一定的时间,在写入时序结束之后芯片会进入一段忙的状态,所以在页缓存区的左边有一条线通往状态 寄存器,给状态寄存器的BUSY位置1,表示芯片当前正在忙,此时芯片不会响应新的读写时序。 写入操作前先进行写使能,为了防止误操作,写使能通过SPI发送写使能的指令。

读数据

  • 图中读数据也是从缓存区进行读取,但是区别在于,读取只需要看一下电路的状态即可,基本不花时间,限制非常的少

#4 Flash操作注意事项 ###写入操作

*Flash不和RAM一样具备直接覆盖改写的能力,比如在某一个字节的存储单元里存储了0xaa这个数据,对应的二进制位是1010 1010,如果在这个存储单元再次写入数据0x55二进制位是0101 0101,当新的0101 0101要覆盖原来的1010 1010时,会受到限制(每个数据位只能由1变0不能由0变1)。改写数据的过程中,最高位的1改写为0是ok的,写入后新的最高位就是0;在第二位原来是0现在想改写成1,违反规则,仍然是0;第三位原来的1改成0ok,第四位0无法变1仍然为0.以此类推最后转换成0000 0000,并不是我们需要储存的结果。

*因此有了新的规则,在写入数据前将数据进行擦除,就可以写入正确的数据。数据位为1的数据拥有单向改成0的权利,一旦写成0之后不能改回1,除非先擦除,所有的位变1重新写入。如果不擦除就写入的话,基本上数据会出现错误。有时候读取Flash发现数据全是ff,有可能是写入数据的空白空间。

*擦除必须按最小擦除单元进行,如果想在00地址下进行写入数据,需要先把00地址擦除再写入到00地址。但是Flash的擦除有最小擦除单元限制,不能指定某一个字节去擦除,要擦需要一大片一起擦,在芯片中可以选择整个芯片擦除,也可以选择按快擦除或按扇区擦除,最小的擦除单元是一个扇区。一个扇区是4096个字节,每次擦除最少得4096个字节一起擦。如果在擦除数据时想不丢失数据,只能先把4096个字节读出来,再把4096个字节的扇区擦掉,改写完读出来的数据之后,再把改写完的全部写回去。 *也有另一种方法可以优化这个流程,比如上电之后先把Flash的数据读出来放到RAM里,当有数据变动时再统一把数据备份到Flash里;或者把使用频繁的扇区放在RAM里,当使用频率降低时再把整个扇区备份到Flash里,或者数据量非常少,只想存几个字节的参数而已,那可以选择一个字节占一个扇区。

*一个写入时序最多只能写入一页的数据,也就是256个字节,因为前边提及的页缓存区只有256个字节。Flash写入速度太慢跟不上SPI,缓存区的是写入的数据放在RAM里暂存,等时序结束后芯片再慢慢把数据写入Flash里。所以每个时序只能写入256字节数据,如果非要写超过256字节的数据,则超过页尾的数据会回到页首覆盖写入。 *页缓存区是和Flash的页对应的,必须得从页起始位置开始才能写入256字节,如果从页中间开始写,那写到页尾时地址会跳回页首,导致地址错乱。所以在进行多字节写入时,注意地址范围不能跨越界的边沿,否则会地址错乱。

*写入结束后芯片进入忙状态,写入操作是对缓存区进行的,在时序结束之后芯片还需要搬运一段时间,写入操作之后会有一段时间的忙状态,在这个状态下不进行读写操作,芯片不会响应。要想知道芯片忙状态是否结束,可以使用读取状态寄存器的指令,查看状态寄存器的BUSY位是否为1,BUSY位为0时芯片不忙再进行操作。

*包括擦除指令也会使芯片进入忙状态,需要等忙状态结束后才能进行后续操作。

*可以在每次写操作时序结束之后调用一下WaitBusy,分为事前等待和事后等待:

*事后等待:可以选择在每次写入后等待Busy清零之后再退出,这样较为保险,函数结束之后芯片处于不忙的状态,

*事前等待:写入时序后不进行等待,而是在每次操作之前进行等待,不忙的时候写入。

*两者区别在于:事后等待最保险,事前等待效率会高,写完之后不等可以执行其他代码,可以利用执行代码的时间消耗等待的时间。事后等待只需要在写入操作之后调用,而事前等待在写入操作和读写操作之前都得调用,因为在忙的时候不能读取 ###读取操作 *读取时较为宽松,无需使能,对应写入的第一条

*读取时较为宽松,无需使能,对应写入的第一条 *没有页的限制,对应第五条,想读多少读多少,没有页的限制

*·读取后不会进入忙状态,可以立刻执行下一条指令,但是不能再忙状态下进行读取,对应写入的第六条,忙状态时不会响应新的读写操作,在读取之前需要注意一下芯片的状态是否处于忙状态。Flash这种非易失性存储器,虽然有诸多不方便,但是可以使用软件来弥补,他的优点是其他存储器无法比,容量大价格低,速度虽然比RAM低,但是在非易失性存储器中非常快。