bigharpoon 发表于 2022-3-3 10:24:43

一个关于往SPI Flash写数据必须擦除扇区的问题

第一次用SPI Flash,型号是M25P10-A,128K字节。
根据数据手册的描述,往里面写数据,必须先擦除一整块扇区(约32K字节)?请教坛友,是这样的吗?
感觉这种存储器的特性和EEPROM的特性完全不同,前者写一个字节的数据,需要擦除整块扇区才能写!

hjjnt2008 发表于 2022-3-3 10:34:08

flash结构和eeprom不一样,写前必须要先擦除,最少一个扇区,

bigharpoon 发表于 2022-3-3 10:42:34

hjjnt2008 发表于 2022-3-3 10:34
flash结构和eeprom不一样,写前必须要先擦除,最少一个扇区,
(引用自2楼)

原来如此{:smile:} 。
为了写一个字节,那就需要先将扇区的内容先读到buffer,程序里修改buffer,将扇区擦除再将buffer写入至扇区。
这么看来,步骤多出几步,汗!

hjjnt2008 发表于 2022-3-3 10:51:21

bigharpoon 发表于 2022-3-3 10:42
原来如此 。
为了写一个字节,那就需要先将扇区的内容先读到buffer,程序里修改buffer,将扇区 ...
(引用自3楼)

可以用两个扇区轮流写,具体方法想必不用不多说

epwwm 发表于 2022-3-3 11:05:45

那些没EEPROM的单片机,用FLASH代用就是要这么干 。。

bigharpoon 发表于 2022-3-3 11:06:19

hjjnt2008 发表于 2022-3-3 10:51
可以用两个扇区轮流写,具体方法想必不用不多说
(引用自4楼)

这个好!按照此方法,只有1KB RAM 的MCU,也能读写32KB大扇区的Flash。{:handshake:}

simplorer 发表于 2022-3-3 11:06:42

flash的特性决定的,没有办法。
如果成本可以接受的话,可以考虑eeprom。

bigharpoon 发表于 2022-3-3 11:25:25

epwwm 发表于 2022-3-3 11:05
那些没EEPROM的单片机,用FLASH代用就是要这么干 。。
(引用自5楼)

两年之前,实验过往MCU内部Flash写数据,当时没找到好办法,改回来用外部FRAM了。
今天算是找到答案了。

modbus 发表于 2022-3-3 11:26:14

bigharpoon 发表于 2022-3-3 10:42
原来如此 。
为了写一个字节,那就需要先将扇区的内容先读到buffer,程序里修改buffer,将扇区 ...
(引用自3楼)

不但步骤多几步,可靠性也低一些,想想正在擦除期间CPU突然受干扰复位了,或者突然掉电了,整个扇区的数据就全没了

Doding 发表于 2022-3-3 11:42:38

modbus 发表于 2022-3-3 11:26
不但步骤多几步,可靠性也低一些,想想正在擦除期间CPU突然受干扰复位了,或者突然掉电了,整个扇区的数 ...
(引用自9楼)

要用2页,先写,校验完再擦。

hjjnt2008 发表于 2022-3-3 12:03:17

可以认真读一下stm32的虚拟eerpom读写操作,有效降低flash的擦写次数,延长寿命,虽然操作有相对复杂些

bigharpoon 发表于 2022-3-3 12:31:30

simplorer 发表于 2022-3-3 11:06
flash的特性决定的,没有办法。
如果成本可以接受的话,可以考虑eeprom。
(引用自7楼)

eeprom还是经典,我看网上报价已经到1两块,抵得上一颗MCU的价格了。{:mad:}

bigharpoon 发表于 2022-3-3 12:45:46

modbus 发表于 2022-3-3 11:26
不但步骤多几步,可靠性也低一些,想想正在擦除期间CPU突然受干扰复位了,或者突然掉电了,整个扇区的数 ...
(引用自9楼)

这个问题,见坛子里一些帖子讨论过。对于掉电的情况,说是用掉电检测+并联电容的方法可以解决。
具体细节好像是(但不确定):1,加掉电检测电路和电容蓄能电路。2,程序实时扫描外部电源输入情况,一旦发生掉电,因为有电容蓄能可以维持程序运行一小段时间(可能几百毫秒~1s),将需要保存的数据写入ROM。

相比掉电,擦写时发生干扰复位时的是灾难性后果。干扰电脉冲是us级别的,对于这种情况个人觉得几乎没有补救措施{:cry:}

hjjnt2008 发表于 2022-3-3 12:51:43

按stm32的例程的操作,如果存储只有几十个字节,那完全不需要每次都擦除,一个个往后写下去,等写满了一个扇区,再换一个扇区,换到第二扇区再去擦除第一扇区,这样可靠性还是有保障的

Doding 发表于 2022-3-3 13:00:03

LZ可以看一下Flashdb或ST的EEPROM Emul,拿来就能用。

simplorer 发表于 2022-3-3 14:14:41

st的emul可以看看,我用过,不过写入数据不多,而且也不是频繁写入。
主要是保存一些故障信息。

bigharpoon 发表于 2022-3-3 14:17:19

Doding 发表于 2022-3-3 13:00
LZ可以看一下Flashdb或ST的EEPROM Emul,拿来就能用。
(引用自15楼)

好滴,我看一看,谢谢支招。
原来的产品用的是FRAM,一直没问题。最近两年,因为芯片短缺和炒作,市面是充斥着大量散新货,每买一个批次的货,将近2成左右用不了。
实在是受不了劣质货的折磨,想到了spi flash和eeprom。

lyz3432 发表于 2022-3-3 14:39:11

如果关机时候程序可以知道的话,可以放到ram里面下电前写道flash里

ycheng2004 发表于 2022-3-3 14:52:32

bigharpoon 发表于 2022-3-3 14:17
好滴,我看一看,谢谢支招。
原来的产品用的是FRAM,一直没问题。最近两年,因为芯片短缺和炒作,市面是 ...
(引用自17楼)

那就用eeprom,
比FRAM便宜多了,

tomzbj 发表于 2022-3-3 16:13:19

用flash模拟eeprom也容易呀...

写入的时候从前往后, 按"伪地址:数据"的方式成对写, 读的时候从后往前查找, 找第一个匹配到的伪地址. 写满时可以用一个空闲页或者SRAM中转一下, 再擦除重写.
一般1k flash大概能提供256字节的eeprom空间, eeprom如果只是用来存点参数设置的话, 足够了.

bigharpoon 发表于 2022-3-3 18:50:52

tomzbj 发表于 2022-3-3 16:13
用flash模拟eeprom也容易呀...

写入的时候从前往后, 按"伪地址:数据"的方式成对写, 读的时候从后往前查找, ...
(引用自20楼)

先前的操作都是讲Modbus寄存器地址直接和ROM的物理地址对齐。
这个“伪地址:数据”成对写的思路不错,可以乱序写。大咖威武!

tomzbj 发表于 2022-3-4 08:56:16

bigharpoon 发表于 2022-3-3 18:50
先前的操作都是讲Modbus寄存器地址直接和ROM的物理地址对齐。
这个“伪地址:数据”成对写的思路不错,可 ...
(引用自21楼)

我是在st某个官方application note里看的...

tim4146 发表于 2022-3-4 12:48:26

tomzbj 发表于 2022-3-3 16:13
用flash模拟eeprom也容易呀...

写入的时候从前往后, 按"伪地址:数据"的方式成对写, 读的时候从后往前查找, ...
(引用自20楼)

伪地址,数据,具体是什么意思,想不明白

tomzbj 发表于 2022-3-4 14:53:51

tim4146 发表于 2022-3-4 12:48
伪地址,数据,具体是什么意思,想不明白
(引用自23楼)

你要往0x1f地址写数据0xa5 0xb3, 就直接往这个扇区的0x0000位置写个0x001f 0xa5b3
再要往0x20地址写数据0xba 0xc4, 就再往0x0004位置写0x0020 0xbac4
然后又要往0x1f地址写0xc7 0x08, 再往0x0008位置写0x001f 0xc708, 前面的不用管
这样依次往后写, 从前往后, 找到第一个全是0xff的位置就可以写了

读的时候从后往前查找, 找到第一个不是全0xff的位置, 再判断伪地址是不是你要读的地址, 是就读出来.
写满的话, 把数据全部读到sram(不要求掉电安全), 或者读到一个空闲页, 然后把原先的页擦除, 再把刚读出来的数据按上面的格式一次写回去.

不知道我说明白了没有?

lfgc 发表于 2022-3-6 21:47:31

tomzbj 发表于 2022-3-4 14:53
你要往0x1f地址写数据0xa5 0xb3, 就直接往这个扇区的0x0000位置写个0x001f 0xa5b3
再要往0x20地址写数据0 ...
(引用自24楼)

讲的非常清楚,高手!
页: [1]
查看完整版本: 一个关于往SPI Flash写数据必须擦除扇区的问题