stm32 读写Flash

    在有些场合掉电保存是很有用的,但一般都是用EEPROM,要新增硬件电路,比较麻烦。stm32有一个Flash控制器,用户可以在线读写Flash,这样一定情况下可以用读写Flash做掉电保存,挺方便的。擦写不多于10万次。

    我用的是stm32F10x3ZET6的Flash(512K)结构如下:

    stm32 读写Flash_第1张图片

存储区的地址:0x0800 0000--0x0807 FFFF

这一段存储区使用存储程序的,用户也可以读写这一块区域。当然你得保证你读写的区域不是你的程序存储的区域。为此你要对你的编程器进行设置,如何你是用的j-link,用keil直接下载的,你可以进行一下设置,进入 “魔术棒”---utilities--seting

stm32 读写Flash_第2张图片

程序编程区域设为0x0800 0000--0x0007 0000 。

这样这之后的区域就0x0007 0001--0x0807 FFFF你就可以任意读写了。

程序:

    1、一定要开启HSI时钟。

    2、先擦除后写入。擦除时只能按页擦除。

    3、读写必须是半字(16 bit)。

下面为读写配置函数。

flash.c

#include "flash.h"

void Flash_Init(void)
{
	RCC_HSICmd(ENABLE);//开启内部高速时钟	
}

uint8_t Flash_Write(uint32_t STARTADDR, uint16_t data[], uint16_t len)//擦除一页从这一页的开始写一组数据,成功返回0,不成功返回1
{
	FLASH_Status flashStatus = FLASH_COMPLETE;
	uint16_t i=0;
	FLASH_Unlock();    					//解锁
	FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR |  FLASH_FLAG_WRPRTERR);	//清除flag  
	flashStatus = FLASH_ErasePage(STARTADDR);	//擦除以STARTADDR开始的那一页	
	if(flashStatus != FLASH_COMPLETE)//是否擦除成功,不成功返回1
		return 1;
	for(i=0; i<len; i++)
		FLASH_ProgramHalfWord(STARTADDR+2*i, data[i]);     //写入数组   
	
	FLASH_Lock();//锁定flash
	
	return 0;
}

void Flash_Read(uint32_t startaddr, uint16_t data[], uint16_t len) 
{
	uint16_t i=0;
	for(i=0; i<len; i++)	
		data[i] = *(vu16*)(startaddr+i*2);//为什么这个指针是指向flash,而不是内存呢?因为
	//在arm中ram,sdram,flash都映射到同一套地址中,在startaddr所在的这一片地址就是对应着flash
}

测试程序,写进去再读出来,发到串口。

#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "led.h"
#include "usart.h"
#include "stdio.h"
#include "timer.h"
#include "dma.h"
#include "adc.h"
#include "flash.h"

void init()
{
	Usart1_Init(115200);
	Flash_Init();
}

#define STARTADDR 0x0807f800
int main()
{
	uint8_t flag = 0;
	uint8_t i=0;
	uint16_t data[5]={1, 2, 3, 4, 5};
	uint16_t num[5]={0};
	init();
		
	//printf("hello");
	
	
	
	Flash_Write(STARTADDR, data, 5);
	Flash_Read(STARTADDR, num, 5);
	
	for(i=0; i<5; i++)
	{
		printf("%d", num[i]);
	}
	
	while(1);
	
}

认为重要的就这些了,其他的问题可以百度到。



你可能感兴趣的:(stm32,Flash读写)