STM32-Flash闪存

[复制链接]
发表于 2025-12-26 10:08:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
目次
一、简介
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
KEY10x45670123
KEY20xCDEF89AB
  解锁:
        复位后,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:
 
  1. #include "stm32f10x.h"                  // Device header
  2. uint32_t MyFlash_ReadWord(uint32_t Address)
  3. {
  4.         return *((__IO uint32_t *)(Address));     //32位
  5. }
  6. uint16_t MyFlash_ReadHalfWord(uint32_t Address)
  7. {
  8.         return *((__IO uint16_t *)(Address));
  9. }
  10. uint8_t MyFlash_ReadByte(uint32_t Address)
  11. {
  12.         return *((__IO uint16_t *)(Address));
  13. }
  14. void MyFlash_EraseAllPages(void)
  15. {
  16.         FLASH_Unlock();
  17.    FLASH_EraseAllPages();
  18.         FLASH_Lock();
  19.        
  20. }
  21. void MyFlash_ErasePage(uint32_t PageAddress)
  22. {
  23.         FLASH_Unlock();
  24.    FLASH_ErasePage(PageAddress);
  25.         FLASH_Lock();
  26.        
  27. }
  28. void MyFlash_ProgramWord(uint32_t Address,uint32_t Data)
  29. {
  30.        
  31.         FLASH_Unlock();
  32.    FLASH_ProgramWord(Address,Data);
  33.         FLASH_Lock();
  34.        
  35. }
  36. void MyFlash_ProgramHalfWord(uint32_t Address,uint16_t Data)
  37. {
  38.        
  39.         FLASH_Unlock();
  40.    FLASH_ProgramHalfWord(Address,Data);
  41.         FLASH_Lock();
  42.        
  43. }
复制代码
MyFlash.h:
  1. #ifndef _MYFLASH_H
  2. #define _MYFLASH_H
  3. uint32_t MyFlash_ReadWord(uint32_t Address);
  4. uint16_t MyFlash_ReadHalfWord(uint32_t Address);
  5. uint8_t MyFlash_ReadByte(uint32_t Address);
  6. void MyFlash_EraseAllPages(void);
  7. void MyFlash_ErasePage(uint32_t PageAddress);
  8. void MyFlash_ProgramWord(uint32_t Address,uint32_t Data);
  9. void MyFlash_ProgramHalfWord(uint32_t Address,uint16_t Data);
  10. #endif
复制代码
Store.c:
用来在Flash内部储存数据
  1. #include "stm32f10x.h"                  // Device header
  2. #include  "MyFlash.h"
  3. #define STORE_START_ADDRESS   0x0800FC00
  4. #define STORE_COUNT  512
  5. uint16_t Store_Data[STORE_COUNT];
  6. uint16_t i=0;
  7. void Store_Init(void)
  8. {
  9.        
  10.        
  11.         if(MyFlash_ReadHalfWord(STORE_START_ADDRESS)!=0xA5A5)
  12.         {
  13.                 MyFlash_ErasePage(STORE_START_ADDRESS);
  14.                 MyFlash_ProgramHalfWord(STORE_START_ADDRESS,0xA5A5);
  15.                 for(i=1;i<STORE_COUNT;i++)
  16.                 {
  17.                         MyFlash_ProgramHalfWord(STORE_START_ADDRESS+i*2,0x0000);
  18.                 }
  19.         }
  20.         for(i=0;i<STORE_COUNT ;i++)
  21.         {
  22.                 Store_Data[i]=MyFlash_ReadHalfWord(STORE_START_ADDRESS+i*2);
  23.         }
  24. }
  25. void Store_Save(void)
  26. {
  27.         MyFlash_ErasePage(STORE_START_ADDRESS);
  28.         for(i=0;i<STORE_COUNT;i++)
  29.         {
  30.                 MyFlash_ProgramHalfWord(STORE_START_ADDRESS+i*2,Store_Data[i]);
  31.         }
  32.        
  33. }
  34. void Store_Clear(void)
  35. {
  36.         for(i=1;i<STORE_COUNT;i++)
  37.         {
  38.                 Store_Data[i]=0x0000;
  39.         }
  40.        
  41.          Store_Save();
  42. }
复制代码
Store.h:
  1. #ifndef _STORE_H
  2. #define _STORE_H
  3. extern uint16_t Store_Data[];
  4. void Store_Init(void);
  5. void Store_Save(void);
  6. void Store_Clear(void);
  7. #endif
复制代码
main.c:
 
  1. #include  "stm32f10x.h"                  // Device header
  2. #include  "OLED.h"
  3. #include  "delay.h"
  4. #include  "Store.h"
  5. #include  "MyFlash.h"
  6. int main(void)
  7. {
  8.        
  9.    OLED_Init();
  10.         Store_Init();
  11.         //擦除后数据位全都变为1
  12.         //MyFlash_EraseAllPages();  
  13.         OLED_ShowString(1,1,"Flag:");
  14.         OLED_ShowString(2,1,"Data:");       
  15.        
  16.         while(1)
  17.         {
  18.                   
  19.              OLED_ShowHexNum(1,6,Store_Data[0],4);
  20.                   OLED_ShowHexNum(2,6,Store_Data[1],4);
  21.              OLED_ShowHexNum(3,6,Store_Data[2],4);
  22.       
  23.               Store_Data[1]++;
  24.              Store_Data[2]+=2;
  25.              Store_Save();
  26.                   Delay_ms(1000);
  27.         }
  28.        
  29. }
复制代码


三、器件电子署名

1、简介



  • 电子署名存放在闪存存储器模块的体系存储地区,包罗的芯片辨认信息在出厂时编写,不可更改,利用指针读指定地点下的存储器可获取电子署名
  • 闪存容量寄存器:     
    基地点:0x1FFF F7E0     巨细:16位
  • 产物唯一身份标识寄存器:     
    基地点: 0x1FFF F7E8     巨细:96位
2、编程实现

main.c:
  1. #include  "stm32f10x.h"                  // Device header
  2. #include  "OLED.h"
  3. #include  "delay.h"
  4. int main(void)
  5. {
  6.        
  7.    OLED_Init();
  8.        
  9.         OLED_ShowString(1,1,"F_SIZE:");
  10.         OLED_ShowHexNum(1,8,*(__IO uint16_t *)(0x1FFFF7E0),4);
  11.        
  12.         OLED_ShowString(2,1,"U_ID:");
  13.         OLED_ShowHexNum(2,6,*(__IO uint16_t *)(0x1FFFF7E8),4);
  14.         OLED_ShowHexNum(2,11,*(__IO uint16_t *)(0x1FFFF7E8+0x02),4);
  15.         OLED_ShowHexNum(3,1,*(__IO uint32_t *)(0x1FFFF7E8+0x04),8);
  16.         OLED_ShowHexNum(4,1,*(__IO uint32_t *)(0x1FFFF7E8+0x08),8);
  17.        
  18.        
  19.         while(1)
  20.         {
  21.         }
  22.        
  23. }
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表