本文最后更新于11 天前,其中的信息可能已经过时,如有错误请发送邮件到tudougin@163.com
1. Flash描述
BAT32G133 微控制器内置一块容量为 32 KB 的主 Flash 存储器,该存储器划分为 64 个扇区(Sector),每个扇区大小为 512 字节。该 Flash 可用于存储程序代码或数据内容,支持擦除、编程和读取等基本操作。此外,芯片还集成了 1.5 KB 的数据 Flash 区域,专用于数据持久化存储。
Flash 存储器地址划分如下:
- 数据 Flash 区域(Data Flash):地址范围为
0x00500000
至0x00500600
(共 1.5 KB) - 代码 Flash 区域(Code Flash):地址起始于
0x00000000
,总容量为 32 KB
2. flash的操作方式
2.1 页擦除
sector擦除(每个Sector容量为512Byte),擦除时间由硬件实现,也可以通过FLSERCNT配置。操作流程如下:
/***********************************************************************************************************************
* Function Name: EraseSector
* @brief Sector Erase Flash
* @param adr - sector address of user code flash
* @return status: 0 - OK, 1 - Failed
***********************************************************************************************************************/
int EraseSector (uint32_t adr)
EraseSector (0x500200);
2.2 全片擦除
chip擦除,擦除时间由硬件实现,也可以通过FLCERCNT配置。
/***********************************************************************************************************************
* Function Name: EraseChip
* @brief Chip Erase Flash
* @param adr - Any address of user code flash
* @return None
***********************************************************************************************************************/
int EraseChip (uint32_t adr)
2.3 编程(Word program)
word编程,写入时间由硬件实现,也可以通过PROCNT配置。
/***********************************************************************************************************************
* Function Name: ProgramPage
* @brief Write data to Flash
* @param adr - Page Start Address
* @param sz - Page Size
* @param buf - Page Data
* @return None
***********************************************************************************************************************/
int ProgramPage (uint32_t adr, uint32_t sz, uint8_t *buf)
uint8_t buf[128] = {0};
for(i=0; i<128; i++){
buf[i] = 0xAA550000 + i;
}
ProgramPage (0x500200, sizeof(buf), (uint8_t *)buf);
2.4 闪存读取
uint32_t value = *(uint32_t *)0x500000;
2.5 官方推荐的flash写入API——flash_write
推荐使用flash_write函数擦写Data Flash或Code Flash,因为它能自动判断是否需要擦除。如果目标区域时空白的,它会省略擦除,直接写入。并且支持按Byte写入。
/***********************************************************************************************************************
* 函数名称: flash_write
* @简介 向Flash区域写入数据。自动判断是否需要擦除。
* 如果目标区域为空白,则跳过擦除,直接写入。
* 否则,将Flash中的数据保存到RAM,擦除Flash,然后再写入Flash。
* @参数 adr - 页起始地址
* sz - 页大小
* buf - 页数据
* @返回值 status - MD_OK 或 MD_ERROR
* @注意 sz 必须小于或等于 SECTOR_SIZE,否则返回 MD_ERROR,且不会更改 Flash 内容。
***********************************************************************************************************************/
MD_STATUS flash_write(uint32_t adr, uint32_t sz, uint8_t *buf)
flash_write(0x500000, sizeof(tmp), (uint8_t *)tmp);
3. 使用范例
设备上电后检查是否存在初始化标志,如果没有,则写入默认配置;如果已经写入过配置,则从 Flash 读取使用。
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#define CONFIG_FLASH_ADDR 0x00500000 // Data Flash 起始地址
#define CONFIG_FLAG 0xA5 // 初始化标志位
#define CONFIG_SIZE sizeof(DeviceConfig)
#define SECTOR_SIZE 512
typedef struct {
uint8_t init_flag; // 初始化标志
uint32_t device_id; // 设备ID
uint32_t baudrate; // 通信波特率
uint8_t reserved[16]; // 预留空间
} DeviceConfig;
// RAM 中保存配置
DeviceConfig g_device_config;
// 默认配置
const DeviceConfig default_config = {
.init_flag = CONFIG_FLAG,
.device_id = 0x12345678,
.baudrate = 115200,
.reserved = {0}
};
void LoadOrInitDeviceConfig(void)
{
// 从 Flash 中读取当前配置
memcpy(&g_device_config, (void *)CONFIG_FLASH_ADDR, CONFIG_SIZE);
// 检查是否已初始化
if (g_device_config.init_flag != CONFIG_FLAG) {
// 未初始化,写入默认配置
memcpy(&g_device_config, &default_config, CONFIG_SIZE);
if (flash_write(CONFIG_FLASH_ADDR, CONFIG_SIZE, (uint8_t *)&g_device_config) != MD_OK) {
// Flash 写入失败,进入错误处理
while (1);
}
}
}