STM32 FLASH模擬EEPROM實驗



     STM32自己沒有自帶EEPROM,可是STM32具備IAP(在應用編程)功能,因此咱們能夠把它的FLASH當成EEPROM來使用。 編程


1 STM32 FLASH簡介

不 同型號的STM32,其FLASH容量也有所不一樣,最小的只有16K字節,最大的則達到了1024K字節。 electron


STM32的閃存模塊由:主存儲器、信息塊和閃存存儲器接口寄存器等3部分組成。 函數

主存儲器,該部分用來存放代碼和數據常數(如const類型的數據)。對於大容量產品,其被劃分爲256頁,每頁2K字節。注意,小容量和中容量產品則每頁 只有1K字節。從上圖能夠看出主存儲器的起始地址就是0X08000000, B0、B1都接GND的時候,就是從0X08000000開始運行代碼的。 lua

信息塊,該部分分爲2個小部分,其中啓動程序代碼,是用來存儲ST自帶的啓動程序,用於串口下載代碼,當B0接V3.3,B1接GND的時候,運行的就是這部分代碼。用戶選擇字節,則通常用於配置寫保護、讀保護等功能,本章不做介紹。 spa

閃存存儲器接口寄存器,該部分用於控制閃存讀寫等,是整個閃存模塊的控制機構。 設計

對主存儲器和信息塊的寫入由內嵌的閃存編程/擦除控制器(FPEC)管理;編程與擦除的高電壓由內部產生。 指針

在執行閃存寫操做時,任何對閃存的讀操做都會鎖住總線,在寫操做完成後讀操做才能正確地進行;既在進行寫或擦除操做時,不能進行代碼或數據的讀取操做。 code

閃存的讀取內置閃存模塊能夠在通用地址空間直接尋址,任何32位數據的讀操做都能訪問閃存模塊的內容並獲得相應的數據。讀接口在閃存端包含一個讀控制器,還包含一個 AHB接口與CPU銜接。這個接口的主要工做是產生讀閃存的控制信號並預取CPU要求的指令塊,預取指令塊僅用於在I-Code總線上的取指操做,數據常 量是經過D-Code總線訪問的。這兩條總線的訪問目標是相同的閃存模塊,訪問D-Code將比預取指令優先級高。 接口

這裏要特別留意一個閃存等待時間,由於CPU運行速度比FLASH快得多,STM32F103的FLASH最快訪問速度≤24Mhz,若是CPU頻率超過這 個速度,那麼必須加入等待時間,好比咱們通常使用72Mhz的主頻,那麼FLASH等待週期就必須設置爲2,該設置經過FLASH_ACR寄存器設置。 ip

例如,咱們要從地址addr,讀取一個半字(半字爲16爲,字爲32位),能夠經過以下的語句讀取:

                    data=*(vu16*)addr;

將 addr強制轉換爲vu16指針,而後取該指針所指向的地址的值,即獲得了addr地址的值。相似的,將上面的vu16該位vu8,便可讀取指定地址的一 個字節。相對FLASH讀取來講,STM32 FLASH的寫就複雜一點了,下面咱們介紹STM32閃存的編程和擦除。

       閃存的編程和擦除

STM32的閃存編程是由FPEC(閃存編程和擦除控制器)模塊處理的,這個模塊包含7個32位寄存器,他們分別是:

l  FPEC鍵寄存器(FLASH_KEYR)

l  選擇字節鍵寄存器(FLASH_OPTKEYR)

l  閃存控制寄存器(FLASH_CR)

l  閃存狀態寄存器(FLASH_SR)

l  閃存地址寄存器(FLASH_AR)

l  選擇字節寄存器(FLASH_OBR)

l  寫保護寄存器(FLASH_WRPR)

其中FPEC鍵寄存器總共有3個鍵值:

RDPRT鍵=0X000000A5

KEY1=0X45670123

KEY2=0XCDEF89AB

STM32復位後,FPEC模塊是被保護的,不能寫入FLASH_CR寄存器;經過寫入特定的序列到FLASH_KEYR寄存器能夠打開FPEC模塊(即寫入KEY1和KEY2),只有在寫保護被解除後,咱們才能操做相關寄存器。

STM32閃存的編程每次必須寫入16位(不能單純的寫入8位數據哦!),當FLASH_CR寄存器的PG位爲’1’時,在一個閃存地址寫入一個半字將啓動一次編程;寫入任何非半字的數據,FPEC都會產生總線錯誤。在編程過程當中(BSY位爲’1’),任何讀寫閃存的操做都會使CPU暫停,直到這次閃存編程結束。

一樣,STM32的FLASH在編程的時候,也必需要求其寫入地址的FLASH是被擦除了的(也就是其值必須是0XFFFF),不然沒法寫入,在FLASH_SR寄存器的PGERR位將獲得一個警告。

STM23的FLASH編程過程如圖所示:

從上圖能夠獲得閃存的編程順序以下:

l  檢查FLASH_CR的LOCK是否解鎖,若是沒有則先解鎖

l  檢查FLASH_SR寄存器的BSY位,以確認沒有其餘正在進行的編程操做

l  設置FLASH_CR寄存器的PG位爲’1’

l  在指定的地址寫入要編程的半字

l  等待BSY位變爲’0’

l  讀出寫入的地址並驗證數據

前面提到,咱們在STM32的FLASH編程的時候,要先判斷縮寫地址是否被擦除了,因此,咱們有必要再紹一下STM32的閃存擦除,STM32的閃存擦除分爲兩種:頁擦除和整片擦除。頁擦除過程以下圖所示

從上圖能夠看出,STM32的頁擦除順序爲:

l  檢查FLASH_CR的LOCK是否解鎖,若是沒有則先解鎖

l  檢查FLASH_SR寄存器的BSY位,以確認沒有其餘正在進行的閃存操做

l  設置FLASH_CR寄存器的PER位爲’1’

l  用FLASH_AR寄存器選擇要擦除的頁

l  設置FLASH_CR寄存器的STRT位爲’1’

l  等待BSY位變爲’0’

l  讀出被擦除的頁並作驗證

軟件設計:

#include "Flash.h"
u32 StartAddr = 0x0801F800;  //要寫入Flash的數據的首地址--FLASH起始地址
u32 EndAddr  = 0x0801FFFF;  //要寫入Flash的數據的末地址--FLASH結束地址
u32 FlashAddress=0x00;//Flash的內部地址	 
vu32 NbrOfPage = 0x00; //要擦除的頁面數量
u32 data = 0;
//u32 *p=(u32 *)0x08008000; //定義指針指向要傳送的數據的地址
volatile FLASH_Status FLASHStatus;
volatile TestStatus MemoryProgramStatus;
ErrorStatus HSEStartUpStatus;

/*******************************************************************************
* Function Name  : Writeflash
* Description    : 寫函數 把數據從CPU寫到FLASH中
*                
* Input          : u8 Erasenumber,u32 *Data,輸入要擦除的頁面和要寫入的數據的地址
* Output         : None
* Return         : None
*******************************************************************************/
void Writeflash(u8 Erasenumber ,u32 *p,u8 start,u8 end)
{
	int i = start;
	FLASHStatus = FLASH_COMPLETE;
   MemoryProgramStatus = PASSED;

    /* Unlock the Flash Program Erase controller */
    FLASH_Unlock();	//FLASH解鎖

    /* Clear All pending flags */
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);//清標誌位
	
//擦除後寫數據		
//*******************************************************************************  
//一次擦除1頁
      /* Define the number of page to be erased *///定義要擦出的頁面的數量
      NbrOfPage = (EndAddr - StartAddr) / FLASH_PAGE_SIZE;
	 /* Erase the FLASH pages *///頁面擦除子程序
      FLASHStatus = FLASH_ErasePage(StartAddr + (FLASH_PAGE_SIZE * NbrOfPage));
	 //寫數據
	  FlashAddress = StartAddr+4*start;
	 
      while((FlashAddress < EndAddr) && (FLASHStatus == FLASH_COMPLETE) && i<end)
      {
	     FLASHStatus = FLASH_ProgramWord(FlashAddress, *(p+i));//*p);
		 i++;
	     FlashAddress = FlashAddress + 4;
      }
}

/*******************************************************************************
* Function Name  : Readflash
* Description    : 讀數據,從FLASH中讀出須要的數據
*                
* Input          : None
* Output         : Data輸出要取出的數據
* Return         : None
*******************************************************************************/

void Readflash(u32 *p,u8 start,u8 end) //
{
   	int j = start;
    FlashAddress = StartAddr+4*start;
	//讀數據

	while(j<end)
	{
		*(p+j) = *(u32*)(FlashAddress+4*j);
		j++;
	}
}



#ifndef _FLASH_H
#define _FLASH_H
 
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_flash.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment the line corresponding to the STMicroelectronics evaluation board
   used to run the example */
#if !defined (STM32_DK_128K) &&  !defined (STM32_EK)
 //#define USE_STM3210B_EVAL
 #define STM32_EK
#endif

/* Define the STM32F10x hardware depending on the used evaluation board */
#ifdef STM32_DK_128K
  #define FLASH_PAGE_SIZE    ((u16)0x400) //1024  1K
#elif defined STM32_EK
  #define FLASH_PAGE_SIZE    ((u16)0x800) //2048   2K
#endif /* USE_STM3210B_EVAL */
/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

void Writeflash(u8 Erasenumber ,u32 *p,u8 start,u8 end);
void Readflash(u32 *p,u8 start,u8 end) ;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */

#endif /* __PLATFORM_CONFIG_H */



Writeflash(0,Var_Compensate,0,6);
Readflash(Var_Compensate,0,6)
相關文章
相關標籤/搜索