新聞中心

stm32 Flash 模擬EEPROM

作者: 時(shí)間:2016-11-13 來(lái)源:網(wǎng)絡(luò) 收藏
/*
*STM32的閃存模塊由:主存儲(chǔ)器、信息塊和閃存存儲(chǔ)器接口寄存器等3部分組成。
* 對(duì)于大容量產(chǎn)品 每頁(yè)2K字節(jié)
* 小容量和中容量產(chǎn)品則每頁(yè)只有1K字節(jié)
*
*/
/*
*
*閃存的讀取
*內(nèi)置閃存模塊可以在通用地址空間直接尋址,
*任何32位數(shù)據(jù)的讀操作都能訪問(wèn)閃存模塊的內(nèi)容并得到相應(yīng)的數(shù)據(jù)。
*這里要特別留意一個(gè)閃存等待時(shí)間,因?yàn)镃PU運(yùn)行速度比FLASH快得多,
*STM32F103的FLASH最快訪問(wèn)速度≤24Mhz,如果CPU頻率超過(guò)這個(gè)速度,
*那么必須加入等待時(shí)間,比如我們一般使用72Mhz的主頻,那么FLASH等待周期就必須設(shè)置為2,
*該設(shè)置通過(guò)FLASH_ACR寄存器設(shè)置。
*例如,我們要從地址addr,讀取一個(gè)半字(半字為16為,字為32位),可以通過(guò)如下的語(yǔ)句讀取:
*data=*(vu16*)addr;
*將addr強(qiáng)制轉(zhuǎn)換為vu16指針,然后取該指針?biāo)赶虻牡刂返闹担?/div>
*即得到了addr地址的值。類似的,將上面的vu16該位vu8,即可讀取指定地址的一個(gè)字節(jié)。
*/
/*
*
*閃存的編程和擦除
*STM32的閃存編程是由FPEC(閃存編程和擦除控制器)模塊處理的,
*這個(gè)模塊包含7個(gè)32位寄存器,他們分別是:
*FPEC鍵寄存器(FLASH_KEYR)
*選擇字節(jié)鍵寄存器(FLASH_OPTKEYR)
*閃存控制寄存器(FLASH_CR)
*閃存狀態(tài)寄存器(FLASH_SR)
*閃存地址寄存器(FLASH_AR)
*選擇字節(jié)寄存器(FLASH_OBR)
*寫(xiě)保護(hù)寄存器(FLASH_WRPR)
*STM32復(fù)位后,F(xiàn)PEC模塊是被保護(hù)的,不能寫(xiě)入FLASH_CR寄存器;
*通過(guò)寫(xiě)入特定的序列到FLASH_KEYR寄存器可以打開(kāi)FPEC模塊(即寫(xiě)入KEY1和KEY2),
*只有在寫(xiě)保護(hù)被解除后,我們才能操作相關(guān)寄存器
*STM32閃存的編程每次必須寫(xiě)入16位(不能單純的寫(xiě)入8位數(shù)據(jù)哦?。?,
*當(dāng)FLASH_CR寄存器的PG位為’1’時(shí),在一個(gè)閃存地址寫(xiě)入一個(gè)半字將啟動(dòng)一次編程
*寫(xiě)入任何非半字的數(shù)據(jù),F(xiàn)PEC都會(huì)產(chǎn)生總線錯(cuò)誤。在編程過(guò)程中(BSY位為’1’),
*任何讀寫(xiě)閃存的操作都會(huì)使CPU暫停,直到此次閃存編程結(jié)束
*同樣,STM32的FLASH在編程的時(shí)候,也必須要求其寫(xiě)入地址的FLASH是被擦除了的(也就是其值必須是0XFFFF),
*否則無(wú)法寫(xiě)入,在FLASH_SR寄存器的PGERR位將得到一個(gè)警告
*檢查FLASH_CR的LOCK是否解鎖,如果沒(méi)有則先解鎖
*檢查FLASH_SR寄存器的BSY位,以確認(rèn)沒(méi)有其他正在進(jìn)行的編程操作
*設(shè)置FLASH_CR寄存器的PG位為’1’
*在指定的地址寫(xiě)入要編程的半字
*等待BSY位變?yōu)?rsquo;0’
*讀出寫(xiě)入的地址并驗(yàn)證數(shù)據(jù)
*前面提到,我們?cè)赟TM32的FLASH編程的時(shí)候,要先判斷縮寫(xiě)地址是否被擦除了,
*所以,我們有必要再紹一下STM32的閃存擦除,STM32的閃存擦除分為兩種:頁(yè)擦除和整片擦除。頁(yè)擦除過(guò)程如圖39.1.3所示
*STM32的頁(yè)擦除順序?yàn)椋?/div>
*檢查FLASH_CR的LOCK是否解鎖,如果沒(méi)有則先解鎖
*檢查FLASH_SR寄存器的BSY位,以確認(rèn)沒(méi)有其他正在進(jìn)行的閃存操作
*設(shè)置FLASH_CR寄存器的PER位為’1’
*用FLASH_AR寄存器選擇要擦除的頁(yè)
*設(shè)置FLASH_CR寄存器的STRT位為’1’
*等待BSY位變?yōu)?rsquo;0’
*讀出被擦除的頁(yè)并做驗(yàn)證
*/
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);// 倒數(shù)第二頁(yè)
FLASH_ProgramHalfWord(0x807F000,0x000C);
FLASH_Lock();
}
關(guān)于頁(yè)擦除的地址問(wèn)題:stm32 閃存編程手冊(cè)里面是這樣說(shuō)的,
只要是這個(gè)頁(yè)范圍的內(nèi)的地址,就會(huì)自動(dòng)擦除這個(gè)頁(yè),不一定要是起始地址或者結(jié)束地址
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); // 發(fā)送收到的數(shù)據(jù)
USART_SendData(USART1,0x0A);
readData=*(uint16_t*)0x807F000;
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)== RESET); // 發(fā)送收到的數(shù)據(jù)
USART_SendData(USART1,readData);
}

正點(diǎn)原子的一篇文章:
第三十九章 FLASH模擬EEPROM實(shí)驗(yàn)
STM32本身沒(méi)有自帶EEPROM,但是STM32具有IAP(在應(yīng)用編程)功能,所以我們可以把它的FLASH當(dāng)成EEPROM來(lái)使用。本章,我們將利用STM32內(nèi)部的FLASH來(lái)實(shí)現(xiàn)第二十八章類似的效果,不過(guò)這次我們是將數(shù)據(jù)直接存放在STM32內(nèi)部,而不是存放在W25Q64。本章分為如下幾個(gè)部分:
39.1 STM32 FLASH簡(jiǎn)介
39.2 硬件設(shè)計(jì)
39.3 軟件設(shè)計(jì)
39.4 下載驗(yàn)證
39.1 STM32 FLASH簡(jiǎn)介
不同型號(hào)的STM32,其FLASH容量也有所不同,最小的只有16K字節(jié),最大的則達(dá)到了1024K字節(jié)。戰(zhàn)艦STM32開(kāi)發(fā)板選擇的STM32F103ZET6的FLASH容量為512K字節(jié),屬于大容量產(chǎn)品(另外還有中容量和小容量產(chǎn)品),大容量產(chǎn)品的閃存模塊組織如圖39.1.1所示:
STM32的閃存模塊由:主存儲(chǔ)器、信息塊和閃存存儲(chǔ)器接口寄存器等3部分組成。
主存儲(chǔ)器,該部分用來(lái)存放代碼和數(shù)據(jù)常數(shù)(如const類型的數(shù)據(jù))。對(duì)于大容量產(chǎn)品,其被劃分為256頁(yè),每頁(yè)2K字節(jié)。注意,小容量和中容量產(chǎn)品則每頁(yè)只有1K字節(jié)。從上圖可以看出主存儲(chǔ)器的起始地址就是0X08000000, B0、B1都接GND的時(shí)候,就是從0X08000000開(kāi)始運(yùn)行代碼的。
信息塊,該部分分為2個(gè)小部分,其中啟動(dòng)程序代碼,是用來(lái)存儲(chǔ)ST自帶的啟動(dòng)程序,用于串口下載代碼,當(dāng)B0接V3.3,B1接GND的時(shí)候,運(yùn)行的就是這部分代碼。用戶選擇字節(jié),則一般用于配置寫(xiě)保護(hù)、讀保護(hù)等功能,本章不作介紹。
閃存存儲(chǔ)器接口寄存器,該部分用于控制閃存讀寫(xiě)等,是整個(gè)閃存模塊的控制機(jī)構(gòu)。
對(duì)主存儲(chǔ)器和信息塊的寫(xiě)入由內(nèi)嵌的閃存編程/擦除控制器(FPEC)管理;編程與擦除的高電壓由內(nèi)部產(chǎn)生。
在執(zhí)行閃存寫(xiě)操作時(shí),任何對(duì)閃存的讀操作都會(huì)鎖住總線,在寫(xiě)操作完成后讀操作才能正確地進(jìn)行;既在進(jìn)行寫(xiě)或擦除操作時(shí),不能進(jìn)行代碼或數(shù)據(jù)的讀取操作。
閃存的讀取
內(nèi)置閃存模塊可以在通用地址空間直接尋址,任何32位數(shù)據(jù)的讀操作都能訪問(wèn)閃存模塊的內(nèi)容并得到相應(yīng)的數(shù)據(jù)。讀接口在閃存端包含一個(gè)讀控制器,還包含一個(gè)AHB接口與CPU銜接。這個(gè)接口的主要工作是產(chǎn)生讀閃存的控制信號(hào)并預(yù)取CPU要求的指令塊,預(yù)取指令塊僅用于在I-Code總線上的取指操作,數(shù)據(jù)常量是通過(guò)D-Code總線訪問(wèn)的。這兩條總線的訪問(wèn)目標(biāo)是相同的閃存模塊,訪問(wèn)D-Code將比預(yù)取指令優(yōu)先級(jí)高。
這里要特別留意一個(gè)閃存等待時(shí)間,因?yàn)镃PU運(yùn)行速度比FLASH快得多,STM32F103的FLASH最快訪問(wèn)速度≤24Mhz,如果CPU頻率超過(guò)這個(gè)速度,那么必須加入等待時(shí)間,比如我們一般使用72Mhz的主頻,那么FLASH等待周期就必須設(shè)置為2,該設(shè)置通過(guò)FLASH_ACR寄存器設(shè)置。
例如,我們要從地址addr,讀取一個(gè)半字(半字為16為,字為32位),可以通過(guò)如下的語(yǔ)句讀?。?/div>
data=*(vu16*)addr;
將addr強(qiáng)制轉(zhuǎn)換為vu16指針,然后取該指針?biāo)赶虻牡刂返闹担吹玫搅薬ddr地址的值。類似的,將上面的vu16該位vu8,即可讀取指定地址的一個(gè)字節(jié)。相對(duì)FLASH讀取來(lái)說(shuō),STM32 FLASH的寫(xiě)就復(fù)雜一點(diǎn)了,下面我們介紹STM32閃存的編程和擦除。
閃存的編程和擦除
STM32的閃存編程是由FPEC(閃存編程和擦除控制器)模塊處理的,這個(gè)模塊包含7個(gè)32位寄存器,他們分別是:
l FPEC鍵寄存器(FLASH_KEYR)
l 選擇字節(jié)鍵寄存器(FLASH_OPTKEYR)
l 閃存控制寄存器(FLASH_CR)
l 閃存狀態(tài)寄存器(FLASH_SR)
l 閃存地址寄存器(FLASH_AR)
l 選擇字節(jié)寄存器(FLASH_OBR)
l 寫(xiě)保護(hù)寄存器(FLASH_WRPR)
其中FPEC鍵寄存器總共有3個(gè)鍵值:
RDPRT鍵=0X000000A5
KEY1=0X45670123
KEY2=0XCDEF89AB
STM32復(fù)位后,F(xiàn)PEC模塊是被保護(hù)的,不能寫(xiě)入FLASH_CR寄存器;通過(guò)寫(xiě)入特定的序列到FLASH_KEYR寄存器可以打開(kāi)FPEC模塊(即寫(xiě)入KEY1和KEY2),只有在寫(xiě)保護(hù)被解除后,我們才能操作相關(guān)寄存器。
STM32閃存的編程每次必須寫(xiě)入16位(不能單純的寫(xiě)入8位數(shù)據(jù)哦?。?,當(dāng)FLASH_CR寄存器的PG位為’1’時(shí),在一個(gè)閃存地址寫(xiě)入一個(gè)半字將啟動(dòng)一次編程;寫(xiě)入任何非半字的數(shù)據(jù),F(xiàn)PEC都會(huì)產(chǎn)生總線錯(cuò)誤。在編程過(guò)程中(BSY位為’1’),任何讀寫(xiě)閃存的操作都會(huì)使CPU暫停,直到此次閃存編程結(jié)束。
同樣,STM32的FLASH在編程的時(shí)候,也必須要求其寫(xiě)入地址的FLASH是被擦除了的(也就是其值必須是0XFFFF),否則無(wú)法寫(xiě)入,在FLASH_SR寄存器的PGERR位將得到一個(gè)警告。
STM23的FLASH編程過(guò)程如圖39.1.2所示:
從上圖可以得到閃存的編程順序如下:
l 檢查FLASH_CR的LOCK是否解鎖,如果沒(méi)有則先解鎖
l 檢查FLASH_SR寄存器的BSY位,以確認(rèn)沒(méi)有其他正在進(jìn)行的編程操作
l 設(shè)置FLASH_CR寄存器的PG位為’1’
l 在指定的地址寫(xiě)入要編程的半字
l 等待BSY位變?yōu)?rsquo;0’
l 讀出寫(xiě)入的地址并驗(yàn)證數(shù)據(jù)
前面提到,我們?cè)赟TM32的FLASH編程的時(shí)候,要先判斷縮寫(xiě)地址是否被擦除了,所以,我們有必要再紹一下STM32的閃存擦除,STM32的閃存擦除分為兩種:頁(yè)擦除和整片擦除。頁(yè)擦除過(guò)程如圖39.1.3所示

從上圖可以看出,STM32的頁(yè)擦除順序?yàn)椋?div>l 檢查FLASH_CR的LOCK是否解鎖,如果沒(méi)有則先解鎖
l 檢查FLASH_SR寄存器的BSY位,以確認(rèn)沒(méi)有其他正在進(jìn)行的閃存操作
l 設(shè)置FLASH_CR寄存器的PER位為’1’
l 用FLASH_AR寄存器選擇要擦除的頁(yè)
l 設(shè)置FLASH_CR寄存器的STRT位為’1’
l 等待BSY位變?yōu)?rsquo;0’
l 讀出被擦除的頁(yè)并做驗(yàn)證
本章,我們只用到了STM32的頁(yè)擦除功能,整片擦除功能我們?cè)谶@里就不介紹了。通過(guò)以上了解,我們基本上知道了STM32閃存的讀寫(xiě)所要執(zhí)行的步驟了,接下來(lái),我們看看與讀寫(xiě)相關(guān)的寄存器說(shuō)明。
第一個(gè)介紹的是FPEC鍵寄存器:FLASH_KEYR。該寄存器各位描述如圖39.1.4所示:


關(guān)鍵詞: stm32Flash模擬EEPRO

評(píng)論


技術(shù)專區(qū)

關(guān)閉