在 STM32 芯片内部有一个 FLASH 存储器,它主要用于存储代码,我们在电脑上编写好应用程序后,使用下载器把编译后的代码文件烧录到该内部 FLASH 中,由于 FLASH 存储器的内容在掉电后不会丢失,芯片重新上电复位后,内核可从内部 FLASH 中加载代码并运行,见图 STM32 的内部框架图 。
除了使用外部的工具(如下载器)读写内部 FLASH 外,STM32 芯片在运行的时候,也能对自身的内部 FLASH 进行读写,因此,若内部 FLASH 存储了应用程序后还有剩余的空间,我们可以把它像外部 SPI-FLASH 那样利用起来,存储一些程序运行时产生的需要掉电保存的数据。
1.1 内部 FLASH 的构成
STM32 的内部 FLASH 包含主存储器、系统存储器以及选项字节区域,它们的地址分布及大小见表 STM32 大容量产品内部 FLASH 的构成
各个存储区域的说明如下:
(1)主存储
一般我们说 STM32 内部 FLASH 的时候,都是指这个主存储器区域,它是存储用户应用程序的空间,芯片型号说明中的 256K FLASH、512K FLASH 都是指这个区域的大小。
关于 STM32 内部 FLASH 的容量类型可根据它的型号名获知,见表 STM32 芯片的命名规则 。
(2)系统存储区
系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、USB以及 CAN 等 ISP 烧录功能。
(3)选项字节
选项字节用于配置 FLASH 的读写保护、待机/停机复位、软件/硬件看门狗等功能,这部分共 16字节。可以通过修改 FLASH 的选项控制寄存器修改。
对 FLASH 写入数据前,需要先给它解锁。解锁的操作步骤如下:
(1) 往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY1 = 0x45670123
(2) 再往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY2 = 0xCDEF89AB
页擦除的过程如下:
(1) 检查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以确认当前未执行任何 Flash 操作;
(2) 在 FLASH_CR 寄存器中,将“激活页擦除寄存器位 PER ”置 1,
(3) 用 FLASH_AR 寄存器选择要擦除的页;
(4) 将 FLASH_CR 寄存器中的“开始擦除寄存器位 STRT ”置 1,开始擦除;
(5) 等待 BSY 位被清零时,表示擦除完成。
擦除完毕后即可写入数据,写入数据的过程并不是仅仅使用指针向地址赋值,赋值前还还需要配置一系列的寄存器,步骤如下:
(1) 检查 FLASH_SR 中的 BSY 位,以确认当前未执行任何其它的内部 Flash 操作;
(2) 将 FLASH_CR 寄存器中的“激活编程寄存器位 PG”置 1;
(3) 向指定的 FLASH 存储器地址执行数据写入操作,每次只能以 16 位的方式写入;
(4) 等待 BSY 位被清零时,表示写入完成。
(1) 对内部 FLASH 解锁;
(2) 找出空闲页,擦除目标页;
(3) 进行读写测试;
1.硬件定义
2.读写内部 FLASH
(1) 调用 FLASH_Unlock 解锁;
(2) 根据起始地址及结束地址计算要擦除多少页;
(3) 调用 FLASH_ClearFlag 清除各种标志位;
(4) 使用循环调用 FLASH_ErasePage 擦除页,每次擦除一页;
(5) 使用循环调用 FLASH_ProgramWord 函数向起始地址至结束地址的存储区域都写入变量“Data”存储的数值数值;
(6) 调用 FLASH_Lock 上锁;
(7) 使用指针读取写入的数据内容并校验。
3.main 函数
main.c
*/
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./led/bsp_led.h"
#include "./internal_flash/bsp_internal_flash.h"
// 函数原型声明
void Delay(__IO uint32_t nCount);
/*
* 函数名:main
* 描述 :主函数
* 输入 :无
* 输出 :无
*/
int main(void)
{
/*初始化USART,配置模式为 115200 8-N-1*/
USART_Config();
LED_GPIO_Config();
LED_BLUE;
printf("\r\n 欢迎使用野火 STM32 开发板。\r\n");
printf("正在进行读写内部FLASH实验,请耐心等待\r\n");
if(InternalFlash_Test()== PASSED)
{
LED_GREEN;
printf("读写内部FLASH测试成功\r\n");
}
else
{
printf("读写内部FLASH测试失败\r\n");
LED_RED;
}
while(1)
{ }
}
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
/*********************************************END OF FILE**********************/
其他配置: