【STM32】讀寫stm32的內置Flash(附代碼)

最近嘗試了一下對32的內置flash進行讀寫,衆所周知,芯片的flash是用來存放代碼指令和變量的,其中的數據即使掉電也不會丟失。而stm32的flash之大,對於初學者的小打小鬧完全不用擔心不夠用的情況。

因此,在需要保存一些芯片掉電之後依舊需要保存的數據(數據量不是特別大)時,運用內置flash的空閒部分可以爲我們省去一顆eeprom或外置flash的花銷。


知識總結:

1.flash的寫入之前需要先擦除,且擦除是直接擦除一頁(2KBytes),整個流程爲

(1)解鎖flash(2)擦除一頁或多頁(3)寫數據(4)鎖定flash

2.flash正常寫入一次是16bit

3.flash的地址從0x08000000開始,存儲代碼指令與變量。所以在用戶自己寫flash時,要注意不要把代碼指令與變量給覆蓋了。查看編譯過的代碼使用了多少內存,可在Keil中雙擊工程名查看*.map文件

基地址加上Size就是代碼指令與變量佔用的空間。在寫入用戶數據時,要避開這些地方。

以下是基於正點原子庫函數的flash讀寫代碼。在STM32F103RCT6測試通過。可以直接複製使用,好用請爲博客點個贊!

flash.h:

#ifndef _FLASH_H
#define _FLASH_H

#include "stm32f10x.h"

extern uint32_t Flash_EraseWriteOnePage(uint32_t WRITE_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress);
extern void Flash_ReadOnePage(uint32_t READ_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress);

#endif

flash.c

/////////////////////////////////////////
//Author: Read Air
//Version: 1.0
//Date:2019/4/18
/////////////////////////////////////////

#include "flash.h"
#include "stm32f10x.h"
///////////////////////////////////////////////////////
//WRITE_START_ADDR 	-- 開始寫的地址
//SizeOf_u32 		-- 要寫入的32位(雙字)的數量
//DataAddress		-- 等待被寫入的數據數組(32位的)
//返回值			-- 出現擦除失敗故障返回寫入地址,正常返回0
///////////////////////////////////////////////////////
uint32_t Flash_EraseWriteOnePage(uint32_t WRITE_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress)
{
	char EraseCounter = 0;
	static FLASH_Status FLASHStatus;
	uint32_t Address;
	u16 Remain_u32 = SizeOf_u32;
	u8 err_time=0;
	/* 解鎖 */
	FLASH_Unlock();
	/* 清空所有標誌位 */
	FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
	/* 擦除一頁*/
	FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR);
	/* 嘗試擦除*/
	while((FLASHStatus != FLASH_COMPLETE)&&(err_time<5))
	{
		FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR);
		err_time++;
	}
	/* 擦除失敗*/
	if (err_time >= 5) return WRITE_START_ADDR;
	/* 向內部 FLASH 寫入數據 */
	Address = WRITE_START_ADDR;
	while ((Remain_u32 > 0) && (FLASHStatus == FLASH_COMPLETE)) 
	{
		FLASHStatus = FLASH_ProgramWord(Address, DataAddress[SizeOf_u32-Remain_u32]);
		Address = Address + 4;
		Remain_u32--;
	}
	/* 鎖定*/
	FLASH_Lock();
	return 0;
}

///////////////////////////////////////////////////////
//READ_START_ADDR 	-- 開始寫的地址
//SizeOf_u32 		-- 要讀出的32位(雙字)的數量
//DataAddress		-- 等待被讀出的數據數組(32位的)
///////////////////////////////////////////////////////
void Flash_ReadOnePage(uint32_t READ_START_ADDR,u16 SizeOf_u32,uint32_t *DataAddress)
{	
	uint32_t Address;
	u16 Remain_u32 = SizeOf_u32;
	/* 檢查寫入的數據是否正確 */
	Address = READ_START_ADDR;
	while ((Remain_u32 > 0)) 
	{
		 DataAddress[SizeOf_u32-Remain_u32] = (*(__IO uint32_t*) Address);
		Address += 4;
		Remain_u32--;	
	}
}

//注意事項: 
//1、對flash進行寫入操作,一定要遵循“先擦除,後寫入”的原則 
//2、注意到stm32內置flash的擦除操作都是以頁爲單位進行,而寫入操作則必須以16位半字寬度數據爲單位,允許跨頁寫,嘗試寫入非16位半字數據將導致stm32內部總線錯誤。 
//3、進行stm32的內置flash編程操作時(寫或擦除),必須打開內部的RC振盪器(HSI) 
//4、注意stm32的內置flash最多隻有10萬次重複擦寫的生命週期,謹記切勿在程序中放任死循環對flash進行持續地重複擦寫。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章