stm32 Flash 模擬EEPROM
*STM32的閃存模塊由:主存儲器、信息塊和閃存存儲器接口寄存器等3部分組成。
* 對于大容量產品 每頁2K字節
* 小容量和中容量產品則每頁只有1K字節
*
*/
/*
*
*閃存的讀取
*內置閃存模塊可以在通用地址空間直接尋址,
*任何32位數據的讀操作都能訪問閃存模塊的內容并得到相應的數據。
*這里要特別留意一個閃存等待時間,因為CPU運行速度比FLASH快得多,
*STM32F103的FLASH最快訪問速度≤24Mhz,如果CPU頻率超過這個速度,
*那么必須加入等待時間,比如我們一般使用72Mhz的主頻,那么FLASH等待周期就必須設置為2,
*該設置通過FLASH_ACR寄存器設置。
*例如,我們要從地址addr,讀取一個半字(半字為16為,字為32位),可以通過如下的語句讀取:
*data=*(vu16*)addr;
*將addr強制轉換為vu16指針,然后取該指針所指向的地址的值,
*即得到了addr地址的值。類似的,將上面的vu16該位vu8,即可讀取指定地址的一個字節。
*/
/*
*
*閃存的編程和擦除
*STM32的閃存編程是由FPEC(閃存編程和擦除控制器)模塊處理的,
*這個模塊包含7個32位寄存器,他們分別是:
*FPEC鍵寄存器(FLASH_KEYR)
*選擇字節鍵寄存器(FLASH_OPTKEYR)
*閃存控制寄存器(FLASH_CR)
*閃存狀態寄存器(FLASH_SR)
*閃存地址寄存器(FLASH_AR)
*選擇字節寄存器(FLASH_OBR)
*寫保護寄存器(FLASH_WRPR)
*STM32復位后,FPEC模塊是被保護的,不能寫入FLASH_CR寄存器;
*通過寫入特定的序列到FLASH_KEYR寄存器可以打開FPEC模塊(即寫入KEY1和KEY2),
*只有在寫保護被解除后,我們才能操作相關寄存器
*STM32閃存的編程每次必須寫入16位(不能單純的寫入8位數據哦?。?/div>



從上圖可以看出,STM32的頁擦除順序為:
主站蜘蛛池模板:
县级市|
鄢陵县|
余江县|
宜州市|
荔浦县|
柏乡县|
易门县|
鹿泉市|
青冈县|
龙井市|
冷水江市|
绥阳县|
合江县|
纳雍县|
湘阴县|
大埔县|
鄱阳县|
阿拉善盟|
屏东市|
桐柏县|
来凤县|
梧州市|
铁岭市|
弥勒县|
武义县|
津南区|
稻城县|
顺平县|
屯门区|
乌拉特后旗|
保靖县|
读书|
汾阳市|
临武县|
四会市|
佛冈县|
英德市|
辉县市|
光山县|
溧水县|
扬州市|
*當FLASH_CR寄存器的PG位為’1’時,在一個閃存地址寫入一個半字將啟動一次編程
*寫入任何非半字的數據,FPEC都會產生總線錯誤。在編程過程中(BSY位為’1’),
*任何讀寫閃存的操作都會使CPU暫停,直到此次閃存編程結束
*同樣,STM32的FLASH在編程的時候,也必須要求其寫入地址的FLASH是被擦除了的(也就是其值必須是0XFFFF),
*否則無法寫入,在FLASH_SR寄存器的PGERR位將得到一個警告
*檢查FLASH_CR的LOCK是否解鎖,如果沒有則先解鎖
*檢查FLASH_SR寄存器的BSY位,以確認沒有其他正在進行的編程操作
*設置FLASH_CR寄存器的PG位為’1’
*在指定的地址寫入要編程的半字
*等待BSY位變為’0’
*讀出寫入的地址并驗證數據
*前面提到,我們在STM32的FLASH編程的時候,要先判斷縮寫地址是否被擦除了,
*所以,我們有必要再紹一下STM32的閃存擦除,STM32的閃存擦除分為兩種:頁擦除和整片擦除。頁擦除過程如圖39.1.3所示
*STM32的頁擦除順序為:
*檢查FLASH_CR的LOCK是否解鎖,如果沒有則先解鎖
*檢查FLASH_SR寄存器的BSY位,以確認沒有其他正在進行的閃存操作
*設置FLASH_CR寄存器的PER位為’1’
*用FLASH_AR寄存器選擇要擦除的頁
*設置FLASH_CR寄存器的STRT位為’1’
*等待BSY位變為’0’
*讀出被擦除的頁并做驗證
*/
void FLASH_Unlock(void)
{
/* Authorize the FPEC of Bank1 Access */
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
#ifdef STM32F10X_XL
/* Authorize the FPEC of Bank2 Access */
FLASH->KEYR2 = FLASH_KEY1;
FLASH->KEYR2 = FLASH_KEY2;
#endif /* STM32F10X_XL */
}
void FlashEEpromInitial(void)
{
FLASH_Unlock(); //解鎖
FLASH_ErasePage(0x807F000);// 倒數第二頁
FLASH_ProgramHalfWord(0x807F000,0x000C);
FLASH_Lock();
}
關于頁擦除的地址問題:stm32 閃存編程手冊里面是這樣說的,
只要是這個頁范圍的內的地址,就會自動擦除這個頁,不一定要是起始地址或者結束地址
For Page Erase operations, this
should be updated by software to indicate the chosen page
void FlashReadInitial(void)
{
uint16_t readData=0;
//FLASH_Unlock(); //解鎖
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)== RESET); // 發送收到的數據
USART_SendData(USART1,0x0A);
readData=*(uint16_t*)0x807F000;
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)== RESET); // 發送收到的數據
USART_SendData(USART1,readData);
}
正點原子的一篇文章:
第三十九章 FLASH模擬EEPROM實驗
STM32本身沒有自帶EEPROM,但是STM32具有IAP(在應用編程)功能,所以我們可以把它的FLASH當成EEPROM來使用。本章,我們將利用STM32內部的FLASH來實現第二十八章類似的效果,不過這次我們是將數據直接存放在STM32內部,而不是存放在W25Q64。本章分為如下幾個部分:
39.1 STM32 FLASH簡介
39.2 硬件設計
39.3 軟件設計
39.4 下載驗證
39.1 STM32 FLASH簡介
不同型號的STM32,其FLASH容量也有所不同,最小的只有16K字節,最大的則達到了1024K字節。戰艦STM32開發板選擇的STM32F103ZET6的FLASH容量為512K字節,屬于大容量產品(另外還有中容量和小容量產品),大容量產品的閃存模塊組織如圖39.1.1所示:

STM32的閃存模塊由:主存儲器、信息塊和閃存存儲器接口寄存器等3部分組成。
主存儲器,該部分用來存放代碼和數據常數(如const類型的數據)。對于大容量產品,其被劃分為256頁,每頁2K字節。注意,小容量和中容量產品則每頁只有1K字節。從上圖可以看出主存儲器的起始地址就是0X08000000, B0、B1都接GND的時候,就是從0X08000000開始運行代碼的。
信息塊,該部分分為2個小部分,其中啟動程序代碼,是用來存儲ST自帶的啟動程序,用于串口下載代碼,當B0接V3.3,B1接GND的時候,運行的就是這部分代碼。用戶選擇字節,則一般用于配置寫保護、讀保護等功能,本章不作介紹。
閃存存儲器接口寄存器,該部分用于控制閃存讀寫等,是整個閃存模塊的控制機構。
對主存儲器和信息塊的寫入由內嵌的閃存編程/擦除控制器(FPEC)管理;編程與擦除的高電壓由內部產生。
在執行閃存寫操作時,任何對閃存的讀操作都會鎖住總線,在寫操作完成后讀操作才能正確地進行;既在進行寫或擦除操作時,不能進行代碼或數據的讀取操作。
閃存的讀取
內置閃存模塊可以在通用地址空間直接尋址,任何32位數據的讀操作都能訪問閃存模塊的內容并得到相應的數據。讀接口在閃存端包含一個讀控制器,還包含一個AHB接口與CPU銜接。這個接口的主要工作是產生讀閃存的控制信號并預取CPU要求的指令塊,預取指令塊僅用于在I-Code總線上的取指操作,數據常量是通過D-Code總線訪問的。這兩條總線的訪問目標是相同的閃存模塊,訪問D-Code將比預取指令優先級高。
這里要特別留意一個閃存等待時間,因為CPU運行速度比FLASH快得多,STM32F103的FLASH最快訪問速度≤24Mhz,如果CPU頻率超過這個速度,那么必須加入等待時間,比如我們一般使用72Mhz的主頻,那么FLASH等待周期就必須設置為2,該設置通過FLASH_ACR寄存器設置。
例如,我們要從地址addr,讀取一個半字(半字為16為,字為32位),可以通過如下的語句讀?。?/div>
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編程過程如圖39.1.2所示:

從上圖可以得到閃存的編程順序如下:
l 檢查FLASH_CR的LOCK是否解鎖,如果沒有則先解鎖
l 檢查FLASH_SR寄存器的BSY位,以確認沒有其他正在進行的編程操作
l 設置FLASH_CR寄存器的PG位為’1’
l 在指定的地址寫入要編程的半字
l 等待BSY位變為’0’
l 讀出寫入的地址并驗證數據
前面提到,我們在STM32的FLASH編程的時候,要先判斷縮寫地址是否被擦除了,所以,我們有必要再紹一下STM32的閃存擦除,STM32的閃存擦除分為兩種:頁擦除和整片擦除。頁擦除過程如圖39.1.3所示

從上圖可以看出,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 讀出被擦除的頁并做驗證
本章,我們只用到了STM32的頁擦除功能,整片擦除功能我們在這里就不介紹了。通過以上了解,我們基本上知道了STM32閃存的讀寫所要執行的步驟了,接下來,我們看看與讀寫相關的寄存器說明。
第一個介紹的是FPEC鍵寄存器:FLASH_KEYR。該寄存器各位描述如圖39.1.4所示:


關鍵詞:
stm32Flash模擬EEPRO
評論