stm32读写flash

通常情况下我们的32的flash不会被占满,这时候我们可以用32的flash存储一些我们不希望在掉电时候会丢的数据。
在这里我使用的芯片时stm32f103zet6。flash大小为512k。
由keil编译器我们可以看到该芯片的内部flash起始地址为0x08000000,大小为0x80000。内部RAM的起始地址为0x20000000,大小为0x10000。这个是在我们选择芯片型号是编译器自动帮我们加载的,一般情况下无需修改。
stm32读写flash_第1张图片
确定了flash的大小及地址,我们还需要知道我们该往哪里写入我们要储存的数据。一般情况下flash的起始部分会存储程序。我们存入的数据必须在程序占用不到的地方。keil编译环境下编译后会生成一个map格式文件,默认储存在Listing文件夹里。打开这个文件可以看到我们的RAM和ROM使用情况。在这里我的程序只用到了0x080039b0。可见我的代码很小,才用到了flash几十分之一,即使如此我们在一般情况下在储存数据时也要在flash的最后开始使用。这样可以方便我们的代码扩展。而且一般情况下我们也不需要存储大量的数据,如果存储大量数据还是要扩充片外flash。
stm32读写flash_第2张图片
在ST官方库中提供了页擦除的函数,所以我们还需要知道flash的内部分页情况。stm32系列产品根据内存大小不同,分页方式也有所不同。下图是stm32f103zet6的内部flash分页情况。
stm32读写flash_第3张图片
说了这么多,究竟该如何进行flash读写呢?下面上代码。

FLASH_Unlock();       //解锁flash
FLASH_ErasePage(0x08060000);    //擦除指定页
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); //清除标志位
FLASH_ProgramWord(0x08060000,0x0001);    //在指定的地址写入数据
FLASH_Lock();     //锁flash
int val=*((volatile int *)(0x08060000));       //读出指定地址的数

这是一段简单的flash读写代码,下面我们将其封装成函数。
//读取指定地址的半字(16位数据)
//faddr:读地址(此地址必须为2的倍数!!)
//返回值:对应数据.

//读取指定地址的半字(16位数据)
//faddr:读地址(此地址必须为2的倍数!!)
//返回值:对应数据.
u16 STMFLASH_ReadHalfWord(u32 faddr)
{
    return *(vu16*)faddr; 
}

//不检查的写入
//WriteAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数
void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   
{                    
    u16 i;
    for(i=0;i2;//地址增加2.
    }  
} 

//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数
void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)     
{
    u16 i;
    for(i=0;i//读取2个字节.
        ReadAddr+=2;//偏移2个字节.   
    }
}

注意:
1、 写flash之前一定要先解锁
2、写之前一定擦除,擦除后全为1

博客代码部分摘自正点原子,如有侵权请告知。

你可能感兴趣的:(stm32)