一、簡介
本文介紹STM32系列如何將flash的一部分當(dāng)做eeprom來存儲數(shù)據(jù)。
注:本驅(qū)動特點(diǎn)是可自定義數(shù)據(jù)存儲空間、限制寫入地址避免誤寫至代碼段、支持跨頁讀寫、允許保存非半字倍數(shù)的字節(jié)。
二、實驗平臺
庫版本:STM32F10x_StdPeriph_Lib_V3.5.0
編譯軟件:MDK4.53
硬件平臺:STM32開發(fā)板(主芯片stm32f103c8t6)
仿真器:JLINK
三、版權(quán)聲明
博主:甜甜的大香瓜
聲明:喝水不忘挖井人,轉(zhuǎn)載請注明出處。
原文地址:http://blog.csdn.NET/feilusia
聯(lián)系方式:897503845@qq.com
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
香瓜BLE之Android群:541462902
香瓜單片機(jī)之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘寶店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
四、實驗前提
1、在進(jìn)行本文步驟前,請先閱讀以下博文:
1)《STM32F10xxx 閃存編程》(下載地址):http://blog.csdn.net/feilusia/article/details/49031709
2、在進(jìn)行本文步驟前,請先實現(xiàn)以下博文:
暫無
五、基礎(chǔ)知識
1、flash的介紹
答:
香瓜使用的stm32f103c8t6的flash為64K,詳情如下圖:
1)主存儲器(BOOT1=x、BOOT0=0)
①地址:從0x08000000開始。
②頁大?。盒 ⒅腥萘康膄lash為1K每頁,大容量的flash為2K每頁。
2)信息塊
①系統(tǒng)存儲器(BOOT1=0、BOOT0=1):存放ST自帶的啟動代碼。
②選項字節(jié):一般用于配置寫保護(hù)、讀保護(hù)等功能。
3)閃存存儲器/接口寄存器
flash所用到的寄存器。
2、閃存等待時間是什么?
答:
由于flash的頻率最高位24MHz,所以當(dāng)STM32的頻率小于24MHz時不需要等待時間、大于24MHz時需要等待時間。
例如當(dāng)STM32的頻率為72MHz時,需要在工程中設(shè)置等待時間:“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é)要保存,那該如何操作?
答:
香瓜的驅(qū)動是把flash中的整頁數(shù)據(jù)讀出來,修改要寫的3個字節(jié),然后再按頁寫回去。
雖然此法浪費(fèi)了些寫多余字節(jié)的時間,但能只改動flash中所需的3個字節(jié),而不是按半字的倍數(shù)(4個)來寫。
6、如何避免寫到代碼段導(dǎo)致代碼運(yùn)行異常?
答:
以stm32f103c8t6為例,它的flash大小是64K,范圍是0x8000000~0x8010000。
假設(shè)通過MDK編譯后得知代碼段大小為31K(0x7C00),所以在32K(0x8007D00)之后的位置肯定都不是代碼段,都可用于自定義的數(shù)據(jù)存儲空間。
保險起見可參考香瓜下文使用的方式,使用flash的末尾4K。
六、實驗步驟
1、編寫并添加驅(qū)動
1)編寫驅(qū)動GUA_Flash.c(存放在“……HARDWARE”)
//******************************************************************************
//name: GUA_Flash.c
//introduce: flash驅(qū)動
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group: 香瓜單片機(jī)之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: 香瓜單片機(jī)之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: 香瓜單片機(jī)之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: 香瓜單片機(jī)之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: 香瓜單片機(jī)之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: 香瓜單片機(jī)之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設(shè)置(STM32CubeMX)
下一篇:【STM32】STM32之LED
推薦閱讀最新更新時間:2025-08-02 19:41

設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 使用 ST10F276 微控制器的三相交流感應(yīng)電機(jī)電流感應(yīng)板的傳感器磁場定向控制
- LTC2908CTS8-B1、12V、2.5V、1.8V、1.5V、1.2V、1V六電源監(jiān)視器的典型應(yīng)用電路
- 具有功耗計量功能的兩相交錯式功率因數(shù)校正轉(zhuǎn)換器
- MC33174VDR2G 有源高 Q 陷波濾波器的典型應(yīng)用
- LTC7149IUFD 24V 輸入至 -24V 輸出、1MHz 降壓穩(wěn)壓器的典型應(yīng)用電路
- 基于單片機(jī)和ZIGBEE協(xié)議的無線傳感器網(wǎng)絡(luò)節(jié)點(diǎn)的設(shè)計原理圖
- NSI45030AZT1G可調(diào)電流LED串并聯(lián)CCR的典型應(yīng)用
- LT3066EDE-3.3 電流監(jiān)視器的典型應(yīng)用電路
- 使用 ROHM Semiconductor 的 BA70BC0FP-E2 的參考設(shè)計
- LT6656BCDC-4.096、4.096V ADC 電壓基準(zhǔn)和橋式勵磁電源的典型應(yīng)用
- 消息稱三星在美“特斯拉專供”2nm 生產(chǎn)線 2026H2 投運(yùn),初期產(chǎn)能每月 1~1.5 萬片晶圓
- 黑客如何入侵軟件定義的汽車
- 中國首款國芯腦機(jī)智能頭環(huán)正式發(fā)布:非侵入式腦機(jī) 全自主國產(chǎn)芯片
- 自動駕駛中Transformer大模型會取代深度學(xué)習(xí)嗎?
- 這家面板廠在車載OLED領(lǐng)域或再迎新大單
- 激光雷達(dá)和攝像頭,誰會是機(jī)器人主要的“眼睛”?
- 毫米波雷達(dá)技術(shù)參數(shù)有哪些?毫米波雷達(dá)如何用于機(jī)器人導(dǎo)航
- 毫米波雷達(dá)技術(shù)有哪些優(yōu)勢?如何提高毫米波雷達(dá)測距精度
- 工業(yè)邊緣設(shè)備的安全啟動,TPM 2.0與可信執(zhí)行環(huán)境(TEE)的硬件級防護(hù)
- 工業(yè)機(jī)器人視覺系統(tǒng)的深度學(xué)習(xí)優(yōu)化,YOLOv8、3D點(diǎn)云匹配的實時性提升
- 我國機(jī)器人分為兩種CR認(rèn)證模式,工業(yè)機(jī)器人發(fā)展還需進(jìn)一步推動
- 機(jī)器人抓取研究前沿及抓取的研究進(jìn)展整體分析
- 萬盛全域旅游服務(wù)中心采用“機(jī)器人”上崗服務(wù)
- 廣東省工業(yè)機(jī)器人產(chǎn)量報告,機(jī)器人相關(guān)企業(yè)超過500家
- 特斯拉研發(fā)新鋰電池技術(shù)路線
- Renesas宣布R-Car片上系統(tǒng)(SoC)增添全新產(chǎn)品系列
- 【STM32Cube_21】使用DAC輸出任意指定電壓
- 貿(mào)澤電子宣布與浪涌保護(hù)產(chǎn)品制造商CITEL簽訂分銷協(xié)議
- 單片機(jī)學(xué)習(xí)札記4---調(diào)試蜂鳴器驅(qū)動
- 單片機(jī)學(xué)習(xí)札記5---定時器和中斷配置