马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
目次
一、简介
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:
- #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:
- #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内部储存数据
- #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:
- #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:
- #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:
- #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)
- {
- }
-
- }
复制代码 |