0%

15-2读写内部FLASH&读取芯片ID

常用函数

1
void FLASH_Unlock(void);

用于解锁,在KEYR寄存器,先写入KEY1,再写入KEY2

1
void FLASH_Lock(void);

用于加锁,把CR寄存器的LOCK位设置为1

1
FLASH_Status FLASH_ErasePage(uint32_t Page_Address);

闪存擦除页,参数给某一页的起始地址。返回值是这个操作的完成状态。

1
FLASH_Status FLASH_EraseAllPages(void);

闪存全擦除。

1
FLASH_Status FLASH_EraseOptionBytes(void);

擦除选项字节。

1
2
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);

指定地址写入字和写入半字。

1
2
3
4
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);
FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages);
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);
FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY);

选项字节写入。
第一个是选项字节的写入。第二个是选项字节的写保护。第三个是选项字节的读保护。第四个是选项字节用户选项的三个配置位。

1
2
3
uint32_t FLASH_GetUserOptionByte(void);
uint32_t FLASH_GetWriteProtectionOptionByte(void);
FlagStatus FLASH_GetReadOutProtectionStatus(void);

获取选项字节当前状态。
第一个是获取用户选项的三个配置位。第二个是获取写保护状态。第三个是获取读保护状态。

1
FlagStatus FLASH_GetPrefetchBufferStatus(void);

获取预取缓冲区状态。

1
void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);

中断使能

1
FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);

获取标志位

1
void FLASH_ClearFlag(uint32_t FLASH_FLAG);

清除标志位

1
FLASH_Status FLASH_GetStatus(void);

获取状态

1
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);

等待上一次操作,等待忙。一般不需要单独调用。

读写内部FLASH

MyFLASH.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "stm32f10x.h"                  // Device header

uint32_t MyFLASH_ReadWord(uint32_t Address)//FLASH读字
{
return *((__IO uint32_t *)(Address));
}

uint16_t MyFLASH_ReadHalfWord(uint32_t Address)//FLASH读半字
{
return *((__IO uint16_t *)(Address));
}

uint8_t MyFLASH_ReadByte(uint32_t Address)//FLASH读字节
{
return *((__IO uint8_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();//上锁
}

Store.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "stm32f10x.h"                  // Device header
#include "MyFLASH.h"
#include "Store.h"

uint16_t Store_Data[512];//对应闪存的一页

void Store_Init(void)
{
//初始化闪存
if (MyFLASH_ReadHalfWord(0x0800FC00) != 0xA5A5)
{
MyFLASH_ErasePage(0x0800FC00);
MyFLASH_ProgramHalfWord(0x0800FC00,0xA5A5);
for(uint16_t i = 1; i<512;i++)
{
MyFLASH_ProgramHalfWord(0x0800FC00 + i * 2,0x0000);
}
}
//上电时把闪存数据备份到SRAM
for(uint16_t i = 0; i<512;i++)
{
Store_Data[i] = MyFLASH_ReadHalfWord(0x0800FC00 + i * 2);
}
}

void Store_Save(void)
{
MyFLASH_ErasePage(0x0800FC00);
for(uint16_t i = 0; i<512;i++)
{
MyFLASH_ProgramHalfWord(0x0800FC00 + i * 2,Store_Data[i]);
}
}

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

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Store.h"
#include "Key.h"

uint8_t KeyNum;

int main(void)
{
OLED_Init();
KEY_Init();
Store_Init();
OLED_ShowString(1,1,"Flag:");
OLED_ShowString(2,1,"Data:");
while(1)
{
KeyNum = Key_GetNum();
if(KeyNum == 1)
{
Store_Data[1]++;
Store_Data[2]+=2;
Store_Data[3]+=3;
Store_Data[4]+=4;
Store_Save();
}
if(KeyNum == 2)
{
Store_Clear();
}
OLED_ShowHexNum(1,6,Store_Data[0],4);
OLED_ShowHexNum(3,1,Store_Data[1],4);
OLED_ShowHexNum(3,6,Store_Data[2],4);
OLED_ShowHexNum(4,1,Store_Data[3],4);
OLED_ShowHexNum(4,6,Store_Data[4],4);
}
}

读取芯片ID

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.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);
}