本文介绍: 通过写入特定的序列到FLASH_KEYR寄存器可以打开FPEC模块这个特定的序列是在FLASH_KEYR写入两个键值(KEY1和KEY2);如果指定地址在FLASH_WRPR中设定为写保护,则不执行编程并在FLASH_SR寄存器的WRPRTERR位置’1’提出警告。FPEC模块和FLASH_CR寄存器可以程序设置FLASH_CR寄存器中的LOCK位锁住,这时可以通过在FLASH_KEYR中写正确键值对FPEC解锁检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作

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

        读写FLASH的用途利用程序存储器的剩余空间保存掉电不丢失用户数 ,通过在程序编程IAP),实现程序的自我更新在线编程(In-Circuit Programming – ICP用于更新程序存储器的全部内容,它通过JTAGSWD协议系统加载程序Bootloader下载程序,在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任一种通信接口下载程序。

 FPEC模块处理闪存的编程和擦除操作,它包括7个32位的寄存器

FPEC键寄存器(FLASH_KEYR)
选择字节键寄存器(FLASH_OPTKEYR)
闪存控制存器(FLASH_CR)
闪存状态存器(FLASH_SR)
闪存地址寄存器(FLASH_AR)
选择字节存器(FLASH_OBR)
写保护寄存器(FLASH_WRPR)

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

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

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

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

其中:

          #define    __IO    volatile

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

 STM32—Flash读写详解_stm32写入flash-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zhuxinmingde/article/details/131972752?utm_medium=distribute.pc_relevant.nonetaskblog-2~default~baidujs_baidulandingword~default-1-131972752-blog-123402701.235^v39^pc_relevant_3m_sort_dl_base1&spm=1001.2101.3001.4242.2&utm_relevant_index=4
        下文代码中STMFLASH_Read(FLASH_ADDR,Temporary_storage,size);这里FLASH_ADDR是我们读取的起始地址,Temporary_storage是16位的指针变量,存放我们读取到的内容,size我们读取大小,值得注意的是,size是半字大小,也就是多少两个字节比如我们读取100个字节,size就可以填50。

FLASH的读取
直接读取某一地址的内容
因为读取FLASH并不需要解锁,我们可以直接用指针指向所读的地址,之后读取此地址的内容即可。

p = (uint32_t *)(0x08008000);
printf("rn读取内部FLASH该地址存储内容为:0x%x",*p);
此程序就是先将0x08008000赋给指针变量P,之后将P指向地址的内容以16进制格式输出出来。

读取选定位置的选定大小的内容
1. 首先我们编写一个函数,用以读取指定地址的半字(16位数据)。

u16 STMFLASH_ReadHalfWord(u32 faddr)
{
	return *(vu16*)faddr; 
}
2. 从指定地址开始读出指定长度数据

LReadAddr:起始地址

pBuffer:数据指针

NumToWrite:半字(16位)数

void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)   	
{
	u16 i;
	for(i=0;i<NumToRead;i++)
	{
		pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
		ReadAddr+=2;//偏移2个字节.	
	}
}
当我们想读取FLASH内容时,只需要直接调用上面的函数即可

共有三个键值
RDPRT键 = 0x000000A5

        RDP:读出保护选择字节
        读出保护功能帮助用户保护存在闪存中的代码。该功能设置信息块中的一个选择字节启用
        写入正确数值(RDPRT键=0x00A5)到这个选择字节后,闪存被开放允许读出访问。

KEY1 = 0x45670123
KEY2 = 0xCDEF89AB

解除闪存锁
        复位后,FPEC模块是被保护的,不能写入FLASH_CR寄存器;通过写入特定的序列到FLASH_KEYR寄存器可以打开FPEC模块,这个特定的序列是在FLASH_KEYR写入两个键值(KEY1和KEY2);错误操作序列都会在下次复位前锁死FPEC模块和FLASH_CR寄存器。
        写入错误的键序列还会产生总线错误总线错误发生在第一次写入的不是KEY1,或第一次写入的是KEY1但第二次写入的不是KEY2时;FPEC模块和FLASH_CR寄存器可以由程序设置FLASH_CR寄存器中的LOCK位锁住,这时可以通过在FLASH_KEYR中写正确的键值对FPEC解锁。

主闪存编程

        对主闪存编程每次可以写入16位。当FLASH_CR寄存器的PG位为’1’时,在一个闪存地址写入一个半字将启动一次编程;写入任何非半字的数据,FPEC都会产生总线错误在编程过程中(BSY位为’1’),任何读写闪存的操作都会使CPU暂停,直到此次闪存编程结束

 标准的闪存编程顺序如下:(即上图详细过程文字描述)
        检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作
        设置FLASH_CR寄存器的PG位为’1’;
        在指定的地址写入要编程的半字;
        等待BSY位变为’0’;
        读出写入的地址并验证数据
注意: 当FLASH_SR寄存器的BSY位为’1’时,不能对任何寄存器执行操作

        这种模式下CPU以标准的写半字的方式烧写闪存,FLASH_CR寄存器的PG位必须置’1’。FPEC先读出指定地址的内容检查是否擦除,如未被擦除则不执行编程并在FLASH_SR寄存器的PGERR位提出警告(唯一的例外是当要烧写的数值是0x0000时,0x0000可被正确烧入且PGERR位不被置位);如果指定的地址在FLASH_WRPR中设定为写保护,则不执行编程并在FLASH_SR寄存器的WRPRTERR位置’1’提出警告。FLASH_SR寄存器的EOP为’1’时表示编程结束

闪存擦除

 页擦除
闪存的任何一页都可以通过FPEC的页擦除功能擦除;擦除一页应遵守下述过程
        检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作
        设置FLASH_CR寄存器的PER位为’1’;
        用FLASH_AR寄存器选择要擦除的页;
        设置FLASH_CR寄存器的STRT位为’1’;
        等待BSY位变为’0’;
        读出被擦除的页并做验证

 整片擦除
可以用整片擦除功能擦除所有用户区的闪存,信息块不受此操作影响建议使用下述过程
        检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作
        设置FLASH_CR寄存器的MER位为’1’;
        设置FLASH_CR寄存器的STRT位为’1’;
        等待BSY位变为’0’;
        读出所有页并做验证

选择字节说明
        选择字节共有8个字节,由用户根据应用需要配置例如:可以选择使用硬件模式看门狗软件的看门狗。
        在选择字节中每个32位的字被划分为下述格式:

        每次系统复位后,选择字节装载器读出信息块的数据并保存在寄存器中每个选择位都在信息块中有它的反码位,在装载选择位时反码位用于验证选择位是否正确,如果有任何的差别,将产生一个选择字节错误标志(OPTERR)。当发生选择字节错误时,对应的选择字节被强置为0xFF。当选择字节和它的反码均为0xFF时(擦除后的状态),则关闭上述验证功能。 

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

 STM32单片机bootloader扫盲_stm32 bootloader-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_42378319/article/details/120896348

BootLoader和APP之间关系
        APP就是平时写的单片机上的应用程序,而BootLoader本质上和APP一样,也是平时写的应用程序BootLoader只不过是拥有从外部接收数据,更新Flash(也就是APP),跳转至APP功能特殊APP罢了。

        以STM32F103为例,如果没有BootLoader,flash分布就如下图左半部分。如果有BootLoader,就如下图右半部分,将flash分为两部分(这里举例用0x800 4000做分界线),存储了两个应用程序(BootLoader和APP)

 

原文地址:https://blog.csdn.net/weixin_57604904/article/details/134729757

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_40228.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注