【STM32 HAL库】使用HAL库操作FLASH

操作顺序

先解锁Flash,再擦除片区,再写入,写完了别忘了加锁。

c 复制代码
HAL_FLASH_Unlock();
HAL_FLASHEx_Erase();
HAL_FLASH_Program();
HAL_FLASH_Lock();

擦除操作

首先有个问题,我们为什么要擦除,不能直接覆写吗?答案是不能!!!。Flash存储器是一种非易失性存储器,其存储单元在未编程的时候处于1状态(对于Nor Flash,通常擦除后为全1),写操作是将某些比特位变为0,而只有擦除操作才能将位从0变为1

c 复制代码
typedef struct {
  uint32_t TypeErase;    // 擦除类型
  uint32_t Banks;        // 指定操作的目标 Bank
  uint32_t Sector;       // 起始扇区号
  uint32_t NbSectors;    // 要擦除的扇区数量
  uint32_t VoltageRange; // 工作电压范围
} FLASH_EraseInitTypeDef;

HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError);
TypeErase :指定要执行的擦除操作类型。

可选值

  • FLASH_TYPEERASE_SECTORS:擦除指定扇区(最常用)
  • FLASH_TYPEERASE_MASSERASE:整片擦除(全芯片擦除)
  • FLASH_TYPEERASE_PAGES:按页擦除(某些系列如 STM32L0/L1)
Banks :目标存储区,指定要操作的 Flash Bank(存储区)

可选值

  • FLASH_BANK_1:操作 Bank1
  • FLASH_BANK_2:操作 Bank2
  • FLASH_BANK_BOTH:同时操作两个 Bank

注意事项

  • 仅对支持多 Bank 的芯片有效(如 STM32F4/F7/H7)
  • 单 Bank 芯片固定使用 FLASH_BANK_1
Sector :指定擦除操作的起始扇区

取值范围

  • FLASH_SECTOR_0FLASH_SECTOR_11(具体取决于芯片型号)
  • 不同芯片的扇区划分不同:
    • STM32F4:扇区0-3(16KB), 扇区4(64KB), 扇区5-11(128KB)
    • STM32F7:扇区0-7(32KB), 扇区8-11(128KB)
    • STM32H7:扇区0-7(128KB), 扇区8(256KB)
NbSectors :指定要连续擦除的扇区数量

注意事项

  • 必须大于0
  • 扇区必须连续(不能跳过中间扇区)
  • 最大数量受芯片实际扇区数限制
VoltageRange:指定芯片当前工作电压范围,影响编程时间和精度

可选值

  • FLASH_VOLTAGE_RANGE_1:1.7V - 2.1V
  • FLASH_VOLTAGE_RANGE_2:2.1V - 2.7V
  • FLASH_VOLTAGE_RANGE_3:2.7V - 3.6V(最常用)
  • FLASH_VOLTAGE_RANGE_4:2.7V - 3.6V(特定芯片)
c 复制代码
void erase_flash_sectors(uint32_t start_sector, uint32_t num_sectors) {
    HAL_FLASH_Unlock(); // 解锁Flash
    
    FLASH_EraseInitTypeDef erase_init;
    uint32_t sector_error = 0;
    
    // 配置擦除参数
    erase_init.TypeErase = FLASH_TYPEERASE_SECTORS;
    erase_init.Banks = FLASH_BANK_1; // F407系列只有Bank1
    erase_init.Sector = FLASH_SECTOR_11;
    erase_init.NbSectors = 1;
    erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_3;
    
    // 执行擦除
    if (HAL_FLASHEx_Erase(&erase_init, &sector_error) != HAL_OK) {
        // 错误处理
        if (sector_error != 0xFFFFFFFF) {
            // sector_error包含失败扇区号
            Error_Handler();
        }
    }
    
    HAL_FLASH_Lock(); // 重新锁定Flash
}

写入操作

c 复制代码
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);
参数 含义 可选值/要求
TypeProgram 指定编程数据类型宽度 FLASH_TYPEPROGRAM_BYTE(8位) FLASH_TYPEPROGRAM_HALFWORD(16位) FLASH_TYPEPROGRAM_WORD(32位) FLASH_TYPEPROGRAM_DOUBLEWORD(64位)
Address 写入的目标 Flash 地址 必须按数据类型对齐(如32位写入需4字节对齐)
Data 要写入的数据(实际使用时会根据类型截断) 最大支持64位,超宽数据需分多次写入
c 复制代码
void write_word(uint32_t address, uint32_t data) {
    HAL_FLASH_Unlock();  // 解锁Flash
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);  // 清除错误标志

    // 执行写入
    HAL_StatusTypeDef status = HAL_FLASH_Program(
        FLASH_TYPEPROGRAM_WORD, 
        address, 
        (uint64_t)data
    );

    HAL_FLASH_Lock();  // 重新上锁

    if (status != HAL_OK) {
        uint32_t error = HAL_FLASH_GetError();
        Error_Handler(error);
    }
}

// 调用示例
write_word(0x080E0000, 0x12345678);  // 向扇区5起始地址写入数据

读取操作

读取操作很简单,没有调用函数,直接按照地址取值即可。

c 复制代码
// 读取验证
uint32_t read_val = *(__IO uint32_t*)address;
if (read_val != expected_val) {
    // 检查地址/擦除状态
}
相关推荐
阿容1234568 小时前
stm32两轮平衡小车 -04
stm32·嵌入式硬件
silno10 小时前
图解 STM32 USB CDC虚拟串口 的实现
stm32·单片机·stm32f103c8t6·cdc虚拟串口
Silicore_Emma11 小时前
芯谷科技—D8227 双通道音频功率放大集成电路产品简介与应用推广
单片机·音视频·功率放大器·芯谷科技·便携式音频设备·双通道音频·车载音频系统
Darken0312 小时前
单片机的库函数和HAL库有什么区别?还有那些库函数?
单片机·hal库·ai学习
皓月盈江13 小时前
STC12、STC15、STM32系列单片机控制16*64LED点阵屏显示,修改显示内容
单片机·嵌入式硬件·keil·stm32f103c8t6·stc12c5a60s2·stc15w4k32s4·led点阵屏程序源码
沐欣工作室_lvyiyi13 小时前
智能家居安全报警系统设计(论文+源码)
单片机·毕业设计·智能家居·家居安全报警
一枝小雨14 小时前
7 App代码转AES加密文件生成步骤
stm32·单片机·嵌入式·aes·ota·bootloader·加密升级
li星野14 小时前
打工人日报#20251202
单片机·嵌入式硬件
mylinke15 小时前
永磁同步电机双闭环控制模型故障诊断与仿真研究:基于MATLAB Simulink的仿真代码实现
单片机
云山工作室15 小时前
基于ZigBee的温室智能控制系统设计(论文+源码)
stm32·单片机·嵌入式硬件·物联网·课程设计