2021.1.31
本文使用HAL库中的函数进行Flash的读写操作。
1.Flash简介
Flash就是关于平常程序储存的地方,而sram一般是存放变量的地方。Flash中的数据不会因为断电而丢失,SRAM则会。
-
为了保护数据的安全,Flash有安全锁,对Flash写入时先要解锁,擦除,写入,锁上。任何时候对任何型号的STm32都是这些操作
- Flash中的内存分页,修改一页的内容中内容时,不支持只修改一部分,所以修改前要将整页擦除
- 擦除数据,就是将整页数据变成1,而数据一16位的形式保存在Flash中,因此观察寄存器可以看见擦写过后的Flash的地址位0xFF。
- 地址是32位
2.Flash的解锁和锁上函数
HAL_FLASH_Lock();
/****用户操作********/
HAL_FLASH_Unlock();
3.flash的擦除函数
创建错误返回参数 (参数2)
uint32_t FlashError=0;
正确擦除后,FlashError因该会返回值FFFFFFFF
4.flash写入函数
参数1为,写入数据的类型(8/16/32/64位)
参数2为,开始写入地址
参数3为,要写入的地址
5.读取函数
自己建立一个函数,里面通过函数memcpy()进行复制
简单介绍以下memcpy()函数
注意到,
参数1为,数据需要复制到的地址
参数2为,数据原来所在的地址
参数3为,需要 复制的字节,对是字节,这就说明,不论,前两个参数是说明类型,这个函数就复制相应个字节数据,有很强的适用性。
6.创建工程
STM32C'ubeMX中直接生成一个工程即可
7.代码实现
首先要确定需要写入的地址:博主使用的STM32f103ZET6,512kFLASH内存,(不同型号的地址不同,自行在下面表中查找,这是STM32f10XX的,其他型号,在对应手册中应该有)照表选用最后一页的地址,防止对存在前面的程序产生影响。
uint32_t address=0x0807E000;
下面是将字符串写进Flash中的代码
注意以下几点
-
字符串为8位数据,需要转化成32位类型,去接受数据。
-
写入数据的时候,每写完一个数据,地址要前移,数组也要前移。
#define MAX 8//数据长度
uint8_t Bf_date[MAX]="dawn_zs";//数据
uint8_t Af_date[MAX];//读取数据的数组
uint32_t address=0x0807E000;//地址
uint32_t FlashError=0;//擦除的反馈void printfflash(void)//读取并打印,需要重定向printf,并且在建立工程的时候勾选一个串口
{
memcpy((uint32_t *)Af_date,(void*)address,MAX);
printf("%s",Af_date);}
void FLASHWRITER(uint32_t addr,uint32_t* pdate, uint32_t len)//读数据函数
{
uint32_t i=0;
for(;i<len;i++)// i个32位数据
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,addr,*pdate);
addr+=4;//32位为4个字节所以地址加4
pdate++;//因为为32位数组所以加1就行
}}
void FLASH_init(void){
HAL_FLASH_Unlock();
FLASH_EraseInitTypeDef FlashSet;
FlashSet.TypeErase=FLASH_TYPEERASE_PAGES;
FlashSet.PageAddress=address;
FlashSet.NbPages=1;
printfflash();
HAL_FLASHEx_Erase(&FlashSet,&FlashError);
printfflash();
FLASHWRITER(address,(uint32_t*)Bf_date,MAX/4);
printfflash();HAL_FLASH_Lock();
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
FLASH_init();
while (1)
{
}
}