“ 有时候需要对一些数据进行掉电可存储,一般来说可以把这些数据存储到外部EEPROM或FLASH,如AT24CXX、SPI FLASH等。对于一些不需要经常写入的少量数据,可以直接存储到单片机内部FLASH,可以节省成本。”
前期准备
- STM32硬件电路板及仿真器(以STM32F072单片机为例)
Keil v5以上版本(MDK-ARM)
01
—
FLASH读写流程
FLASH不用于EEPROM等存储器,可以任意字节写入。FLASH存储器写入数据时,每一位只能由“1”变成“0”,不能由“0”变成“1“,因此,当我们有数据要保存到FLASH存储器时,要先对目标段进行整段擦除操作,擦除操作使对应段FLASH存储器变成全“1”,再对需要的位写为“0”,即完成写入操作。
具体到STM32内部FLASH,每次擦除操作最小单位为1个扇区,不同型号的单片机扇区大小也不一样,STM32F072C8T6的扇区大小为2K字节,其起始地址为0x08000000。
具体的读写操作流程如下:
- 对FLASH写入数据
- 解锁FLASH
- 擦除FLASH
- 写入数据到FLASH
- 锁住FLASH
- FLASH读取数据
- 直接读取相应的FLASH地址
02
—
代码编写
FLASH读写不需要对STM32CubeMX进行特殊配置,直接调用HAL相关函数即可,编写读写函数如下:
uint16_t WriteFlash(uint32_t start_Add,uint32_t end_Add,uint32_t *data)
{
uint32_t i;
uint8_t j=0;
uint32_t PageError;
FLASH_EraseInitTypeDef f;
f.TypeErase = FLASH_TYPEERASE_PAGES;
f.PageAddress = START_ADDRESS;
f.NbPages = 1;
PageError = 0;
HAL_FLASH_Unlock();
HAL_FLASHEx_Erase(&f, &PageError);
data = (uint32_t*)(&Saved_Param);
for(i = START_ADDRESS; i < END_ADDRESS; i += 4)
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, i, data[j++]);
}
HAL_FLASH_Lock();
}
uint8_t ReadFlash (uint32_t start_Add,uint32_t end_Add,uint32_t *data)
{
uint32_t i;
uint8_t j=0;
for(i = start_Add; i < end_Add; i += 4)
{
data[j++]=*(uint32_t *)(i);
}
return HAL_OK;
}
函数调用方式如下:
0x08080000,0x08080010,dat);
0x08080000,0x08080010,dat);
需要注意的是,FLASH读写地址必须都是4的整数倍。