STM32-Flash闪存
目录
一、简介
1、闪存模块组织
2、FLASh基本结构
3、FLash写入和读取操作
4、编程流程
5、选项字节格式
6、选项字节编程步骤
二、读写芯片内部FLASH编程
三、器件电子签名
1、简介
2、编程实现
一、简介
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
volatile告诉编译器这个变量是易变的,不要去优化它,每次必须从内存中读取。
4、编程流程
FLASH_CR寄存器中某位:
FLASH_SR寄存器中某位:
5、选项字节格式
每个选择位都在信息 块中有它的反码位,在装载选择位时反码位用于验证选择位是否正确,如果有任何的差别,将 产生一个选择字节错误标志(OPTERR)
6、选项字节编程步骤
二、读写芯片内部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)
{
}
}
作者:GCC_a.out