A-A+

Flash学习——STM32F103C8T6

2017年09月22日 STM32 暂无评论 阅读 1,495 views 次

前言

项目中使用了STM32F103C8T6的Flash进行数据的断电保存,所以介绍下STM32F103的Flash。将从flash的基本作用、特性、空间分析、函数与代码几个方面介绍。由于此次项目涉及的内容只是Flash中简单的一部分,故用户选择字节部分没有介绍。

作用

Flash在STM32芯片中主要用于储存程序,也可以用于存储需要断电保存的用户数据。

特性

  1. 数据可以断电保存;
  2. 可擦写
    1. STM32官方数据提供最小的有效擦写次数是10k次;
    2. 最少按页擦除,一页是1KB或2KB(High-Quality)的数据,擦除后全部置1;
    3. 写操作,是一种 位与 操作,按2字节的倍数写入,如写1,则(1与1=1)保留;如写0,则(0与1=0),当该位为0时,就不能被写1了,只能通过页擦写实现置1;
    4. 读取操作,就是普通的读取。

C8T6空间分析

STM32F103C8T6属于middle-quality的芯片,数据手册上说只有64k,但是由于C8与CB是同一圆晶上制造的,所有均有128k可用,但是后64K C8T6中没有经过检测,Flash有0x0800 0000 – 0x0800 FFFF 和 0x0801 0000-0x0801 FFFF,在分配之前,需要先知道主程序的空间占了多少,然后根据实际情况进行空间分配。此外,在Information block中还有系统记忆区和选择区,系统记忆区存储着用于单片机基本操作的内容,选择区则是用于对Flash主存储区的配置与操作。

函数与代码

常用库函数

事先声明:FLASH_Status 类型申明,返回是1/0(true/false),这是运行对应函数成功与否的 返回标志。

函数功能解释
void FLASH_Unlock(void)解锁FLASH编写擦除控制器
void
FLASH_Lock(void)
锁定FLASH编写擦除控制器
FLASH_Status  FLASH_ErasePage
(u32 Page_Address)
擦除一个FLASH页面
Page_Address是页起始地址
FLASH_Status FLASH_EraseAllPages
(void)
擦除全部 FLASH 页面
FLASH_Status FLASH_ProgramWord
(u32 Address, u32 Data)
 在指定地址编写一个字,4个字节。
FLASH_Status FLASH_ProgramHalfWord
(u32 Address, u16 Data)
在指定地址编写半字
FLASH_Status FLASH_EnableWriteProtection
(u32 FLASH_Pages)
对制定页面进行写保护,保护了就不能写入。输入参数形式:FLASH_WRProt_Pages4to7
/FLASH_WRProt_AllPages
FLASH_Status FLASH_ReadOutProtection
(FunctionalState NewState)
使能或者失能读出保护
NewState:读出保护的新状态。这个参数可以取: ENABLE 或者 DISABLE

 

选择字节——OptionByte(s)

Flash 中有一个16字节的OptionByte(s),用于使用者对芯片的配置和操作,每2个字节互为反码,所以只有8个字节。功能如下:

RDP   字节0。读保护字节,存储对主存储块的读保护设置。 
USER   字节2。用户字节,配置看门狗、停机、待机。 (UserOptionByte)
Data0  字节4。数据字节0,由芯片使用者自由使用。 
Data1  字节6。数据字节1,由芯片使用者自由使用。 
WRP0   字节8。写保护字节0,存储对主存储块的写保护设置。 
WRP1   字节10。写保护字节1,存储对主存储块的写保护设置。
WRP2   字节12。写保护字节2,存储对主存储块的写保护设置。 
WRP3   字节14。写保护字节3,存储对主存储块的写保护设置。 

函数功能
FLASH_Status FLASH_EraseOptionBytes
(void)
擦除OptionBytes的内容
FLASH_Status FLASH_ProgramOptionByteData
(u32 Address, u8 Data)
在指定 FLASH 选择字节地址编写字节。
待编写的地址,该参数取值可以是 0x1FFF804 或者 0x1FFF806
FLASH_Status FLASH_UserOptionByteConfig
(u16 OB_IWDG, u16 OB_STOP, u16 OB_STDBY)
编写 FLASH 用户选择字节: IWDG_SW(看门狗软硬件选择)/RST_STOP(进入stop模式是否复位)/RST_STDBY(进入待机模式是否复位)
u32 FLASH_GetUserOptionByte
(void)
返回 FLASH 用户选择字节的值:FLASH 用户选择字节的值: IWDG_SW(Bit0),
RST_STOP(Bit1) and RST_STDBY(Bit2)
FLASH_GetWriteProtectionOptionByte
(void)
返回 FLASH 写保护选择字节的值

 

由于当前项目并没有较细致地运用flash中的optionbyte,所以就浅尝辄止地介绍到这里。

代码

flash.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
45
46
#include "sys.h"
#include "flash.h"
#include "stm32f10x.h"
#include "stm32f10x_flash.h"
 
volatile FLASH_Status FLASHStatus = FLASH_COMPLETE; //Flash操作状态变量
 
/****************************************************************
*Name: ReadFlashNBtye
*Function: 从内部Flash读取N字节数据
*Input: ReadAddress:数据地址(偏移地址)ReadBuf:数据指针 ReadNum:读取字节数
*Output: 读取的字节数
****************************************************************/
int ReadFlashNBtye(uint32_t ReadAddress, uint8_t *ReadBuf, int32_t ReadNum)
{
int DataNum = 0;
ReadAddress = (uint32_t)STARTADDR + ReadAddress;
while(DataNum < ReadNum)
{
*(ReadBuf + DataNum) = *(__IO uint8_t*) ReadAddress++;
DataNum++;
}
return DataNum;
}
 
/****************************************************************
*Name: WriteFlashOneWord
*Function: 向内部Flash写入32位数据
*Input: WriteAddress:数据地址(偏移地址)WriteData:写入数据
*Output:
****************************************************************/
 
void WriteFlashOneWord(uint32_t WriteAddress,uint32_t WriteData)
{
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASHStatus = FLASH_ErasePage(STARTADDR); //擦除
 
if(FLASHStatus == FLASH_COMPLETE)
{
FLASHStatus = FLASH_ProgramWord(STARTADDR + WriteAddress, WriteData);
//FLASHStatus = FLASH_ProgramWord(StartAddress+4, 0x0); //需要写入更多数据时开启
//FLASHStatus = FLASH_ProgramWord(StartAddress+8, 0x0); //需要写入更多数据时开启
}
FLASH_Lock();
}

flash.h

1
2
3
4
5
6
7
#ifndef __FLASH_H
#define __FLASH_H
#include <stdint.h>
#define STARTADDR 0x0801FC00
void WriteFlashOneWord(uint32_t WriteAddress,uint32_t WriteData);
int ReadFlashNBtye(uint32_t ReadAddress, uint8_t *ReadBuf, int32_t ReadNum);
#endif

参考

STM32F103xx固件函数库用户手册

标签:

给我留言