STM32-Flash闪存

目录

一、简介

1、闪存模块组织

2、FLASh基本结构

3、FLash写入和读取操作

4、编程流程

5、选项字节格式

6、选项字节编程步骤

二、读写芯片内部FLASH编程

三、器件电子签名

1、简介

2、编程实现


一、简介

  • STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程
  • 读写FLASH的用途:利用程序存储器的剩余空间来保存掉电不丢失的用户数据;通过在程序中编程(IAP),实现程序的自我更新。
  • 在线编程(In-Circuit Programming -- ICP)用于更新程序存储器的全部内容,它通过JTAG、SWD协议或系统加载程序(Bootloader)下载下载程序
  • 在程序中编程(In-Application Programming -- IAP),可以使用微控制器支持的任一种通信接口下载程序
  • STM32F103C8T6 中Flash为64字节

ROM和RAM存储 :

1、闪存模块组织

主存储器利用页单元来存储数据,每个页的大小为1KByte,C8T6芯片64KByte ,所以只用了前64页。

启动程序代码即系统存储器,大小为2KByte

2、FLASh基本结构

3、FLash写入和读取操作

  • 先解锁

**FPEC(闪存编程/擦除控制器)**共有三个键值:

|--------|------------|
| 键 | 值 |
| RDPRT键 | 0x000000A5 |
| KEY1 | 0x45670123 |
| KEY2 | 0xCDEF89AB |

解锁:

复位后,FPEC被保护 ,不能写入FLASH_CR

在FLASH_KEYR先写入KEY1 ,再写入KEY2,解锁

错误的操作序列会在下次复位前锁死FPEC和FLASH_CR

加锁:

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

  • 读写
    • 使用指针 指定地址下的存储器: uint16_t Data = *((__IO uint16_t *)(0x08000000));
    • 使用指针指定地址下的存储器: *((__IO uint16_t *)(0x08000000)) = 0x1234;
    • 其中: #define __IO volatile

volatile告诉编译器这个变量是易变的,不要去优化它,每次必须从内存中读取。

4、编程流程

FLASH_CR寄存器中某位:

  • LOCK :锁,只能写'1'。 当该位为'1'时表示FPEC和FLASH_CR被锁住。在检测到正确的解 锁序列后,硬件清除此位为'0'。 在一次不成功的解锁操作后,下次系统复位前,该位不能再被改变。
  • PG:编程,选择编程操作,置'1'。
  • PER:页擦除,选择整页擦除,置'1'。
  • START:开始,当该位为1时将触发一次擦除操作。该位只可由软件置1,并在BSY变为'1'时,清为'0'。
  • MER:全擦除,选择擦除所有用户页,置'1'

FLASH_SR寄存器中某位:

  • BSY:忙,该位指示闪存操作正在进行。在闪存操作开始时,该位被设置为'1';在操作结束或发生错误时该位被清除为'0'

  • 编程过程

  • 闪存页擦除
  • 闪存全擦除

5、选项字节格式

每个选择位都在信息 块中有它的反码位,在装载选择位时反码位用于验证选择位是否正确,如果有任何的差别,将 产生一个选择字节错误标志(OPTERR)

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

6、选项字节编程步骤

  • 选项字节编程
    • 检查FLASH_SR的BSY位,以确认没有其他正在进行的编程操作
    • 解锁FLASH_CR的OPTWRE(允许写选择字节),当该位为1时 ,允许对选择字节进行编程操作。当在FLASH_OPTKETR寄存器写入正确的键序列后,该位被置为'1'。软件可清除此位。
    • 设置FLASH_CR的OPTPG位为1
    • 写入要编程的半字到指定的地址
    • 等待BSY位变为0
    • 读出写入的地址并验证数据
  • 选项字节擦除
    • 检查FLASH_SR的BSY位,以确认没有其他正在进行的闪存操作
    • 解锁FLASH_CR的OPTWRE位
    • 设置FLASH_CR的OPTER位为1
    • 设置FLASH_CR的OPTER位为1
    • 等待BSY位变为0
    • 读出被擦除的选择字节并做验证

二、读写芯片内部FLASH编程

MyFlash.c:

cpp 复制代码
#include "stm32f10x.h"                  // Device header


uint32_t MyFlash_ReadWord(uint32_t Address)
{
	return *((__IO uint32_t *)(Address));     //32位
}

uint16_t MyFlash_ReadHalfWord(uint32_t Address)
{
	return *((__IO uint16_t *)(Address));
}

uint8_t MyFlash_ReadByte(uint32_t Address)
{
	return *((__IO uint16_t *)(Address));
}

void MyFlash_EraseAllPages(void)
{
	FLASH_Unlock();
   FLASH_EraseAllPages();
	FLASH_Lock();
	
}

void MyFlash_ErasePage(uint32_t PageAddress)
{
	FLASH_Unlock();
   FLASH_ErasePage(PageAddress);
	FLASH_Lock();
	
}

void MyFlash_ProgramWord(uint32_t Address,uint32_t Data)
{
	
	FLASH_Unlock();
   FLASH_ProgramWord(Address,Data);
	FLASH_Lock();
	
}

void MyFlash_ProgramHalfWord(uint32_t Address,uint16_t Data)
{
	
	FLASH_Unlock();
   FLASH_ProgramHalfWord(Address,Data);
	FLASH_Lock();
	
}

MyFlash.h:

cpp 复制代码
#ifndef _MYFLASH_H
#define _MYFLASH_H

uint32_t MyFlash_ReadWord(uint32_t Address);

uint16_t MyFlash_ReadHalfWord(uint32_t Address);

uint8_t MyFlash_ReadByte(uint32_t Address);

void MyFlash_EraseAllPages(void);


void MyFlash_ErasePage(uint32_t PageAddress);

void MyFlash_ProgramWord(uint32_t Address,uint32_t Data);

void MyFlash_ProgramHalfWord(uint32_t Address,uint16_t Data);

#endif

Store.c:

用来在Flash内部储存数据

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include  "MyFlash.h"

#define STORE_START_ADDRESS   0x0800FC00
#define STORE_COUNT  512


uint16_t Store_Data[STORE_COUNT];
uint16_t i=0;

void Store_Init(void)
{
	
	
	if(MyFlash_ReadHalfWord(STORE_START_ADDRESS)!=0xA5A5)
	{
		MyFlash_ErasePage(STORE_START_ADDRESS);
		MyFlash_ProgramHalfWord(STORE_START_ADDRESS,0xA5A5);
		for(i=1;i<STORE_COUNT;i++)
		{
			MyFlash_ProgramHalfWord(STORE_START_ADDRESS+i*2,0x0000);
		}
	}
	for(i=0;i<STORE_COUNT ;i++)
	{
		Store_Data[i]=MyFlash_ReadHalfWord(STORE_START_ADDRESS+i*2);
	}
}

void Store_Save(void)
{
	MyFlash_ErasePage(STORE_START_ADDRESS);
	for(i=0;i<STORE_COUNT;i++)
	{
		MyFlash_ProgramHalfWord(STORE_START_ADDRESS+i*2,Store_Data[i]);
	}
	
}


void Store_Clear(void)
{
	for(i=1;i<STORE_COUNT;i++)
	{
		Store_Data[i]=0x0000;
	}
	
	 Store_Save();
}

Store.h:

cpp 复制代码
#ifndef _STORE_H
#define _STORE_H

extern uint16_t Store_Data[];

void Store_Init(void);

void Store_Save(void);

void Store_Clear(void);

#endif

main.c:

cpp 复制代码
#include  "stm32f10x.h"                  // Device header
#include  "OLED.h"
#include  "delay.h"
#include  "Store.h"
#include  "MyFlash.h"


int main(void)
{
	
   OLED_Init();
	Store_Init();
	//擦除后数据位全都变为1
	//MyFlash_EraseAllPages();  
	OLED_ShowString(1,1,"Flag:");
	OLED_ShowString(2,1,"Data:");	
	
	while(1) 
	{
		  
	     OLED_ShowHexNum(1,6,Store_Data[0],4);
		  OLED_ShowHexNum(2,6,Store_Data[1],4);
	     OLED_ShowHexNum(3,6,Store_Data[2],4);
      
    	  Store_Data[1]++;
	     Store_Data[2]+=2;
	     Store_Save();
		  Delay_ms(1000);
	}
	
}

三、器件电子签名

1、简介

  • 电子签名存放在闪存存储器模块的系统存储区域,包含的芯片识别信息在出厂时编写,不可更改,使用指针读指定地址下的存储器可获取电子签名
  • 闪存容量寄存器:
    基地址:0x1FFF F7E0 大小:16位
  • 产品唯一身份标识寄存器:
    基地址:0x1FFF F7E8 大小:96位

2、编程实现

main.c:

cpp 复制代码
#include  "stm32f10x.h"                  // Device header
#include  "OLED.h"
#include  "delay.h"

int main(void)
{
	
   OLED_Init();
	
	OLED_ShowString(1,1,"F_SIZE:");
	OLED_ShowHexNum(1,8,*(__IO uint16_t *)(0x1FFFF7E0),4);
	
	OLED_ShowString(2,1,"U_ID:");
	OLED_ShowHexNum(2,6,*(__IO uint16_t *)(0x1FFFF7E8),4);
	OLED_ShowHexNum(2,11,*(__IO uint16_t *)(0x1FFFF7E8+0x02),4);
	OLED_ShowHexNum(3,1,*(__IO uint32_t *)(0x1FFFF7E8+0x04),8);
	OLED_ShowHexNum(4,1,*(__IO uint32_t *)(0x1FFFF7E8+0x08),8);
	
	
	while(1) 
	{

	}
	
}
相关推荐
A9better20 分钟前
嵌入式开发学习日志37——stm32之USART
stm32·嵌入式硬件·学习
国科安芯4 小时前
ASP4644芯片低功耗设计思路解析
网络·单片机·嵌入式硬件·安全
充哥单片机设计4 小时前
【STM32项目开源】基于STM32的智能厨房火灾燃气监控
stm32·单片机·嵌入式硬件
CiLerLinux11 小时前
第四十九章 ESP32S3 WiFi 路由实验
网络·人工智能·单片机·嵌入式硬件
时光の尘11 小时前
【PCB电路设计】常见元器件简介(电阻、电容、电感、二极管、三极管以及场效应管)
单片机·嵌入式硬件·pcb·二极管·电感·三极管·场效应管
Lu Zelin11 小时前
单片机为什么不能跑Linux
linux·单片机·嵌入式硬件
宁静致远202112 小时前
stm32 freertos下基于hal库的模拟I2C驱动实现
stm32·嵌入式硬件·freertos
Wave84517 小时前
STM32--智能小车
stm32·单片机·嵌入式硬件
wdfk_prog19 小时前
[Linux]学习笔记系列 -- lib/timerqueue.c Timer Queue Management 高精度定时器的有序数据结构
linux·c语言·数据结构·笔记·单片机·学习·安全
helesheng1 天前
用低成本FPGA实现FSMC接口的多串口(UART)控制器
stm32·fsmc·fpga·uart控制器