stm32读写内部flash
stm32读写内部flash
更多
在STM32中读写内部Flash(闪存)需遵循特定步骤,以下是详细流程和注意事项(以标准外设库/HAL库为例):
关键步骤
1. 解锁Flash(解除写保护)
Flash默认被锁定以防止误操作,需先解锁:
// 标准库
FLASH_Unlock();
// HAL库
HAL_FLASH_Unlock();
2. 擦除目标页/扇区
Flash只能将1写成0,写入前需擦除(将整页恢复为0xFF):
// 标准库(以STM32F1为例)
FLASH_Status status = FLASH_ErasePage(FLASH_ADDR); // 按页擦除
if (status != FLASH_COMPLETE) { /* 错误处理 */ }
// HAL库(以STM32F4为例)
FLASH_EraseInitTypeDef eraseConfig;
uint32_t sectorError;
eraseConfig.TypeErase = FLASH_TYPEERASE_SECTORS; // 按扇区擦除
eraseConfig.Sector = FLASH_SECTOR_7; // 目标扇区编号
eraseConfig.NbSectors = 1; // 擦除数
eraseConfig.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围(3.3V)
if (HAL_FLASHEx_Erase(&eraseConfig, §orError) != HAL_OK) {
/* 错误处理 */
}
3. 写入数据
按半字(16位) 或 字(32位) 写入(不支持单字节写入):
// 标准库(半字写入)
for (uint16_t i = 0; i < dataSize; i += 2) {
FLASH_Status status = FLASH_ProgramHalfWord(targetAddr, *(uint16_t*)(data + i));
if (status != FLASH_COMPLETE) { /* 错误处理 */ }
targetAddr += 2;
}
// HAL库(字写入)
for (uint16_t i = 0; i < dataSize; i += 4) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, targetAddr, *(uint32_t*)(data + i)) != HAL_OK) {
/* 错误处理 */
}
targetAddr += 4;
}
4. 重新锁定Flash
操作完成后重新上锁:
// 标准库
FLASH_Lock();
// HAL库
HAL_FLASH_Lock();
5. 读取数据
直接指针访问(无需解锁):
uint32_t readData = *(__IO uint32_t*)FLASH_ADDR; // 读取32位数据
注意事项
-
地址对齐
- 起始地址必须是偶数(半字写入)或4的倍数(字写入)。
- 跨页写入时需确保每页已提前擦除。
-
中断与超时
- 擦除/写入期间CPU会阻塞,HAL库默认使用中断超时等待。
- 复杂场景建议关闭中断(
__disable_irq())后再操作Flash。
-
Flash寿命
- 典型擦写寿命约 10,000次,避免频繁写入。
-
内存屏障
操作关键寄存器前插入内存屏障:__HAL_FLASH_DATA_CACHE_DISABLE(); // 禁用数据缓存(F4/F7/H7需考虑) __ISB(); // 指令屏障 -
目标地址范围
- 必须位于用户Flash区域(参考芯片手册)。
- 避开启动代码区与向量表(通常从
0x08000000开始)。
-
硬件限制
- 不同系列Flash结构不同(F1按页,F4/F7按扇区)。
- 部分型号支持双Bank(可边读边写)。
完整示例(STM32F1 HAL库)
#include "stm32f1xx_hal.h"
#define FLASH_TARGET_START ((uint32_t)0x0800F000) // 末尾页地址(需根据具体型号调整)
void Flash_Write(uint32_t offset, uint16_t *data, uint16_t size) {
HAL_FLASH_Unlock();
// 计算目标页地址(STM32F1每页1KB)
uint32_t pageAddr = FLASH_TARGET_START + (offset & 0xFFFFFC00);
// 擦除页
FLASH_EraseInitTypeDef eraseConfig = {
.TypeErase = FLASH_TYPEERASE_PAGES,
.PageAddress = pageAddr,
.NbPages = 1
};
uint32_t pageError;
HAL_FLASHEx_Erase(&eraseConfig, &pageError);
// 写入数据(半字)
uint32_t addr = FLASH_TARGET_START + offset;
for (uint16_t i = 0; i < size; i++) {
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr, data[i]);
addr += 2;
}
HAL_FLASH_Lock();
}
void Flash_Read(uint32_t offset, uint16_t *buf, uint16_t size) {
uint32_t addr = FLASH_TARGET_START + offset;
for (uint16_t i = 0; i < size; i++) {
buf[i] = *(__IO uint16_t*)addr;
addr += 2;
}
}
常见问题
- HardFault异常
- 地址非法(超出Flash范围)。
- 未擦除直接写入。
- 数据错误
- 写入时未对齐地址。
- 跨页写入未处理分页边界。
- 擦写失败
- 未解锁Flash或电压范围配置错误。
提示:具体细节需查阅对应型号的《参考手册》和《Flash编程手册》,重点关注:
- 页/扇区大小
- 擦写时间参数
- 寄存器操作时序
STM32CUBEMX开发GD32F303(17)----内部Flash读写
本章STM32CUBEMX配置STM32F103,并且在GD32F303中进行开发,同时通过开发板内进行验证。 本例程主要讲解如何对芯片自带Flash
2023-07-27 09:35:54
STM32 内部Flash读写 程序源码 [已验证]
由于STM32 系列Flash的Erase功能都是按Page擦除,所以想往Flash写入某一段数据,又想保持其他数据不变的话,就要做缓存
资料下载
佚名
2021-12-02 12:06:10
7天热门专题
换一换
换一换
- 如何分清usb-c和type-c的区别
- 中国芯片现状怎样?芯片发展分析
- vga接口接线图及vga接口定义
- 芯片的工作原理是什么?
- 华为harmonyos是什么意思,看懂鸿蒙OS系统!
- 什么是蓝牙?它的主要作用是什么?
- ssd是什么意思
- 汽车电子包含哪些领域?
- TWS蓝牙耳机是什么意思?你真的了解吗
- 什么是单片机?有什么用?
- 升压电路图汇总解析
- plc的工作原理是什么?
- 再次免费公开一肖一吗
- 充电桩一般是如何收费的?有哪些收费标准?
- ADC是什么?高精度ADC是什么意思?
- dtmb信号覆盖城市查询
- EDA是什么?有什么作用?
- 中科院研发成功2nm光刻机
- 苹果手机哪几个支持无线充电的?
- type-c四根线接法图解
- 华为芯片为什么受制于美国?
- 怎样挑选路由器?
- 元宇宙概念股龙头一览
- 锂电池和铅酸电池哪个好?
- 什么是场效应管?它的作用是什么?
- 如何进行编码器的正确接线?接线方法介绍
- 虚短与虚断的概念介绍及区别
- 晶振的作用是什么?
- 大疆无人机的价格贵吗?大约在什么价位?
- 苹果nfc功能怎么复制门禁卡
- amoled屏幕和oled区别
- 单片机和嵌入式的区别是什么
- 复位电路的原理及作用
- BLDC电机技术分析
- dsp是什么意思?有什么作用?
- 苹果无线充电器怎么使用?
- iphone13promax电池容量是多少毫安
- 芯片的组成材料有什么
- 特斯拉充电桩充电是如何收费的?收费标准是什么?
- 直流电机驱动电路及原理图
- 传感器常见类型有哪些?
- 自举电路图
- 通讯隔离作用
- 苹果笔记本macbookpro18款与19款区别
- 新斯的指纹芯片供哪些客户
- 伺服电机是如何进行工作的?它的原理是什么?
- 无人机价钱多少?为什么说无人机烧钱?
- 以太网VPN技术概述
- 手机nfc功能打开好还是关闭好
- 十大公认音质好的无线蓝牙耳机