【STM32标准库】读写内部FLASH

1.内部FLASH的构成

STM32F407的内部FLASH包含主存储器、系统存储器、OTP区域以及选项字节区域。

在这里插入图片描述

一般我们说STM32内部FLASH的时候,都是指这个主存储器区域,它是存储用户应用程序的空间。STM32F407ZGT6型号芯片, 它的主存储区域大小为1MB。其中包含4个16KB扇区、1个64KB扇区和7个128KB的扇区。

  • 系统存储区

系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、USB以及CAN等ISP烧录功能。

  • OTP区域

OTP(One Time Program),指的是只能写入一次的存储区域,容量为512字节,写入后数据就无法再更改,OTP常用于存储应用程序的加密密钥。

  • 选项字节

选项字节用于配置FLASH的读写保护、电源管理中的BOR级别、软件/硬件看门狗等功能,这部分共32字节。可以通过修改FLASH的选项控制寄存器修改。

2.对内部FLASH的写入过程

2.1解锁

由于内部FLASH空间主要存储的是应用程序,是非常关键的数据,为了防止误操作修改了这些内容,芯片复位后默认会给FLASH上锁, 这个时候不允许设置FLASH的控制寄存器,并且不能对修改FLASH中的内容。

所以对FLASH写入数据前,需要先给它解锁。解锁的操作步骤如下:

(1) 往Flash 密钥寄存器 FLASH_KEYR中写入 KEY1 = 0x45670123

(2) 再往Flash 密钥寄存器 FLASH_KEYR中写入 KEY2 = 0xCDEF89AB

2.2数据操作位数

在内部FLASH进行擦除及写入操作时,电源电压会影响数据的最大操作位数,该电源电压可通过配置FLASH_CR 寄存器中的 PSIZE位改变,见表 数据操作位数

数据操作位数

最大操作位数会影响擦除和写入的速度,其中64位宽度的操作除了配置寄存器位外,还需要在Vpp引脚外加一个8-9V的电压源, 且其供电时间不得超过一小时,否则FLASH可能损坏,所以64位宽度的操作一般是在量产时对FLASH写入应用程序时才使用,大部分应用场合都是用32位的宽度。

2.3擦除扇区

在写入新的数据前,需要先擦除存储区域,STM32提供了扇区擦除指令和整个FLASH擦除(批量擦除)的指令,批量擦除指令仅针对主存储区。

扇区擦除的过程如下:

(1) 检查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以确认当前未执行任何 Flash 操作;

(2) 在 FLASH_CR 寄存器中,将“激活扇区擦除寄存器位SER ”置 1,并设置“扇区编号寄存器位SNB”,选择要擦除的扇区;

(3) 将 FLASH_CR 寄存器中的“开始擦除寄存器位 STRT ”置 1,开始擦除;

(4) 等待 BSY 位被清零时,表示擦除完成。

2.4写入数据

擦除完毕后即可写入数据,写入数据的过程并不是仅仅使用指针向地址赋值,赋值前还还需要配置一系列的寄存器,步骤如下:

(1) 检查 FLASH_SR 中的 BSY 位,以确认当前未执行任何其它的内部 Flash 操作;

(2) 将 FLASH_CR 寄存器中的 “激活编程寄存器位PG” 置 1;

(3) 针对所需存储器地址(主存储器块或 OTP 区域内)执行数据写入操作;

(4) 等待 BSY 位被清零时,表示写入完成。

3.查看工程的空间分布

在这里插入图片描述

在上面map文件的描述中,我们了解到加载及执行空间的基地址(Base)都是0x08000000,它正好是STM32内部FLASH的首地址, 即STM32的程序存储空间就直接是执行空间;它们的大小(Size)分别为0x00001ae4及0x00001ab4, 执行空间的ROM比较小的原因就是因为部分RW-data类型的变量被拷贝到RAM空间了;它们的最大空间(Max)均为0x00100000,即1M字节,它指的是内部FLASH的最大空间。计算程序占用的空间时,需要使用加载区域的大小进行计算,本例子中应用程序使用的内部FLASH是从0x08000000至(0x08000000+0x00001ae4)地址的空间区域。所以,一个扇区的大小就够了。

4.FLASH读写实验

#ifndef __BSP_INTER_FLASH_H
#define __BSP_INTER_FLASH_H

#ifdef __cplusplus
extern "C"{

#endif

#include "stm32f4xx.h"


#define TEST_FLASH_SECTION            FLASH_Sector_1 //这里用或操作直接两块section好像不太行
#define TEST_FLASH_BASE_ADDRESS       0x08004000
#define TEST_FLASH_SIZE               16*1024
#define TEST_FLASH_DATA               0x5a5aa5a5 


void inter_flash_test(void);
#ifdef __cplusplus
}
#endif

#endif


#include "bsp_inter_flash.h"
#include "stdio.h"

void inter_flash_test()
{
	//1.解锁  2.擦除  3.写入  4.上锁  5.读取
	FLASH_Status status = FLASH_COMPLETE;
	
	FLASH_Unlock();

	status=FLASH_EraseSector(TEST_FLASH_SECTION,VoltageRange_3);
	if(FLASH_COMPLETE==status)
	{
		printf("FLASH_EraseSector OK\r\n");
	}
	
	for(int i=0;i<TEST_FLASH_SIZE;i+=4)
	{
		status=FLASH_ProgramWord(TEST_FLASH_BASE_ADDRESS+i,TEST_FLASH_DATA);
		if(FLASH_COMPLETE==status)
	    {
		     printf("FLASH_ProgramWord OK\r\n");
	    }
	}
	
	FLASH_Lock();
	
	__IO uint32_t* addr=(__IO uint32_t*)TEST_FLASH_BASE_ADDRESS;
	for(int i=0;i<TEST_FLASH_SIZE;i+=4)
	{
		if(TEST_FLASH_DATA!=*(addr++))
		{
			printf("TEST_FLASH_DATA ERROR\r\n");
		}
	}
}


  • 21
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值