Flash — 页擦除 + 字编程(Flash_PageErase_WordProgram)
固件库: CIU32F003_STDLib V1.0.3 芯片: CIU32F003(Cortex-M0) 源文件:
CIU32/CIU32F003_STDLib_V1.0.3/Projects/FLASH/Flash_PageErase_WordProgram/Source/
一、功能简介
本示例演示内部 Flash 的擦除与编程:在第 32 页(起始地址 0x4000)上,
先把整页擦除,再连续写入 32 个字(每个字 4 字节,内容 0x5A5A5A5A),
每写一个字就读回校验是否正确,最后把 Flash 控制寄存器重新加锁。
这是把 Flash 当“掉电保存的数据区”使用的最标准流程。
务必注意:示例写入的是代码区之外的用户页(0x4000 起)。千万不要擦写正在运行程序的地址,否则会跑飞!
二、硬件准备
- CIU32F003 开发板
- 下载器(如 CMSIS-DAP / J-Link)用于烧录与在线调试
- 可用调试器“Memory”窗口观察
0x4000处的数据变化
关键参数(来自 main.c 宏定义):
|
|
三、完整代码
3.1 主流程 main.c
|
|
3.2 异常处理 common.c(节选)
|
|
四、代码分段讲解
① 地址计算
word_count << 2 即 word_count * 4(每个字 4 字节)。第 32 页起始 0x4000,
第 i 个字地址 = 0x4000 + i*4。
② 解锁 / 加锁
Flash 控制寄存器上电后处于锁定状态,写/擦前必须 std_flash_unlock(),
操作结束后 std_flash_lock() 重新锁定,避免程序跑飞时意外改写 Flash。
③ 页擦除
Flash 只能“按页擦除、按字写”。写入前目标区必须是 0xFF...,所以先整页擦除。
std_flash_erase(FLASH_MODE_PAGE_ERASE, addr) 以页首地址为参数擦除整页(512 字节)。
④ 字编程与校验
std_flash_word_program(addr, data):向 addr 写入一个 32 位字;- 写完后用指针直接读回比较,确认写入成功(Flash 写慢,校验能及时发现写保护/寿命等问题);
- 若返回非
STD_OK或校验不符,进入error_process()卡死便于定位。
⑤ 标志位
开始时清掉 EOP(操作结束)与 WRPERR(写保护错误)标志,保证后续状态判断准确。
五、实验现象
- 程序运行后,调试器查看
0x4000 ~ 0x407F:应全部为5A 5A 5A 5A(小端排列); - 复位再运行,因先擦除后写入,数据保持一致;
- 若
error_process()被触发(卡死),说明擦/写未成功(常见:地址落在受保护区或选项字节写保护)。
六、常见问题
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 写入后读出不一致 | 没先擦除 | 写前必须整页擦除(Flash 只能 1→0) |
| 擦除/编程返回错误 | 地址不在用户区/被写保护 | 选代码区外的页;检查选项字节 |
| 程序跑飞 | 擦写了正在运行的代码页 | 不要把 addr 指向当前程序所在页 |
| 反复写寿命耗尽 | 频繁擦写同一页 | Flash 擦写次数有限(万次级),做磨损均衡/降低频率 |
七、小结
Flash 当 EEPROM 用的标准四步:解锁 → 页擦除 → 按字编程(并校验) → 加锁。 牢记三条铁律:① 最小擦除单位=页(512B);② 最小写入单位=字(4B);③ 写前必擦、写只能 1→0。
八、拓展应用
- 保存校准参数/配置:上电从固定页读出,掉电不丢;
- 实现“配置写入函数”:先备份整页到 RAM → 擦页 → 改后写回;
- 修改读/写保护:配置选项字节(见
Flash_OptionByte_Update)。