文章目录:
目录
一、FLASH的相关背景知识
STM32的存储器分为RAM 和 ROM。
RAM为常说的内存。比如手机的内存2G 4G等等。是程序跑起来时占用的存储空间。特点是掉电数据易丢失。
ROM为常说的硬盘。比如手机的128G存储空间。特点是掉电数据不容易丢失。在STM32中FLASH 和 EEPROM都属于ROM的范围
二、FLASH的基本操作流程
STM32的基本操作流程:
- 解锁FLASH。
- 擦除FLASH.
- 写入FLASH.
- 上锁FLASH.
FLASH的常见操作函数:
1、FLASH擦除函数:
FLASH_Status FLASH_ErasePage(u32 Page_Address)
只要()里面的数是flash第xx页中对应的任何一个地址!就是擦除xx页全部内容! |
FLASH容量大于512K则为大容量,小于512K则为小容量。对大容量FLASH擦除则擦除2k,小容量则擦除1k. |
函数内部有区分是擦除2k,还是擦除1k,因此直接调用封装即可。 |
2、Flash写入函数:
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data); //32位字写入函数
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); //16位半字写入函数
FLASH的写入地址必须是偶数(FLASH机制决定的FLASH写入的时候只能是偶数地址写入,必须写入半字或字,也就是2个字节或是4字节的内容)
3、Flash的读取方法
*(uint32_t *)0x8000000;//读一个字
*(uint8_t *)0x8000000;//读一个字节;
*(uint16_t *)0x8000000;//读半字;
4、几个有用的子函数
/*
功能:向指定地址写入数据
参数说明:addr 写入的FLASH页的首地址
p 被写入变量的地址(数组中的必须是uint8_t类型,元素个数必须是偶数)
Byte_Num 被写入变量的字节数(必须是偶数)
*/
void FLASH_WriteByte(uint32_t addr , uint8_t *p , uint16_t Byte_Num)
{
uint32_t HalfWord;
Byte_Num = Byte_Num/2;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASH_ErasePage(addr);
while(Byte_Num --)
{
HalfWord=*(p++);
HalfWord|=*(p++)<<8;
FLASH_ProgramHalfWord(addr, HalfWord);
addr += 2;
}
FLASH_Lock();
}
例:
uint8_t data[100];
FLASH_WriteByte(0x8000000 , data , 100);/*数组data的数据被写入FLASH中*/
/*
功能:从指定地址读取数据
参数说明:addr 从FLASH中读取的地址
p 读取后要存入变量的地址(数组中的必须是uint8_t类型)
Byte_Num 要读出的字节数
*/
void FLASH_ReadByte(uint32_t addr , uint8_t *p , uint16_t Byte_Num)
{
while(Byte_Num--)
{
*(p++)=*((uint8_t*)addr++);
}
}
例:
uint8_t data[101];
FLASH_ReadByte(0x8000001 , data , 101);/*FLASH中的数据被读入数组data中*/
三、项目中遇到的FLASH操作的问题
在做IAP项目时,参考了原子的IAP关于FLASH的写入函数,同时也参考了网上其他的工程,在进入download函数 功能之前,如果解锁Flash后直接调用FLASH的半字写入函数,后边再进入download函数之后执行flash的擦除、写入都不会成功。只有在第一次写入之前先进行该扇区的擦除,后边download中的关于flash的操作才会成功。