找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 3339|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

STM32怎么用自身程序保存永久數(shù)據(jù)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:703220 發(fā)表于 2020-11-19 11:39 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式


我現(xiàn)在是想做一個(gè)功能,這個(gè)程序在運(yùn)行到某一位置后,會(huì)保存一個(gè)狀態(tài)參數(shù),但是我只會(huì)用變量實(shí)現(xiàn),但是用變量實(shí)現(xiàn)會(huì)面臨一個(gè)弊端,那就是如果系統(tǒng)斷電,那么這個(gè)變量在重新上電后會(huì)重新初始化,也就是不再是斷電前保存的狀態(tài)參數(shù)了。   

我看網(wǎng)上說可以對(duì)STM32自己的flash寫永久保存的數(shù)據(jù),請(qǐng)問,具體怎么操作,求指點(diǎn)一下。



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:827243 發(fā)表于 2020-11-19 13:02 | 只看該作者
自用的,你試試。STM32Flash.h
  1. #ifndef __STM32FLASH_H__
  2. #define __STM32FLASH_H__

  3. #define FLASHSTART_ADDR         0x08000000                                //128K 最后一頁(yè) 1KB每頁(yè) 可存512個(gè)16位數(shù)  僅用于小于512K產(chǎn)品
  4. #define FLASH_BLOCK_USE                1                                                                        //使用倒數(shù)1個(gè)block
  5. #define STM32_FLASH_SIZE        128                                                                //128K Flash

  6. #if STM32_FLASH_SIZE<256
  7. #define STM_SECTOR_SIZE 1024
  8. #else
  9. #define STM_SECTOR_SIZE        2048
  10. #endif       

  11. #define USER_ADDR (FLASHSTART_ADDR+STM32_FLASH_SIZE*1024-FLASH_BLOCK_USE*STM_SECTOR_SIZE)

  12. #include "GloablVar.h"

  13. void STMFlash_Init(void);
  14. u8 STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite);
  15. void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead);


  16. #endif        //for __STM32FLASH_H__
復(fù)制代碼

STM32Flash.c
  1. #include "main.h"
  2. #include "STM32Flash.h"

  3. u8 FLASH_Unlock(void) {
  4.   if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
  5.   {
  6.     /* Authorize the FLASH Registers access */
  7.     WRITE_REG(FLASH->KEYR, FLASH_KEY1);
  8.     WRITE_REG(FLASH->KEYR, FLASH_KEY2);

  9.     /* Verify Flash is unlocked */
  10.     if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
  11.     {
  12.       return 1;
  13.     }
  14.   }
  15.        
  16.         return 0;
  17. }

  18. void FLASH_Lock(void) {
  19. SET_BIT(FLASH->CR, FLASH_CR_LOCK);
  20. }

  21. void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
  22. {
  23.     /* Proceed to program the new data */
  24.     SET_BIT(FLASH->CR, FLASH_CR_PG);

  25.                 /* Write data in the address */
  26.                 *(__IO uint16_t*)Address = Data;
  27.        
  28.                 while (READ_BIT(FLASH->SR, FLASH_SR_BSY));
  29.                 CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
  30.                 SET_BIT(FLASH->SR, FLASH_SR_EOP);
  31. }

  32. void STMFlash_Init(void) {
  33. //        FLASH->ACR=0;                                                        //CPU= 0M-24M
  34. //        FLASH->ACR=1;                                                        //CPU= 24M-48M
  35.         FLASH->ACR=2;                                                        //CPU= 48M-72M
  36. }

  37.        
  38. void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)   
  39. {                                           
  40.         u16 i;
  41.         for(i=0;i<NumToWrite;i++)
  42.         {
  43.                 FLASH_Program_HalfWord(WriteAddr+i*2,pBuffer[i]);
  44.         }  
  45. }

  46. void STMFLASH_PageErase(uint32_t EraseAddress)
  47. {
  48.                 /* Proceed to erase the page */
  49.     SET_BIT(FLASH->SR, FLASH_SR_EOP);
  50.     SET_BIT(FLASH->CR, FLASH_CR_PER);
  51.     WRITE_REG(FLASH->AR, EraseAddress);
  52.     SET_BIT(FLASH->CR, FLASH_CR_STRT);
  53.                 while (READ_BIT(FLASH->SR, FLASH_SR_EOP)==0);
  54.                 SET_BIT(FLASH->SR, FLASH_SR_EOP);
  55.     CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
  56. }

  57. u16 STMFLASH_ReadHalfWord(u32 faddr)
  58. {
  59.         return *(vu16*)faddr;
  60. }

  61. u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];

  62. void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)          
  63. {
  64.         u16 i;
  65.         for(i=0;i<NumToRead;i++)
  66.         {
  67.                 pBuffer[i]=STMFLASH_ReadHalfWord(USER_ADDR+ReadAddr+i*2);
  68.         }
  69.        
  70. }


  71. u8 STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)       
  72. {
  73.         u32 secpos;          
  74.         u16 secoff;
  75.         u16 rdLen;          
  76.         u16 i;
  77.         u16 wrEnd;
  78.        
  79.         if(WriteAddr+NumToWrite*2>FLASH_BLOCK_USE*STM_SECTOR_SIZE)         return 1;                                        //寫入地址超限
  80.         FLASH_Unlock();
  81.         secpos = WriteAddr / STM_SECTOR_SIZE;
  82.         secoff = WriteAddr % STM_SECTOR_SIZE;
  83.   wrEnd=0;
  84.         while (wrEnd<NumToWrite) {
  85.                 rdLen=(secoff+(NumToWrite-wrEnd)*2<=STM_SECTOR_SIZE)?NumToWrite-wrEnd:(STM_SECTOR_SIZE-secoff)/2;
  86.                 STMFLASH_Read(secpos*STM_SECTOR_SIZE,STMFLASH_BUF,STM_SECTOR_SIZE/2);
  87.                 for(i=0;i<rdLen;i++) {
  88.                         if(STMFLASH_BUF[secoff/2+i]!=0XFFFF) break;            
  89.                 }
  90.                 if (i<rdLen) {
  91.                         STMFLASH_PageErase(secpos*STM_SECTOR_SIZE+USER_ADDR);
  92.                         for(i=0;i<rdLen;i++)
  93.                         {
  94.                                 STMFLASH_BUF[i+secoff/2]=pBuffer[i+wrEnd];          
  95.                         }
  96.                         STMFLASH_Write_NoCheck(USER_ADDR+secpos*STM_SECTOR_SIZE,STMFLASH_BUF,STM_SECTOR_SIZE/2);
  97.                 }
  98.                 else
  99.                         STMFLASH_Write_NoCheck(USER_ADDR+secpos*STM_SECTOR_SIZE+secoff,pBuffer+wrEnd,rdLen);
  100.                
  101.                 secoff = 0;
  102.                 secpos++;
  103.                 wrEnd+=rdLen;
  104.         }
  105.         FLASH_Lock();
  106.         return 0;
  107. }
復(fù)制代碼



評(píng)分

參與人數(shù) 1黑幣 +40 收起 理由
admin + 40 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

板凳
ID:845928 發(fā)表于 2020-11-19 16:35 | 只看該作者
如果只是保存少量一兩個(gè)數(shù)據(jù),使用RTC備份寄存器更方便啦,寫FLASH太耗時(shí)間了(毫秒級(jí))
回復(fù)

使用道具 舉報(bào)

地板
ID:703220 發(fā)表于 2020-11-19 19:52 | 只看該作者
daemondong 發(fā)表于 2020-11-19 13:02
自用的,你試試。STM32Flash.h

STM32Flash.c

多謝多謝
回復(fù)

使用道具 舉報(bào)

5#
ID:703220 發(fā)表于 2020-11-19 20:01 | 只看該作者
24335882qq 發(fā)表于 2020-11-19 16:35
如果只是保存少量一兩個(gè)數(shù)據(jù),使用RTC備份寄存器更方便啦,寫FLASH太耗時(shí)間了(毫秒級(jí))

好的,我試試
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表