STM32F1之内部FLASH存储

 

目录

1.  FLASH简介

1.1  存储器映像

1.2  读写FLASH的用途

1.3  闪存容量

1.3.1  命名规则

1.3.2  闪存模块组织

1.4  FLASH基本结构

1.5  FLASH解锁

1.6  使用指针访问存储器

1.6.1  使用指针读指定地址下的存储器

1.6.2  使用指针写指定地址下的存储器

1.7  闪存全擦除过程

1.8  闪存页擦除过程

1.9  程序存储器编程

1.10  选项字节

2.  STM32代码编写

2.1  FLASH读取一个32位的字

2.2  FLASH读取一个16位的半字

2.3  FLASH读取一个8位的字节

2.4  FLASH全擦除

2.5  FLASH页擦除

2.6  FLASH编程字

2.7  FLASH编程半字


1.  FLASH简介

1.1  存储器映像

        STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程。

类型起始地址存储器用途
ROM0x0800 0000程序存储器Flash存储C语言编译后的程序代码
0x1FFF F000系统存储器存储C语言编译后的程序代码
0x1FFF F800选项字节存储一些独立于程序代码的配置参数
RAM0x2000 0000运行内存SRAM存储运行过程中的临时变量
0x4000 0000运行内存SRAM存储各个外设的配置参数
0xE000 0000内核外设寄存器存储内核各个外设的配置参数

1.2  读写FLASH的用途

(1)利用程序存储器的剩余空间来保存掉电不丢失的用户数据     

(2)通过在程序中编程(IAP),实现程序的自我更新


        在线编程(In-Circuit Programming – ICP)用于更新程序存储器的全部内容,它通过JTAG、SWD协议或系统加载程序(Bootloader)下载程序。

        在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任一种通信接口下载程序。


1.3  闪存容量

1.3.1  命名规则

        我们先来了解一下STM32系列的命名规则:

对于STM32F1系列闪存存储容量:

小容量:16K和32K字节的闪存

中容量:64K和128K字节的闪存

大容量:256K、348K和512K字节的闪存

1.3.2  闪存模块组织

(1)小容量

(2)中容量

(3)大容量

        其中,对于信息块分为两部分:

系统存储器(启动程序代码):是用于存放在系统存储器自举模式下的启动程序,这个区域只保留给ST使用,启动程序使用USART1串行接口实现对闪存存储器的编程;ST在生产线上对这个区域编程并锁定以防止用户擦写。

用户选择字节:选项字节。

注意:

  • 对于主存储器,擦除和写入是以页为单位的;
  • 写入前必须擦除;
  • 擦除必须以最小单位进行
  • 擦除后数据位全变为1
  • 数据只能1写0,不能0写1
  • 擦除和写入都需要等待忙

1.4  FLASH基本结构

        以C8T6为例:

1.5  FLASH解锁

FPEC共有三个键值:
        RDPRT键 = 0x000000A5
        KEY1 = 0x45670123
        KEY2 = 0xCDEF89AB

解锁:
        复位后,FPEC被保护,不能写入FLASH_CR
        在FLASH_KEYR先写入KEY1,再写入KEY2,解锁
        错误的操作序列会在下次复位前锁死FPEC和FLASH_CR

加锁:
        设置FLASH_CR中的LOCK位锁住FPEC和FLASH_CR

1.6  使用指针访问存储器

1.6.1  使用指针读指定地址下的存储器

uint16_t Data = *((__IO uint16_t *)(0x08000000));

(0x08000000):这是一个十六进制的地址值。上面我们也说了,STM32F1系列的起始地址为0x08000000,如果想要别的地址下的数据则可以对其进行更改。

(__IO uint16_t *):这是一个类型转换,将前面的地址值(0x08000000)强制转换为一个指向__IO uint16_t类型的指针。如果想要转变其他类型的数据可以将uint16_t更改为及其他的如:uint8_t、uint32_t、float或者double等。

#define    __IO    volatile

__IO:在这里是一个宏定义,用于表示该指针所指向的内存区域具有特定的访问属性,与 volatile 关键字相关,意味着该内存位置的值可能会被硬件或其他异步操作修改,编译器不会对其进行优化,每次访问都从内存中读取实际值。

1.6.2  使用指针写指定地址下的存储器

*((__IO uint16_t *)(0x08000000)) = 0x1234;

1.7  闪存全擦除过程

        首先判断有没有被锁住,锁住执行解锁过程,没解锁继续运行,不过对于STM32给的库函数并没有这层判断,库函数直接执行解锁过程,管你锁没锁都解一次:

        解锁完成后置,控制寄存器的MER位为1,在置STRT为1,STRT位是开始位,当开始运行,发现MER位为1,则开始执行全擦除:

        然后擦除等待:

1.8  闪存页擦除过程

        该过程与全擦除类似:

1.9  程序存储器编程

        解锁:

        置控制寄存器的PG位为1,表示即将写入数据:

        以半字写入数据(只能以半字写入):

字:32位数据

半字:16位数据

字节:8位数据

        等待忙:

1.10  选项字节

  • RDP:写入RDPRT键(0x000000A5)后解除读保护
  • USER:配置硬件看门狗和进入停机/待机模式是否产生复位
  • Data0/1:用户可自定义使用
  • WRP0/1/2/3:配置写保护,每一个位对应保护4个存储页(中容量)

2.  STM32代码编写

2.1  FLASH读取一个32位的字

/**
  * 函    数:FLASH读取一个32位的字
  * 参    数:Address 要读取数据的字地址
  * 返 回 值:指定地址下的数据
  */
uint32_t MyFLASH_ReadWord(uint32_t Address)
{
	return *((__IO uint32_t *)(Address));	//使用指针访问指定地址下的数据并返回
}

2.2  FLASH读取一个16位的半字

/**
  * 函    数:FLASH读取一个16位的半字
  * 参    数:Address 要读取数据的半字地址
  * 返 回 值:指定地址下的数据
  */
uint16_t MyFLASH_ReadHalfWord(uint32_t Address)
{
	return *((__IO uint16_t *)(Address));	//使用指针访问指定地址下的数据并返回
}

2.3  FLASH读取一个8位的字节

/**
  * 函    数:FLASH读取一个8位的字节
  * 参    数:Address 要读取数据的字节地址
  * 返 回 值:指定地址下的数据
  */
uint8_t MyFLASH_ReadByte(uint32_t Address)
{
	return *((__IO uint8_t *)(Address));	//使用指针访问指定地址下的数据并返回
}

2.4  FLASH全擦除

        大多都是STM32封装好的函数,按照上面演示的流程直接调用即可:

/**
  * 函    数:FLASH全擦除
  * 参    数:无
  * 返 回 值:无
  * 说    明:调用此函数后,FLASH的所有页都会被擦除,包括程序文件本身,擦除后,程序将不复存在
  */
void MyFLASH_EraseAllPages(void)
{
	FLASH_Unlock();					//解锁
	FLASH_EraseAllPages();			//全擦除
	FLASH_Lock();					//加锁
}

2.5  FLASH页擦除

/**
  * 函    数:FLASH页擦除
  * 参    数:PageAddress 要擦除页的页地址
  * 返 回 值:无
  */
void MyFLASH_ErasePage(uint32_t PageAddress)
{
	FLASH_Unlock();					//解锁
	FLASH_ErasePage(PageAddress);	//页擦除
	FLASH_Lock();					//加锁
}

2.6  FLASH编程字

/**
  * 函    数:FLASH编程字
  * 参    数:Address 要写入数据的字地址
  * 参    数:Data 要写入的32位数据
  * 返 回 值:无
  */
void MyFLASH_ProgramWord(uint32_t Address, uint32_t Data)
{
	FLASH_Unlock();							//解锁
	FLASH_ProgramWord(Address, Data);		//编程字
	FLASH_Lock();							//加锁
}

2.7  FLASH编程半字

/**
  * 函    数:FLASH编程半字
  * 参    数:Address 要写入数据的半字地址
  * 参    数:Data 要写入的16位数据
  * 返 回 值:无
  */
void MyFLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
{
	FLASH_Unlock();							//解锁
	FLASH_ProgramHalfWord(Address, Data);	//编程半字
	FLASH_Lock();							//加锁
}

STM32学习笔记_时光の尘的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光の尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值