spispi

发布于:2024-04-17 ⋅ 阅读:(19) ⋅ 点赞:(0)

   写入操作

        ·写入操作前先进行写使能,为了防止误操作,写使能通过SPI发送写使能的指令。

        ·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时芯片不忙再进行操作。

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

读取操作