欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: STM32 FLASH 模擬EEPROM程序 [打印本頁]

作者: climberwin    時間: 2020-2-21 09:53
標(biāo)題: STM32 FLASH 模擬EEPROM程序
單片機(jī)源程序如下:
  1. #include "stmflash.h"
  2. #include "delay.h"




  3. //讀取指定地址的半字(16位數(shù)據(jù))
  4. //faddr:讀地址(此地址必須為2的倍數(shù)!!)
  5. //返回值:對應(yīng)數(shù)據(jù).
  6. u16 STMFLASH_ReadHalfWord(u32 faddr)
  7. {
  8.         return *(vu16*)faddr;
  9. }
  10. #if STM32_FLASH_WREN        //如果使能了寫   
  11. //不檢查的寫入
  12. //WriteAddr:起始地址
  13. //pBuffer:數(shù)據(jù)指針
  14. //NumToWrite:半字(16位)數(shù)   
  15. void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   
  16. {                                           
  17.         u16 i;
  18.         for(i=0;i<NumToWrite;i++)
  19.         {
  20.                 FLASH_ProgramHalfWord(WriteAddr,pBuffer[i]);
  21.             WriteAddr+=2;//地址增加2.
  22.         }  
  23. }
  24. //從指定地址開始寫入指定長度的數(shù)據(jù)
  25. //WriteAddr:起始地址(此地址必須為2的倍數(shù)!!)
  26. //pBuffer:數(shù)據(jù)指針
  27. //NumToWrite:半字(16位)數(shù)(就是要寫入的16位數(shù)據(jù)的個數(shù).)
  28. #if STM32_FLASH_SIZE<256
  29. #define STM_SECTOR_SIZE 1024 //字節(jié)
  30. #else
  31. #define STM_SECTOR_SIZE        2048
  32. #endif                 
  33. u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];//最多是2K字節(jié)
  34. void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)       
  35. {
  36.         u32 secpos;           //扇區(qū)地址
  37.         u16 secoff;           //扇區(qū)內(nèi)偏移地址(16位字計算)
  38.         u16 secremain; //扇區(qū)內(nèi)剩余地址(16位字計算)          
  39.         u16 i;   
  40.         u32 offaddr;   //去掉0X08000000后的地址
  41.         if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
  42.         FLASH_Unlock();                                                //解鎖
  43.         offaddr=WriteAddr-STM32_FLASH_BASE;                //實(shí)際偏移地址.
  44.         secpos=offaddr/STM_SECTOR_SIZE;                        //扇區(qū)地址  0~127 for STM32F103RBT6
  45.         secoff=(offaddr%STM_SECTOR_SIZE)/2;                //在扇區(qū)內(nèi)的偏移(2個字節(jié)為基本單位.)
  46.         secremain=STM_SECTOR_SIZE/2-secoff;                //扇區(qū)剩余空間大小   
  47.         if(NumToWrite<=secremain)secremain=NumToWrite;//不大于該扇區(qū)范圍
  48.         while(1)
  49.         {       
  50.                 STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//讀出整個扇區(qū)的內(nèi)容
  51.                 for(i=0;i<secremain;i++)//校驗(yàn)數(shù)據(jù)
  52.                 {
  53.                         if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除            
  54.                 }
  55.                 if(i<secremain)//需要擦除
  56.                 {
  57.                         FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);//擦除這個扇區(qū)
  58.                         for(i=0;i<secremain;i++)//復(fù)制
  59.                         {
  60.                                 STMFLASH_BUF[i+secoff]=pBuffer[i];          
  61.                         }
  62.                         STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//寫入整個扇區(qū)  
  63.                 }else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//寫已經(jīng)擦除了的,直接寫入扇區(qū)剩余區(qū)間.                                   
  64.                 if(NumToWrite==secremain)break;//寫入結(jié)束了
  65.                 else//寫入未結(jié)束
  66.                 {
  67.                         secpos++;                                //扇區(qū)地址增1
  68.                         secoff=0;                                //偏移位置為0          
  69.                            pBuffer+=secremain;          //指針偏移
  70.                         WriteAddr+=secremain;        //寫地址偏移          
  71.                            NumToWrite-=secremain;        //字節(jié)(16位)數(shù)遞減
  72.                         if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一個扇區(qū)還是寫不完
  73.                         else secremain=NumToWrite;//下一個扇區(qū)可以寫完了
  74.                 }         
  75.         };       
  76.         FLASH_Lock();//上鎖
  77. }
  78. #endif

  79. //從指定地址開始讀出指定長度的數(shù)據(jù)
  80. //ReadAddr:起始地址
  81. //pBuffer:數(shù)據(jù)指針
  82. //NumToWrite:半字(16位)數(shù)
  83. void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)          
  84. {
  85.         u16 i;
  86.         for(i=0;i<NumToRead;i++)
  87.         {
  88.                 pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//讀取2個字節(jié).
  89.                 ReadAddr+=2;//偏移2個字節(jié).       
  90.         }
  91. }

  92. //////////////////////////////////////////////////////////////////////////////////////////////////////
  93. //WriteAddr:起始地址
  94. //WriteData:要寫入的數(shù)據(jù)
  95. void Test_Write(u32 WriteAddr,u16 WriteData)          
  96. {
  97.         STMFLASH_Write(WriteAddr,&WriteData,1);//寫入一個字
  98. }
復(fù)制代碼

全部資料51hei下載地址:
FLASH模擬EEPROM實(shí)驗(yàn).7z (180.62 KB, 下載次數(shù): 61)


作者: 神出沒    時間: 2020-2-22 09:43
原理是先讀出來flash中的數(shù)據(jù),然后再擦除flash,然后再更改要寫入的數(shù)據(jù),最后再寫入
作者: 檸檬雙生    時間: 2021-1-5 16:50
這是正點(diǎn)原子的例程吧




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1