1. 从零认识GD32的FMC:你的芯片内置“U盘”管理员
如果你玩过GD32,或者任何一款ARM Cortex-M内核的MCU,你一定知道它内部都自带一块Flash存储器,用来存放你的程序代码。但你可能不知道,这块Flash除了当“只读”的程序仓库,还能变身成一个可以随时读写、存储用户数据的“小U盘”。这个神奇功能的幕后操盘手,就是FMC(Flash Memory Controller,闪存控制器)。
我刚开始接触时,也以为Flash就是上电跑程序的,存点参数还得外挂个EEPROM芯片,既占板子空间又增加成本。后来项目逼得紧,才深入研究FMC,发现这简直是GD32送给开发者的一个宝藏功能。用好它,你可以在产品里记录设备运行时间、保存用户配置、缓存传感器数据,甚至实现一个简易的文件系统,完全省掉一颗外置存储芯片。
简单来说,FMC就是GD32芯片内部的一个专用硬件模块,它负责管理对内部Flash存储器的所有操作,包括读、写(编程)、擦除。它就像一位严谨的仓库管理员,你不能直接闯进仓库(Flash)搬东西,必须通过这位管理员(FMC),按照他定下的规矩(操作流程)来存取货物(数据)。
为什么需要这么麻烦?因为Flash存储器的物理特性很特殊。你可以把它想象成一种特殊的“黑板”,数据是“粉笔字”。读数据就像看黑板上的字,直接看就行。但写数据(编程),相当于用粉笔在黑板上写字,只能从1写成0(在Flash里,1代表已擦除,0代表已编程)。而擦除,则是把整块黑板擦干净,让所有字都消失,恢复成“空白”(全1状态)。最关键的是,擦除不能只擦一个字,必须按“块”来擦,比如一整页、一整个扇区。FMC的存在,就是为了帮我们安全、正确地完成这一系列精细操作,防止我们误操作把整个程序都“擦没了”。
那么,哪些场景最适合用FMC呢?我总结了几点:
- 参数存储:产品出厂校准参数、用户设置(如Wi-Fi密码、屏幕亮度)。
- 数据记录:设备运行日志、事件记录、简单的历史数据缓存。
- OTA升级:下载的新固件可以先暂存在Flash的特定区域,校验后再执行升级。
- 替代EEPROM:对于存储量要求不大(几KB到几十KB)的应用,完全可以用内部Flash替代,省下一颗芯片。
接下来,我们就抛开枯燥的寄存器手册,像老朋友聊天一样,一步步拆解如何让这位“仓库管理员”为我们高效工作。
2. 动手前先“摸清家底”:理解Flash的存储布局
在开始对Flash进行读写擦除之前,第一件绝对不能跳过的事,就是彻底搞清楚你手头这块GD32芯片的“存储家底”。盲目操作就像在不清楚房间结构的情况下胡乱装修,很容易“砸了承重墙”(误擦程序区),导致系统崩溃。
2.1 查看你的芯片“身份证”:存储信息寄存器
每颗GD32芯片内部都有一个FMC_INFO(Flash Memory Information)寄存器。这个寄存器就像是芯片的存储“身份证”,清晰地记录了两个关键信息:片上Flash总容量和片上SRAM容量。在GD32的标准外设库(如GD32F4xx_Firmware_Library)中,通常有相关的宏定义或函数可以直接获取这些值。
例如,你可能会在代码里看到类似 FMC_PAGE_SIZE、FMC_SECTOR_SIZE 或 FMC_NB_SECTORS 这样的宏,它们就是根据芯片型号预定义好的。但更可靠的做法是在程序初始化时,通过读取特定寄存器来动态获取。虽然标准库可能没有直接封装这个函数,但你可以根据参考手册,通过访问 FMC_INFO 寄存器的特定位域来获取容量信息。知道总容量(比如512KB)是你规划存储区域的根本。
2.2 看懂存储“地图”:存储器映射与扇区划分
知道了总容量,下一步就要看“户型图”——存储器映射(Memory Map)。对于GD32F4系列(以常见的F450为例),它的Flash起始地址是 0x0800 0000,这也是你的程序开始执行的地方。假设你的芯片是512KB版本,那么Flash的地址范围就是 0x0800 0000 到 0x0807 FFFF。
重点来了:Flash不是均匀的一块,而是被划分成了大小不同的扇区(Sector)! 这是FMC操作中最重要的概念之一。以512KB的GD32F4为例,它的划分可能类似下表:
| 扇区号 (Sector) | 起始地址 | 大小 | 用途建议 |
|---|---|---|---|
| Sector 0 | 0x0800 0000 | 16 KB | 主程序区(慎动!) |
| Sector 1 | 0x0800 4000 | 16 KB | 主程序区(慎动!) |
| Sector 2 | 0x0800 8000 | 16 KB | 主程序区(慎动!) |
| Sector 3 |


3297

被折叠的 条评论
为什么被折叠?



