在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于STM32的內(nèi)部Flash讀寫操作

要長高 ? 來源:物聯(lián)網(wǎng)知識 ? 作者:跋扈洋 ? 2022-06-22 14:28 ? 次閱讀

本文主要介紹STM32多種的內(nèi)部Flash讀寫方式和讀寫長文件的功能函數(shù)怎樣編寫。閱讀完本文可以使你能夠正常的完成Flash讀寫操作。

介紹

STM32 FLASH

poYBAGKytiiAUaR5AANdxqBlcTc159.png

不同型號的 STM32,其 FLASH 容量也有所不同,最小的只有 16K 字節(jié),最大的則達到了1024K 字節(jié)。本次實驗選用的STM32 開發(fā)板是F103ZET6,其 FLASH 容量為 512K 字節(jié),屬于大容量產(chǎn)品(另外還有中容量和小容量產(chǎn)品),大容量產(chǎn)品的閃存模塊組織如圖 所示:

STM32 的閃存模塊由:主存儲器、信息塊和閃存存儲器接口寄存器等 3 部分組成。
主存儲器,該部分用來存放代碼和數(shù)據(jù)常數(shù)(如 const 類型的數(shù)據(jù))。對于大容量產(chǎn)品,其被劃分為 256 頁,每頁 2K 字節(jié)。注意,小容量和中容量產(chǎn)品則每頁只有 1K 字節(jié)。從上圖可以看出主存儲器的起始地址就是0X08000000, B0、B1 都接 GND 的時候,就是從 0X08000000開始運行代碼的。
信息塊,該部分分為 2 個小部分,其中啟動程序代碼,是用來存儲 ST 自帶的啟動程序,用于串口下載代碼,當 B0 接 V3.3,B1 接 GND 的時候,運行的就是這部分代碼。用戶選擇字節(jié),則一般用于配置寫保護、讀保護等功能。
閃存存儲器接口寄存器,該部分用于控制閃存讀寫等,是整個閃存模塊的控制機構(gòu)。對主存儲器和信息塊的寫入由內(nèi)嵌的閃存編程/擦除控制器(FPEC)管理;編程與擦除的高電壓由內(nèi)部產(chǎn)生。
在執(zhí)行閃存寫操作時,任何對閃存的讀操作都會鎖住總線,在寫操作完成后讀操作才能正確地進行;既在進行寫或擦除操作時,不能進行代碼或數(shù)據(jù)的讀取操作。

閃存的編程和擦除

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

FPEC 鍵寄存器(FLASH_KEYR)

選擇字節(jié)鍵寄存器(FLASH_OPTKEYR)

閃存控制寄存器(FLASH_CR)

閃存狀態(tài)寄存器(FLASH_SR)

閃存地址寄存器(FLASH_AR)

選擇字節(jié)寄存器(FLASH_OBR)

pYYBAGKytjGAH4kgAAESlo82AWs775.png

寫保護寄存器(FLASH_WRPR)
STM32 復位后,F(xiàn)PEC 模塊是被保護的,不能寫入 FLASH_CR 寄存器;通過寫入特定的序列到 FLASH_KEYR 寄存器可以打開 FPEC 模塊,只有在寫保護被解除后,我們才能操作相關(guān)寄存器。
STM32 閃存的編程每次必須寫入 16 位(不能單純的寫入 8 位數(shù)據(jù)哦!),當 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 寫入過程如圖所示。

STM32的Flash寫入順序如下:

檢查 FLASH_CR 的 LOCK 是否解鎖,如果沒有則先解鎖

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

設置 FLASH_CR 寄存器的 PG 位為’1’

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

等待 BSY 位變?yōu)椤?’ - 讀出寫入的地址并驗證數(shù)據(jù)

Flash讀寫的標準庫函數(shù)

解鎖函數(shù):void FLASH_Unlock(void);
對 FLASH 進行寫操作前必須先解鎖,解鎖操作也就是必須在 FLASH_KEYR 寄存器寫入特定的序列,固件庫函數(shù)實現(xiàn)很簡單:只需要直接調(diào)用 FLASH_Unlock();即可。

鎖定函數(shù):void FLASH_Lock(void);
有解鎖當然就有上鎖,為了保護Flash,讀寫和擦除全部需要的Flash后需要上鎖,只需要調(diào)用:FLASH_Lock();

寫操作函數(shù):
固件庫提供了三個 FLASH 寫函數(shù):

FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);

顧名思義分別為:FLASH_ProgramWord 為 32 位字寫入函數(shù),其他分別為 16 位半字寫入和用戶選擇字節(jié)寫入函數(shù)。這里需要說明,32 位字節(jié)寫入實際上是寫入的兩次 16 位數(shù)據(jù),寫完第一次后地址+2,這與我們前面講解的 STM32 閃存的編程每次必須寫入 16 位并不矛盾。寫入 8位實際也是占用的兩個地址了,跟寫入 16 位基本上沒啥區(qū)別。
4. 獲取 FLASH 狀態(tài)
主要是用的函數(shù)是:FLASH_Status FLASH_GetStatus(void);
返回值是通過枚舉類型定義的,分別為:
FLASH_BUSY = 1,//忙
FLASH_ERROR_PG,//編程錯誤
FLASH_ERROR_WRP,//寫保護錯誤
FLASH_COMPLETE,//操作完成
FLASH_TIMEOUT//操作超時
5. 等待操作完成函數(shù)
在執(zhí)行閃存寫操作時,任何對閃存的讀操作都會鎖住總線,在寫操作完成后讀操作才能正確地進行;既在進行寫或擦除操作時,不能進行代碼或數(shù)據(jù)的讀取操作。
所以在每次操作之前,我們都要等待上一次操作完成這次操作才能開始。使用的函數(shù)是:FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)入口參數(shù)為等待時間,返回值是 FLASH 的狀態(tài),這個很容易理解,這個函數(shù)本身我們在固件庫中使用得不多,但是在固件庫函數(shù)體中間可以多次看到。
6. 讀 FLASH 特定地址數(shù)據(jù)函數(shù)
有寫就必定有讀,而讀取 FLASH 指定地址的半字的函數(shù)固件庫并沒有給出來,這里我們自己寫的一個函數(shù)。

u16 STMFLASH_ReadHalfWord(u32 faddr){return *(vu16*)faddr; }

軟件設計

FLASH的讀取

直接讀取某一地址的內(nèi)容

因為讀取FLASH并不需要解鎖,我們可以直接用指針指向所讀的地址,之后讀取此地址的內(nèi)容即可。

p = (uint32_t *)(0x08008000);printf("\r\n讀取內(nèi)部FLASH該地址存儲的內(nèi)容為:0x%x",*p);

此程序就是先將0x08008000賦給指針變量P,之后將P指向地址的內(nèi)容以16進制的格式輸出出來。

讀取選定位置的選定大小的內(nèi)容

首先我們編寫一個函數(shù),用以讀取指定地址的半字(16位數(shù)據(jù))。

u16 STMFLASH_ReadHalfWord(u32 faddr){
	return *(vu16*)faddr; }

從指定地址開始讀出指定長度的數(shù)據(jù)

LReadAddr:起始地址

pBuffer:數(shù)據(jù)指針

NumToWrite:半字(16位)數(shù)

void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)   	{
	u16 i;
	for(i=0;i

當我們想讀取FLASH內(nèi)容時,只需要直接調(diào)用上面的函數(shù)即可。

STMFLASH_Read(FLASH_ADDR,Temporary_storage,size);

這里FLASH_ADDR是我們要讀取的起始地址,Temporary_storage是
16位的指針變量,存放我們讀取到的內(nèi)容, size是我們要讀取的大小,值得注意的是,size是半字大小,也就是有多少個兩個字節(jié)。比如我們要讀取100個字節(jié),size就可以填50。

FLASH的寫入

直接使用標準庫寫入

首先需要先解鎖

FLASH_Unlock(); 

寫入前需要擦除當前頁,對擦除有不理解的可以看我的另一篇文章:基于STM32的Flash擦除方式

FLASH_ErasePage(0x08000000+2*1024*5);

之后可以調(diào)用固件庫函數(shù),進行寫入。例如向地址 0x08000000+210245 至 0x08000000+210246 地址寫入數(shù)據(jù)

FLASH_ProgramWord(0x08000000+2*1024*5,0x01234567);

寫入之后,不要忘了上鎖。

FLASH_Lock();

寫入選定位置的選定大小的內(nèi)容

我們首先編寫一個不檢查的寫入的函數(shù)。
WriteAddr:起始地址,pBuffer:數(shù)據(jù)指針,NumToWrite:半字(16位)數(shù) 。

void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   { 			 		 
	u16 i;
	for(i=0;i

之后編寫函數(shù),實現(xiàn)從指定地址寫入指定大小的指定內(nèi)容。

void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)	{
	u32 secpos;	   //扇區(qū)地址
	u16 secoff;	   //扇區(qū)內(nèi)偏移地址(16位字計算)
	u16 secremain; //扇區(qū)內(nèi)剩余地址(16位字計算)	   
 	u16 i;    
	u32 offaddr;   //去掉0X08000000后的地址
	if(WriteAddr=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
	FLASH_Unlock();						//解鎖
	offaddr=WriteAddr-STM32_FLASH_BASE;		//實際偏移地址.
	secpos=offaddr/STM_SECTOR_SIZE;			//扇區(qū)地址  0~127 for STM32F103RBT6
	secoff=(offaddr%STM_SECTOR_SIZE)/2;		//在扇區(qū)內(nèi)的偏移(2個字節(jié)為基本單位.)
	secremain=STM_SECTOR_SIZE/2-secoff;		//扇區(qū)剩余空間大小   
	if(NumToWrite<=secremain)secremain=NumToWrite;//不大于該扇區(qū)范圍
	while(1) 
	{	
		STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//讀出整個扇區(qū)的內(nèi)容
		for(i=0;i(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一個扇區(qū)還是寫不完
			else secremain=NumToWrite;//下一個扇區(qū)可以寫完了
		}	 
	};	
	FLASH_Lock();//上鎖}

使用時,我們只需要當我們功能需要寫入Flash時,調(diào)用此函數(shù)即可。

STMFLASH_Write(FLASH_ADDR,flg_false,size);//將標志位置為更改為0x00

此語句實現(xiàn)從FLASH_ADDR地址寫入size大小的Temporary_storage數(shù)據(jù)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5359

    瀏覽量

    120795
  • FlaSh
    +關(guān)注

    關(guān)注

    10

    文章

    1640

    瀏覽量

    148298
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10915

    瀏覽量

    356754
收藏 人收藏

    評論

    相關(guān)推薦

    stm32內(nèi)部flash讀寫

    stm32內(nèi)部flash讀寫,stm32內(nèi)部flash
    發(fā)表于 08-05 07:23

    通過對stm32內(nèi)部flash讀寫可以實現(xiàn)對stm32的編程操作

    一、Flash簡介  通過對stm32內(nèi)部flash讀寫可以實現(xiàn)對stm32的編程
    發(fā)表于 08-05 07:56

    flash讀寫可實現(xiàn)對stm32的編程操作

    stm32——Flash讀寫一、Flash簡介  通過對stm32內(nèi)部
    發(fā)表于 08-05 06:54

    如何操作芯片內(nèi)部EEprom讀寫數(shù)據(jù)

    概述本篇文章介紹如何使用STM32HAL庫,本案例只要介紹如何操作芯片內(nèi)部EEprom讀寫數(shù)據(jù),類似操作
    發(fā)表于 08-09 06:12

    怎樣對STM32內(nèi)部FLASH進行讀寫操作

    怎樣對STM32內(nèi)部FLASH進行讀寫操作呢?其讀寫步驟有哪些呢?
    發(fā)表于 10-26 07:17

    STM32怎么讀寫內(nèi)部flash的注意點呢

    STM32讀寫內(nèi)部flash注意點先說注意點怎么寫怎么讀的總結(jié)先說注意點1、寫之前的第一步是要先解鎖flash,解鎖后最好清除下所有的fla
    發(fā)表于 01-26 06:09

    讀寫STM32內(nèi)部FLASH問題解析

    不是那種讀寫外掛FLASH芯片的,而是讀寫STM32內(nèi)部FLASH的。我參考網(wǎng)上的資料寫了
    發(fā)表于 01-09 16:46

    STM32_ SPI讀寫Flash

    STM32_SPI讀寫Flash
    的頭像 發(fā)表于 04-08 10:26 ?5618次閱讀
    <b class='flag-5'>STM32</b>_ SPI<b class='flag-5'>讀寫</b><b class='flag-5'>Flash</b>

    STM32內(nèi)部Flash讀寫問題

    讀寫要注意幾點keil的.map文件中包含了什么操作不當導致Flash損壞會怎樣Flash上鎖與解鎖Keil編譯器如何查看MCU寄存器的值Flash
    發(fā)表于 12-01 20:21 ?20次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>內(nèi)部</b><b class='flag-5'>Flash</b><b class='flag-5'>讀寫</b>問題

    STM32F103:內(nèi)部Flash讀寫

    64-128KB(STM32F10X_MD)3、大容量產(chǎn)品:Flash大小為256KB以上(STM32F10X_HD)2. ST庫函數(shù)ST庫中對Flash
    發(fā)表于 12-01 20:51 ?15次下載
    <b class='flag-5'>STM32</b>F103:<b class='flag-5'>內(nèi)部</b><b class='flag-5'>Flash</b>的<b class='flag-5'>讀寫</b>

    HAL庫之讀寫STM32F103內(nèi)部FLASH空間

    在此聲明——本文摘自這里:【碼神島】STM32F0x HAL庫學習筆記(5)片內(nèi)FLASH讀寫操作本文開發(fā)環(huán)境MCU型號:STM32F10
    發(fā)表于 12-01 20:51 ?23次下載
    HAL庫之<b class='flag-5'>讀寫</b><b class='flag-5'>STM32</b>F103<b class='flag-5'>內(nèi)部</b>的<b class='flag-5'>FLASH</b>空間

    STM32讀寫內(nèi)部flash注意點

    STM32讀寫內(nèi)部flash注意點先說注意點怎么寫怎么讀的總結(jié)先說注意點1、寫之前的第一步是要先解鎖flash,解鎖后最好清除下所有的fla
    發(fā)表于 12-02 11:21 ?7次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>讀寫</b><b class='flag-5'>內(nèi)部</b><b class='flag-5'>flash</b>注意點

    STM32F4內(nèi)部Flash讀寫

    之前的文章中介紹過STM32F0列的內(nèi)部Flash讀寫STM32CubeMX之內(nèi)部
    發(fā)表于 12-02 11:36 ?32次下載
    <b class='flag-5'>STM32</b>F4<b class='flag-5'>內(nèi)部</b><b class='flag-5'>Flash</b><b class='flag-5'>讀寫</b>

    STM32 內(nèi)部Flash讀寫 程序源碼 [已驗證]

    由于STM32 系列Flash的Erase功能都是按Page擦除,所以想往Flash寫入某一段數(shù)據(jù),又想保持其他數(shù)據(jù)不變的話,就要做緩存讀寫,這一塊目前
    發(fā)表于 12-02 12:06 ?11次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>內(nèi)部</b><b class='flag-5'>Flash</b><b class='flag-5'>讀寫</b> 程序源碼 [已驗證]

    STM32CUBEIDE(16)----內(nèi)部Flash讀寫

    本例程主要講解如何對芯片自帶Flash進行讀寫,用芯片內(nèi)部Flash可以對一些需要斷電保存的數(shù)據(jù)進行保存,無需加外部得存儲芯片,本例程采用的是STM
    的頭像 發(fā)表于 07-27 09:24 ?1629次閱讀
    <b class='flag-5'>STM32</b>CUBEIDE(16)----<b class='flag-5'>內(nèi)部</b><b class='flag-5'>Flash</b><b class='flag-5'>讀寫</b>
    主站蜘蛛池模板: 天天视频国产免费入口| 成人激情综合网| 99久久婷婷国产综合精品电影 | 一区视频| 日本口工福利漫画无遮挡| 国模欢欢大尺度| 亚洲人在线| 色五夜婷婷| 免费国产一区二区三区| 国产精品美女自在线观看免费| 在线观看免费xx高清视频| 日日夜夜天天操| 亚洲成a人片毛片在线| 亚洲图片 欧美色图| 深爱开心激情网| 免费黄色福利视频| 国产经典一区| 天天干天天操天天做| 国产全部理论片线观看| 22eee在线播放成人免费视频| 美女被网站免费看九色视频| 午夜黄色大片| 日韩色天使综合色视频| 九色 在线| 天天在线看片| 欧洲三级网站| 与子乱刺激对白在线播放| 日韩视频高清| 成人黄色激情网| 久久久久久国产精品免费免 | 天天干天天骑| 狼色网| 一级片免费在线| 欧美成人性色xxxxx视频大| 成人种子| 国外免费精品视频在线观看| 日不卡| 日韩欧美一卡二区| aaa大片| 欧美专区欧美吧| 亚洲国产成人在线|