一、簡介
本文介紹STM32系列如何將flash的一部分當做eeprom來存儲數(shù)據(jù)。
注:本驅動特點是可自定義數(shù)據(jù)存儲空間、限制寫入地址避免誤寫至代碼段、支持跨頁讀寫、允許保存非半字倍數(shù)的字節(jié)。
二、實驗平臺
庫版本:STM32F10x_StdPeriph_Lib_V3.5.0
編譯軟件:MDK4.53
硬件平臺:STM32開發(fā)板(主芯片stm32f103c8t6)
仿真器:JLINK
三、版權聲明
博主:甜甜的大香瓜
聲明:喝水不忘挖井人,轉載請注明出處。
原文地址:http://blog.csdn.NET/feilusia
聯(lián)系方式:897503845@qq.com
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
香瓜BLE之Android群:541462902
香瓜單片機之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘寶店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
四、實驗前提
1、在進行本文步驟前,請先閱讀以下博文:
1)《STM32F10xxx 閃存編程》(下載地址):http://blog.csdn.net/feilusia/article/details/49031709
2、在進行本文步驟前,請先實現(xiàn)以下博文:
暫無
五、基礎知識
1、flash的介紹
答:
香瓜使用的stm32f103c8t6的flash為64K,詳情如下圖:
1)主存儲器(BOOT1=x、BOOT0=0)
①地址:從0x08000000開始。
②頁大?。盒?、中容量的flash為1K每頁,大容量的flash為2K每頁。
2)信息塊
①系統(tǒng)存儲器(BOOT1=0、BOOT0=1):存放ST自帶的啟動代碼。
②選項字節(jié):一般用于配置寫保護、讀保護等功能。
3)閃存存儲器/接口寄存器
flash所用到的寄存器。
2、閃存等待時間是什么?
答:
由于flash的頻率最高位24MHz,所以當STM32的頻率小于24MHz時不需要等待時間、大于24MHz時需要等待時間。
例如當STM32的頻率為72MHz時,需要在工程中設置等待時間:“FLASH_SetLatency(FLASH_Latency_2); ”
3、閃存的讀、寫、擦除是如何的?
答:
1)讀:可以讀有效地址內(nèi)的任意字節(jié)。
2)寫:需要先解閃存鎖,然后按半字(2個字節(jié))的倍數(shù)寫入。
3)擦除:需要先解閃存鎖,然后可以頁擦除、全片擦除。
4、如何解閃存鎖?
答:
1)首先要知道flash有三個鍵值:
①RDPRT鍵 = 0x000000A5
②KEY1 = 0x45670123
③KEY2 = 0xCDEF89AB
2)將KEY1與KEY2依次寫入到FLASH_KEYR寄存器即可實現(xiàn)解閃存鎖。
5、寫flash只能按半字的倍數(shù)來寫,但如果只有3個字節(jié)要保存,那該如何操作?
答:
香瓜的驅動是把flash中的整頁數(shù)據(jù)讀出來,修改要寫的3個字節(jié),然后再按頁寫回去。
雖然此法浪費了些寫多余字節(jié)的時間,但能只改動flash中所需的3個字節(jié),而不是按半字的倍數(shù)(4個)來寫。
6、如何避免寫到代碼段導致代碼運行異常?
答:
以stm32f103c8t6為例,它的flash大小是64K,范圍是0x8000000~0x8010000。
假設通過MDK編譯后得知代碼段大小為31K(0x7C00),所以在32K(0x8007D00)之后的位置肯定都不是代碼段,都可用于自定義的數(shù)據(jù)存儲空間。
保險起見可參考香瓜下文使用的方式,使用flash的末尾4K。
六、實驗步驟
1、編寫并添加驅動
1)編寫驅動GUA_Flash.c(存放在“……HARDWARE”)
//******************************************************************************
//name: GUA_Flash.c
//introduce: flash驅動
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group: 香瓜單片機之STM8/STM32(164311667)
//changetime: 2017.03.18
//******************************************************************************
#include "stm32f10x.h"
#include "GUA_Flash.h"
#include /********************內(nèi)部變量************************/ static GUA_U8 sbGUA_Flash_Data[GUA_FLASH_SECTOR_SIZE] = {0}; /*********************內(nèi)部函數(shù)聲明************************/ static GUA_U16 GUA_Flash_ReadHalfWord(GUA_U32 nGUA_Flash_CustomOffsetAddr); static GUA_U8 GUA_Flash_ReadByte(GUA_U32 nGUA_Flash_CustomOffsetAddr); static GUA_U32 GUA_Flash_ReadWord(GUA_U32 nGUA_Flash_CustomOffsetAddr); //****************************************************************************** //name: GUA_Flash_ReadHalfWord //introduce: 讀取指定地址的字 //parameter: nGUA_Flash_CustomOffsetAddr:偏移地址 //return: 該地址的字 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜單片機之STM8/STM32(164311667) //changetime: 2017.03.18 //****************************************************************************** static GUA_U32 GUA_Flash_ReadWord(GUA_U32 nGUA_Flash_CustomOffsetAddr) { GUA_U32 nGUA_Flash_Addr = GUA_FLASH_CUSTOM_ADDR_START + nGUA_Flash_CustomOffsetAddr; return *(GUA_U32*)nGUA_Flash_Addr; } //****************************************************************************** //name: GUA_Flash_ReadHalfWord //introduce: 讀取指定地址的半字 //parameter: nGUA_Flash_CustomOffsetAddr:偏移地址 //return: 該地址的半字 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜單片機之STM8/STM32(164311667) //changetime: 2017.03.18 //****************************************************************************** static GUA_U16 GUA_Flash_ReadHalfWord(GUA_U32 nGUA_Flash_CustomOffsetAddr) { GUA_U32 nGUA_Flash_Addr = GUA_FLASH_CUSTOM_ADDR_START + nGUA_Flash_CustomOffsetAddr; return *(GUA_U16*)nGUA_Flash_Addr; } //****************************************************************************** //name: GUA_Flash_ReadHalfWord //introduce: 讀取指定地址的字節(jié) //parameter: nGUA_Flash_CustomOffsetAddr:偏移地址 //return: 該地址的字節(jié) //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜單片機之STM8/STM32(164311667) //changetime: 2017.03.18 //****************************************************************************** static GUA_U8 GUA_Flash_ReadByte(GUA_U32 nGUA_Flash_CustomOffsetAddr) { GUA_U32 nGUA_Flash_Addr = GUA_FLASH_CUSTOM_ADDR_START + nGUA_Flash_CustomOffsetAddr; return *(GUA_U8*)nGUA_Flash_Addr; } //****************************************************************************** //name: GUA_Flash_Read //introduce: 讀取指定地址、指定數(shù)據(jù)長度的數(shù)據(jù) //parameter: nGUA_Flash_CustomOffsetAddr:偏移地址 // pGUA_Data:數(shù)據(jù)緩存區(qū) // nGUA_Data_Num:讀取的字節(jié)數(shù) //return: none //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜單片機之STM8/STM32(164311667) //changetime: 2017.03.18 //****************************************************************************** void GUA_Flash_Read(GUA_U32 nGUA_Flash_CustomOffsetAddr, GUA_U8 *pGUA_Data, GUA_U32 nGUA_Data_Num) { while(nGUA_Data_Num--) { *pGUA_Data++ = GUA_Flash_ReadByte(nGUA_Flash_CustomOffsetAddr++); } } //****************************************************************************** //name: GUA_Flash_Write //introduce: 寫入指定地址、指定數(shù)據(jù)長度的數(shù)據(jù) //parameter: nGUA_Flash_Addr:讀地址 // pGUA_Data:數(shù)據(jù)緩存區(qū)(必須偶數(shù)個字節(jié)) // nGUA_Data_Num:數(shù)據(jù)長度(必須偶數(shù)個字節(jié)) //return: 執(zhí)行情況,詳情見eGUA_FLASH_STATUS //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group: 香瓜單片機之STM8/STM32(164311667) //changetime: 2017.03.18 //****************************************************************************** eGUA_FLASH_STATUS GUA_Flash_Write(GUA_U32 nGUA_Flash_CustomOffsetAddr, GUA_U8 *pGUA_Data, GUA_U32 nGUA_Data_Num) { GUA_U32 nGUA_Flash_Addr = GUA_FLASH_CUSTOM_ADDR_START + nGUA_Flash_CustomOffsetAddr; //要寫入的地址 eGUA_FLASH_STATUS eGUA_Flash_Status = GUA_FLASH_STATUS_OK; //flash操作情況 GUA_U16 i; GUA_U32 nGUA_Flash_SectorPos = (nGUA_Flash_Addr - GUA_FLASH_ADDR_START)/GUA_FLASH_SECTOR_SIZE; //算出是第幾個扇區(qū)(從0開始) GUA_U16 nGUA_Flash_SectorAddr_Offset = (nGUA_Flash_Addr - GUA_FLASH_ADDR_START)%GUA_FLASH_SECTOR_SIZE; //扇區(qū)內(nèi)偏移地址 GUA_U16 nGUA_Flash_SectorAddr_Remain = GUA_FLASH_SECTOR_SIZE - nGUA_Flash_SectorAddr_Offset; //扇區(qū)內(nèi)剩余字節(jié) GUA_U16 nGUA_HalfWord = 0; GUA_U16 nGUA_HalfWord_Num; FLASH_Status eGUA_Flash_Lib_Status = FLASH_COMPLETE;
上一篇:STM32 USB HID設置(STM32CubeMX)
下一篇:【STM32】STM32之LED
推薦閱讀最新更新時間:2025-08-02 19:41

設計資源 培訓 開發(fā)板 精華推薦
- 使用 ST10F276 微控制器的三相交流感應電機電流感應板的傳感器磁場定向控制
- LTC2908CTS8-B1、12V、2.5V、1.8V、1.5V、1.2V、1V六電源監(jiān)視器的典型應用電路
- 具有功耗計量功能的兩相交錯式功率因數(shù)校正轉換器
- MC33174VDR2G 有源高 Q 陷波濾波器的典型應用
- LTC7149IUFD 24V 輸入至 -24V 輸出、1MHz 降壓穩(wěn)壓器的典型應用電路
- 基于單片機和ZIGBEE協(xié)議的無線傳感器網(wǎng)絡節(jié)點的設計原理圖
- NSI45030AZT1G可調(diào)電流LED串并聯(lián)CCR的典型應用
- LT3066EDE-3.3 電流監(jiān)視器的典型應用電路
- 使用 ROHM Semiconductor 的 BA70BC0FP-E2 的參考設計
- LT6656BCDC-4.096、4.096V ADC 電壓基準和橋式勵磁電源的典型應用
- 消息稱三星在美“特斯拉專供”2nm 生產(chǎn)線 2026H2 投運,初期產(chǎn)能每月 1~1.5 萬片晶圓
- 黑客如何入侵軟件定義的汽車
- 中國首款國芯腦機智能頭環(huán)正式發(fā)布:非侵入式腦機 全自主國產(chǎn)芯片
- 自動駕駛中Transformer大模型會取代深度學習嗎?
- 這家面板廠在車載OLED領域或再迎新大單
- 激光雷達和攝像頭,誰會是機器人主要的“眼睛”?
- 毫米波雷達技術參數(shù)有哪些?毫米波雷達如何用于機器人導航
- 毫米波雷達技術有哪些優(yōu)勢?如何提高毫米波雷達測距精度
- 工業(yè)邊緣設備的安全啟動,TPM 2.0與可信執(zhí)行環(huán)境(TEE)的硬件級防護
- 工業(yè)機器人視覺系統(tǒng)的深度學習優(yōu)化,YOLOv8、3D點云匹配的實時性提升