STM32F407 Flash操作筆記


簡述

STM32F4XX的閃存擦除方式分為兩種:扇區擦除(最小單元16K)和整片擦除。在實際應用中,為滿足重要信息的存儲,需將信息存入FLASH中,針對以上兩種擦除方式,扇區擦除更符合實際的需要。
參考手冊:
閃存模塊組織

寫FLASH操作

扇區擦除流程
經過以上五個步,就可以擦除某個扇區。但是實際運用過程中,一個扇區只存儲一個信息或標志,會造成資源嚴重浪費。現采用緩存的方式,先讀取當下扇區的數據,將讀取的數據和要寫入的數據組合,待擦除后再次寫入。

代碼片

  • 寫FLASH操作
/* * WriteAddr: 起始地址 (u32)address 是 4 的整數倍, (u32)data * pBuffer: 數據指針 * NumToWrite:字(u32)數 */ void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite) { FLASH_Status status = FLASH_COMPLETE; u32 addrx=0; u32 endaddr=0; if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return; //非法地址 FLASH_Unlock();//解鎖 FLASH_DataCacheCmd(DISABLE);//FLASH擦除期間,必須禁止數據緩存 addrx=WriteAddr; //寫入起始地址 endaddr=WriteAddr+NumToWrite*4; //寫入結束地址 if(addrx<0X1FFF0000) //是否為主存儲區 { while(addrx<endaddr) //對非0XFFFF FFFF 的地方,先擦除 { if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//對非0XFFFF FFFF 的地方,先擦除 { status=FLASH_EraseSector(GetSector(addrx),VoltageRange_3);//VCC=2.7~3.6V之間!! if(status!=FLASH_COMPLETE)break; //異常 }else addrx+=4; } } if(status==FLASH_COMPLETE) { while(WriteAddr<endaddr)//寫數據 { if(FLASH_ProgramWord(WriteAddr,*pBuffer)!=FLASH_COMPLETE)//寫入數據 { break; //寫入異常 } WriteAddr+=4; pBuffer++; } } FLASH_DataCacheCmd(ENABLE);//FLASH擦除結束,開啟數據緩存 FLASH_Lock();//上鎖 Printf("Flash status :%d\r\n",status); }
 

 

  • 數據流存儲
#define SectorLen 128 //數據長度 128 * 4 = 512 結合實際需要長度調整 /* * (u32)address 是 4 的整數倍, (u32)data * FreeStart( 0x08008000 )~FreeEnd( 0x08010000 ) */ void SaveDataToFlash( u32 address, u32 data ) { FLASH_Status status = FLASH_COMPLETE; u32 site[SectorLen] = {FreeStart}, FlashBuffer[SectorLen] = {0}; for ( u8 i = 0; i < SectorLen; i ++ )//讀取扇區數據,隨即擦除 { // if ( STMFLASH_ReadWord( site[i] ) != 0XFFFFFFFF)//0XFFFFFFFF代表無數據 { FlashBuffer[i] = STMFLASH_ReadWord( site[i] ); site[ i + 1 ] = site[i] + 4; if ( address == site[i] ) FlashBuffer[i] = data; } } FLASH_Unlock();//解鎖 FLASH_DataCacheCmd(DISABLE);//FLASH擦除期間,必須禁止數據緩存 status = FLASH_EraseSector( GetSector( address ), VoltageRange_3 );//VCC=2.7~3.6V之間!! if ( status == FLASH_COMPLETE ) { for (u8 i = 0; i < SectorLen; i ++) { if ( FLASH_ProgramWord( site[i], FlashBuffer[i] ) != FLASH_COMPLETE )//寫入數據 { break; //寫入異常 } } } FLASH_DataCacheCmd(ENABLE); //FLASH擦除結束,開啟數據緩存 FLASH_Lock();//上鎖 Printf("Save status = %d\r\n",status); // return addr; }
 

 

讀FLASH操作

STM23F4 的 FLASH 讀取是很簡單的。例如,我們要從地址 addr,讀取一個字(字節為 8位, 半字為 16 位,字為 32 位),可以通過如下的語句讀取:data=(vu32)addr;
將 addr 強制轉換為 vu32 指針,然后取該指針所指向的地址的值,即得到了 addr 地址的值。

代碼片

/* *faddr :讀地址 *return:對應數據 */ u32 STMFLASH_ReadWord(u32 faddr) { return *(vu32*)faddr; } //讀FLASH操作 /* * ReadAddr :起始地址 (u32)address 是 4 的整數倍, (u32)data * pBuffer :數據指針 * NumToRead :字(4位)數 */ void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead) { u32 i; for(i=0;i<NumToRead;i++) { pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//讀取4個字節 ReadAddr+=4;//偏移4個字節 } }
 
  • 調試注意事項
  • 在FLASH讀寫操作時,未使用數據類型(u32),致讀到的數據一直為:-1(0xFFFF FFFF 默認值,即該地址寫數據失敗) ;
  • 主存儲區<0x0800 0000 ~ 0x080F FFFF>,存儲數據地址小於0x0800 0000,存儲出錯,主控無響應。在寫操作時,一定要保證其 Address 有效!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM