<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          stm32 Flash 模擬EEPROM

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

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

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


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

          評論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();