久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3463|回復: 4
收起左側

STM32怎么用自身程序保存永久數據

[復制鏈接]
ID:703220 發表于 2020-11-19 11:39 | 顯示全部樓層 |閱讀模式


我現在是想做一個功能,這個程序在運行到某一位置后,會保存一個狀態參數,但是我只會用變量實現,但是用變量實現會面臨一個弊端,那就是如果系統斷電,那么這個變量在重新上電后會重新初始化,也就是不再是斷電前保存的狀態參數了。   

我看網上說可以對STM32自己的flash寫永久保存的數據,請問,具體怎么操作,求指點一下。



回復

使用道具 舉報

ID:827243 發表于 2020-11-19 13:02 | 顯示全部樓層
自用的,你試試。STM32Flash.h
  1. #ifndef __STM32FLASH_H__
  2. #define __STM32FLASH_H__

  3. #define FLASHSTART_ADDR         0x08000000                                //128K 最后一頁 1KB每頁 可存512個16位數  僅用于小于512K產品
  4. #define FLASH_BLOCK_USE                1                                                                        //使用倒數1個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__
復制代碼

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. }
復制代碼



評分

參與人數 1黑幣 +40 收起 理由
admin + 40 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:845928 發表于 2020-11-19 16:35 | 顯示全部樓層
如果只是保存少量一兩個數據,使用RTC備份寄存器更方便啦,寫FLASH太耗時間了(毫秒級)
回復

使用道具 舉報

ID:703220 發表于 2020-11-19 19:52 | 顯示全部樓層
daemondong 發表于 2020-11-19 13:02
自用的,你試試。STM32Flash.h

STM32Flash.c

多謝多謝
回復

使用道具 舉報

ID:703220 發表于 2020-11-19 20:01 | 顯示全部樓層
24335882qq 發表于 2020-11-19 16:35
如果只是保存少量一兩個數據,使用RTC備份寄存器更方便啦,寫FLASH太耗時間了(毫秒級)

好的,我試試
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一区二区三区在线免费看 | 91综合在线观看 | 欧美一区二区三区四区视频 | 精久久久| 日韩在线一区二区 | 精品国产亚洲一区二区三区大结局 | 久久夜色精品国产 | 成人免费在线观看 | 成人免费在线播放 | 国产精品一区在线 | 国产精品久久久久久久久久久久午夜片 | 一本在线 | 欧美一区二区精品 | 午夜精品一区二区三区在线视 | 免费精品 | 成人免费一区二区三区视频网站 | 亚洲精品一区中文字幕乱码 | 久久亚洲一区二区三区四区 | 国产精品国产 | www.久久.com| 国产精品久久久久久高潮 | 一级毛片色一级 | 亚洲精品片 | 久久久久久久久毛片 | 中文字幕综合 | 国产成人精品一区二区三区四区 | 国产精品久久性 | 91亚洲免费 | 亚洲福利 | 亚洲精品久久久久久久久久久久久 | 精品久久中文字幕 | 毛片一区二区三区 | 黄色一级大片在线免费看产 | 黄网在线观看 | 久久99一区二区 | 欧美日韩专区 | 91精品国产综合久久久久久 | 天堂综合网久久 | 国产无套一区二区三区久久 | 中文字幕在线观看一区二区 | 亚洲成人三级 |