《《《《《正文》》》》》
《FLASH的缺点》
说到flash大家可能更加熟悉eeprom,典型的有24Cxx,eeprom的操作没有什么限制,想写就写,想读就读,不用擦除,数据都可以覆盖,而且支持字节操作,一般的擦写次数都达到了百万级别,下面是24Cxx的参数:
而内部flash的操作限制就多了,写操作之前必须擦除操作,擦除操作也是有最小单位限制的;flash的擦写次数一般很少,而且因为是块擦除,擦除也很耗时间,例子参数如下图:
《FLASH的操作规则》
(自己总结的白话,与官方冲突的,请以官方为准)
1、读操作没有限制;支持字节、半字、字读操作。
不完全代码如下:
//读字
data = *(__IO uint32_t*)Address;
//读半字
data = *(__IO uint16_t*)Address;
//读字节
data = *(__IO uint8_t*)Address;
2、写操作只能将1写成0,不能将0写成1;支持字节、半字、字写操作。
不完全代码如下:
*((volatile uint8_t*)u32Addr) = u8Data; //写字节
*((volatile uint16_t*)u32Addr) = u16Data; //写半节
*((volatile uint32_t*)u32Addr) = u32Data; //写节
也正是因为这条限制,所以我们的写操作,数据是不会被覆盖,只会按这条规则重叠数据,如下实例:
某一字节的地址上,从未操作过的FALSH 的值均为0xFF,内存图:
0xFF | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
写入0x55,得到0x55,内存图:
(红色为规则生效,黑色规则不生效)
0xFF | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
0x55 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
0x55 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
再写入0xAA,得到0x00,内存图:
(红色为规则生效,黑色规则不生效)
0x55 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
0xAA | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
0x00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
FLASH数据为0x00后,之后写任何数据根据该规则都会是0x00,除非擦除操作,也就是第3条规则;
3、擦除操作的最小单位一般为块大小,大小有芯片自己决定,一般有512bit也有1k的,且擦除后均为0xFF,擦除之后就又可以操作了;这就是为什么写操作之前需要擦除操作的原因;
《为什么还要使用flash》
主要因素有以下几个:
第一:有些项目的存储数据的改变频率并不频繁,这样flash在寿命上就会满足要求,eeprom的百万级别擦写次数优势就荡然无存;
第二、对于存储速度要求不是非常高的情况下,在硬件上稍作掉电处理的电路,在加上软件对掉电的处理,就能保证掉电的瞬间数据能够有足够的时间被正确存储,这样flash的擦除操作耗时的问题就解决了。
第三、成本问题;个人觉得这个还是主要原因,花了全部钱的MCU,多出来的flash干嘛不用?Eeprom的话就要增加成本了,FLASH从某种意义上讲,0成本;
《FLASH在软件上的一些建议》
1、软件做备份,建议2分备份,一份使用,具体逻辑后续有机会分享;
2、软件做电源管理模块,电压不稳是导致擦写不成功的重要因素之一,因此需要在异常电压时,停止擦写,保证数据的正确性;
3、为了掉电存储速度,可以在上电时先做擦除操作,掉电的时候写操作,平时数据放在ram中,这样可以提高掉电时的存储速度;
《《《《《END》》》》》