STM32 使用 Flash 存储数据时的一种管理办法
以上三点对于实际使用时的影响,首先,写数据必须以 16bit 为单位,很多 32bit 长度的值就不能直接使用类似 A = B 的赋值语句的方法去操作了,可以统一转化为指向 16bit 无符号整形值的指针来处理。举例,有一个 32bit 长度的 float 变量 v_float,要存入地址为 (FLASH_ADDRESS)的 flash中:
#define FLASH_ADDRESS (0x0803F800)
if(FLASH->CR &= FLASH_CR_LOCK) //解锁flash
{
FLASH->KEYR = (FLASH_KEYR_FKEYR & FLASH_KEY1);
FLASH->KEYR = (FLASH_KEYR_FKEYR & FLASH_KEY2);
while(FLASH->CR & FLASH_CR_LOCK);
}
while(FLASH->SR &= FLASH_SR_BSY);
FLASH->CR |= FLASH_CR_PG; //功能选择,写flash
{
*((unsigned short *)(FLASH_ADDRESS) + 0 ) = *((unsigned short *)(&v_float) + 0 );
*((unsigned short *)(FLASH_ADDRESS) + 1 ) = *((unsigned short *)(&v_float) + 1 );
}
FLASH->CR &= ~FLASH_CR_PG;
FLASH->CR |= FLASH_CR_LOCK; //锁flash
如果需要读取写入到 flash 中的浮点数到 ram 中的变量 a_float,使用如下语句:
a_float = *((float *) FLASH_ADDRESS);
这样,写入和读取就完成了,下面是擦除,按照参考手册的流程来就可以了:
if(FLASH->CR &= FLASH_CR_LOCK) //解锁flash
{
FLASH->KEYR = (FLASH_KEYR_FKEYR & FLASH_KEY1);
FLASH->KEYR = (FLASH_KEYR_FKEYR & FLASH_KEY2);
while(FLASH->CR & FLASH_CR_LOCK);
}
while(FLASH->SR &= FLASH_SR_BSY); //Wait until flash not busy
FLASH->CR |= FLASH_CR_PER; //功能选择,擦除页
FLASH->AR = FLASH_ADDRESS; //写入flash地址
FLASH->CR |= FLASH_CR_STRT; //开始擦除
while(FLASH->SR &= FLASH_SR_BSY); //等待
if(FLASH->SR &= FLASH_SR_EOP)
{
FLASH->SR |= FLASH_SR_EOP; //重置EOP
}
FLASH->CR &= ~FLASH_CR_PER;
FLASH->CR |= FLASH_CR_LOCK; //锁flash
以上代码会擦除 FLASH_ADDRESS 所在的整个 flash 页。
实现少量数据的读写和擦除操作以后,下一步要开始组织 flash 中存储的数据,这样以后阅读和修改都更为方便,我使用类似 stm32 官方寄存器配置文件的方式,用结构体来组织。假设我要将某个人的个人信息储存在 flash 中地址为(FLASH_ADDRESS)的位置,包括:姓名、性别、身高、体重,代码如下:
typedef struct //构造结构体
{
unsigned char name[16];
unsigned char male;
float height;
float weight;
}Personal_Information_TypeDef;
#define FLASH_ADDRESS (0x0803F800) //flash地址
#define Personal_Data ((Personal_Information_TypeDef *) FLASH_ADDRESS )
以上代码在起始地址为(FLASH_ADDRESS)的 flash 中,定义了用于储存个人信息的结构体指针 Personal_Data,也就是说 Personal_Data 这个指针的值就是 FLASH_ADDRESS,只不过除了这个指针的值以外,我们还定义了这个指针所指向的数据的结构。要读出这些储存于 flash 中的值,使用读取结构体指针的方式:
Temp_variable = Personal_Data -> male;
写 flash 的时候,因为每次只能写 16bit,所以除了 short 类型以外,类似 int 和 float 这种 32bit 的数据,都要取地址强制转化为 16bit 类型后再取值最后写入,方法类似一开始的 float 类型数据写入 flash 的操作。我为了操作方便,在 ram 中建立了一个和 flash 内结构相同的结构体,每次需要写入 flash 的时候,就将 ram 中结构体的所有值全部写入 flash:
typedef struct //构造结构体
{
unsigned char name[16];
unsigned char male;
float height;
float weight;
}Personal_Information_TypeDef;
#define Length (5) //结构体总长(16bit单位)
#define FLASH_ADDRESS (0x0803F800) //flash地址
#define Personal_Data ((Personal_Information_TypeDef *) FLASH_ADDRESS )
Personal_Information_TypeDef Personal_Data_Mirror; //ram中的结构体
/* 写入过程 */
(unsigned short *)WriteAddress = (unsigned short *)Personal_Data;
(unsigned short *)ReadAddress = (unsigned short *)(&Personal_Data_Mirror);
if(FLASH->CR &= FLASH_CR_LOCK) //解锁flash
{
FLASH->KEYR = (FLASH_KEYR_FKEYR & FLASH_KEY1);
FLASH->KEYR = (FLASH_KEYR_FKEYR & FLASH_KEY2);
while(FLASH->CR & FLASH_CR_LOCK);
STM32Flash存储数据管理办 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)