数码工坊
白蓝主题五 · 清爽阅读
首页  > 数据备份

STM32示例程序在数据备份中的实用技巧

做嵌入式开发的兄弟都知道,STM32用得顺手,项目进度能快不少。尤其是涉及到数据备份这类功能时,一个靠谱的示例程序能省去大量调试时间。比如你在做一个智能电表项目,断电后要保存累计用电量,这时候直接拿官方的Flash模拟EEPROM示例改一改,十几分钟就跑通了。

从官方库找突破口

ST官网的STM32Cube固件包里藏着不少好东西。比如STM32F1系列的FLASH_EEPROM示例,演示了怎么用内部Flash模拟存储空间。这个场景特别适合保存校准参数、用户设置或者设备运行记录。别自己从头写写擦流程,容易翻车,直接基于示例改最稳。

#include "stm32f1xx_hal.h"

#define DATA_ADDRESS 0x0800FC00  // 假设放在最后一页

void save_backup_data(uint32_t value) {
    HAL_FLASH_Unlock();
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | \
                          FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR);
    
    FLASH_EraseInitTypeDef EraseInitStruct;
    uint32_t PageError = 0;
    EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.PageAddress = DATA_ADDRESS;
    EraseInitStruct.NbPages = 1;
    
    HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
    HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, DATA_ADDRESS, value);
    HAL_FLASH_Lock();
}

实际应用场景更复杂

真实项目不会只存一个数字。比如你做的工业控制器要记录最近十次的停机时间,就得考虑结构体存储和版本管理。这时候可以在示例基础上加个简单的文件头,标记数据有效性。断电再上电,先判断标志位再读取,避免读到半截垃圾数据。

还有人喜欢外挂SPI Flash做备份,像W25Q64这种几毛钱的芯片,配合STM32的SPI DMA传输,存个几百条日志轻轻松松。ST有个SPI_FLASH示例,初始化时把JEDEC ID读出来,确认芯片在线,后面就能当U盘一样用了。

别忽略电源异常处理

现场设备最怕突然断电。你在示例程序里写了个“保存配置”函数,主循环里一调用就完事?真出问题了数据可能只写了一半。稳妥的做法是加个状态标记,比如写数据前先置“写入中”,写完改成“已完成”。下次上电根据状态决定是否恢复或丢弃。

有些老工程师还会用RTC备份寄存器——那几个64位的备用域,掉电靠纽扣电池撑着。虽然只有几十字节,但存个关机时间戳或者异常代码足够了。对应示例程序在BKP章节里,用__HAL_RCC_BKP_CLK_ENABLE()打开时钟就行。

说到底,STM32示例程序不是给你抄作业的,而是帮你理解底层机制的钥匙。改两行代码跑通不难,关键是要明白什么时候该擦除、哪里会卡住、电压低了怎么办。把这些细节吃透,做数据备份才不会半夜被产线电话叫起来救火。