STM32芯片内部的FLASH存储器,主要用于存储我们代码。如果内部
FLASH存储完我们的代码还有剩余的空间,那么这些剩余的空间我们就可以利
用起来,存储一些需要掉电保存的数据。本文以STM32103ZET为例。
STM32103ZET属于大容量产品,其闪存模块组织如下:
其主存储器大小为512KB分为256页,每页大小都为2KB我们的程序般默认烧写到第0页的起始地址(0x08000000)处。
当BOOT引脚和BOOT引脚都接GND寸,就是从这个地址开始运行代码的。这个地址在keil中可以看到:
F 面对STM32内部FLASH 进行简单的读写测试:
内部FLASH 读写测试 流程图如下:
本流程图省略异常情况,只考虑成功的情况:
f
-
Q Options for Target 'FLASH'
Utvice Til i«l I Output ] Li itinc | Ustr | C/C++ | Asm
Linker Debue Vtiiitws
\t
STHicroetedonici SR32F103ZE
Opef^g syseiTi : |
Sysem \^ewer Rle.
{MHi): B
ll
-Cod* GeniFon —
ARM Compter: | Use default cwnpiter veraion 5
厂 Lse Cjoss-^ottile Ortimiiator
Iv Lse Micro LIB
ot
Cancel
CeCa-olts  Help
假如我们要下载的程序大小为4.05KB , 则第0、1、2页用于保存我们的程
序,我们需要掉电保存的数据只能保存在第 3~第255页这一部分空间内。 我们最终要下载的程序大小可
在工程对应的 .map 文件中看到。.map 文件可以双
击工程的Target 的名字快速打开,如:
hrlphdrt Tool ; SVM 応 inJ 艸 hti 単 ,-■
k ,A 弟=*七住
」Mitw J 咖3口知,樹;卜( J
... —. ■
丹 Ft E4R vl«* PiQjtit “Ml Dtbug
•ffli
11 h
tBj
£画 IF b.农-
I r sj fLASj- I
n 討mi
■. 1.7 viieiiii '.L
KP
;L 叭1祠£ -L 二El 仍恤■走r
二匚 £
J
t±』CMS5
Q StriPaiph thr.ci
二u
c41
14出
, +    e 4H ULiJry T'^CiJb
d Mt*
LMb|
HE
LL ・md " D*fca ] ■
W Egf icrtBli 畤
stm32怎么使用printfTCT P H
muc
fi>n 3 Hlih —b kp C b4i-i3 Jhdn_c.driR.
Hb
loral HD Size Ifodt + ・□ palFl*
Total R>I 51■疋c £RM Eta - Zr TZatJ) Totdg flW S 上电 jt 屁It + 觀尿H * 也 G SU T
L Use CustziE
Fife
示例代码:
本例的关键代码如下(以读写第255页为例):
/********************************************************************
***********************************
* -------------------------------------- STM32 Demo ------------------------
工程说明:STM32内部FLASH实验作者:ZhengNian
博客: zhengnianli.github.io
:嵌入式大杂烩
*********************************************************************
***********************************/
#defi ne MAIN_CONFIG
#i nclude "con fig.h"
/* STM32F103ZET6有256页,每一页的大小都为2KB */
#defi ne ADDR_FLASH _P AGE_255 ((ui nt32_t)0x0807F800) /* Page255 2KB */
/* FLASH
读写测试结果
*/
#defi ne #defi ne #defi ne
/* Flash 读写测试buf */ #defi ne BufferSize 6
ui nt16_t usFlashWriteBuf[BufferSize]= {0x0101,0x0202,0x0303,0x0404,0x0505,0x0606}; ui nt16_t usFlashReadBuf[BufferSize] = {0};
/*供本文件调用的函数声明*/ static int FlashReadWriteTest(void);
*********************************** ** 函数:main
参数:void 返回:无 说明:主函数
********************************************************************* ***********************************/ int main(v oid) {
/*上电初始化*/ Sysl nit();
/*内部Flash 读写测试*/
if (TEST_SUCCESS == FlashReadWriteTest()) prin tf("Flash test success!' n"); } else {
prin tf("Flash test failed!\n"); } while (1) {} }
***********************************
**函数:FlashReadWriteTest ,内部Flash 读写测试函数 ** 参数:void
**返回:TEST_ERROR :错误(擦除、写入错误) TEST_SUCCESS:成功
TEST_FAILED :失败 **说明:无
*********************************************************************
***********************************/ static int FlashReadWriteTest(void) {
TEST_ERROR -1 TEST_SUCCESS 0 TEST_FAILED 1 /*
/*错误(擦除、写入错误)*/ /*成功*/
失败*/
uin t32_t ucStartAddr;
/*解锁*/
FLASH_U nIockO;
/*擦除操作*/ ucStartAddr = ADDR_FLASH _P AGE_255;
if (FLASH_CO MP LETE != FLAsH_Erase Page(ucStartAddr)) { prin tf("Erase Error!\n"); return TEST_ERROR;
}
else
ucStartAddr = ADDR_FLASH _P AGE_255;
printf("擦除成功,此时FLASH中值为:\n");
for (i nt i = 0; i < BufferSize; i++)
{
usFlashReadBuf[i] = *(ui nt32_t*)ucStartAddr;
prin tf("ucFlashReadBuf[%d] = 0x%.4x\n", i, usFlashReadBuf[i]); ucStartAddr += 2;
}
}
/*写入操作*/
ucStartAddr = ADDR_FLASH _P AGE_255;
printf("\n往FLASH中写入的数据为:\n");
for (i nt i = 0; i < BufferSize; i++)
{
if (FLASH_CO MP LETE != FLASH _P rogramHalfWord(ucStartAddr, usFlashWriteBuf[i])) {
prin tf("Write Error!\n");
return TEST_ERROR;
} "
prin tf("ucFlashWriteBuf[%d] = 0x%.4x\n", i, usFlashWriteBuf[i]); ucStartAddr += 2;
} /*上锁*/ FLASH_Lock();