基础知识
为了使用Stm32自带的存储器实现数据的掉电保持,可以操作Flash区域,对Flash写入时先要解锁,擦除,写入,锁上。
任何时候对任何型号的STm32都是这些操作,Flash中的内存分页,修改一页的内容中内容时,不支持只修改一部分,所以修改前要将整页擦除擦除数据。
起始地址:0x08000000 + 页号×1024×2。
可以在程序的map文件查看目前使用的内存大小
flash.h
代码片
.
// flash.h
#ifndef _FLASH_H_
#define _FLASH_H_
#include "config.h"
extern uint32_t Flashaddr;
void writeFlashTest(uint32_t writeFlashaddr,uint32_t *writeFlashData,uint32_t writeFlashLen);//FLASH写入数据
uint32_t readFlashTest(uint32_t writeFlashaddr); //FLASH读取数据
#endif
#flash.c
代码片
.
// flash.c
#include "flash.h"
#include "SEGGER_RTT.h"
uint32_t Flashaddr = 0x0801E000; // Adress = 1024*page*2+base
void writeFlashTest(uint32_t writeFlashaddr,uint32_t *writeFlashData,uint32_t writeFlashLen)//FLASH写入数据
{
HAL_FLASH_Unlock(); //解锁FLASH
FLASH_EraseInitTypeDef f; //初始化FLASH_EraseInitTypeDef
f.TypeErase = FLASH_TYPEERASE_PAGES;//标明Flash执行页面只做擦除操作
f.Page = 60; //声明要擦除的地址页数
f.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
HAL_FLASHEx_Erase(&f, &PageError); //调用擦除函数
if (HAL_FLASHEx_Erase(&f, &PageError) != HAL_OK)
{
HAL_FLASH_Lock();
SEGGER_RTT_printf(0,"Erro1 1\n\r");
}
else
{
SEGGER_RTT_printf(0,"erase is ok = d% \n\r",PageError);
}
u16 i=0;
Flashaddr = 0x0801E000;
while ( i<writeFlashLen )
{
HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, Flashaddr, writeFlashData[i]); //对FLASH烧写
SEGGER_RTT_printf(0, "addr:0x%x, data:0x%x\r\n", Flashaddr,writeFlashData[i]);
Flashaddr = Flashaddr + 8; //TYPEPROGRAM_DOUBLEWORD,所以地址后移8个字节
i++;
} //可以在此处判断是否写入成功
HAL_FLASH_Lock(); //锁住FLASH
}
uint32_t readFlashTest(uint32_t writeFlashaddr) //FLASH读取数据
{
uint32_t readFlashData = *(__IO uint32_t*)(writeFlashaddr); //*(__IO uint16_t *)是读取该地址的参数值,其值为16位数据,一次读取两个字节,*(__IO uint32_t *)就一次读4个字节
return readFlashData;
}
注意事项
1,Flashaddr = Flashaddr + 8; //TYPEPROGRAM_DOUBLEWORD,所以地址后移8个字节
2,注意起始地址和页数的配合。