FLASH具有以下主要特性:
容量高达512 KBytes(其中有32Bytes为功能保留位) 分为64个扇区,每个扇区为8KBytes。
OTP(One Time Program)区域共1020Bytes,分为960Bytes的数据区和60Bytes 的锁存区。
128位宽数据读取。
编程单位为4Bytes,擦除单位为8KBytes。
在512KB产品中,FLASH地址结构如下图所示。
注意: - 扇区63 中地址 0x0007_FFE0~0x0007_FFFF 共 32Bytes 为功能保留地址;对这 32Bytes地址进行编程、扇区擦除、全擦除,FLASH数据不会改变,对这些地址读,读到 数据为全1。
在256KB产品中,FLASH地址结构如下图所示。
代码采用官方数据库案例:EFM扇区擦除,单编程,单编程回读。
需要开启LL_EFM_ENABLE——DDL_ON
修改后代码如下(注释)
/* 读取Flash中保存的压力补偿值 */
int EFM_ReadValue(void)
{
/* 为某些必需的外围设备注册写启用 */
LL_PERIPH_WE(EXAMPLE_PERIPH_WE);
/* 等待Flash就绪 */
while (SET != EFM_GetStatus(EFM_FLAG_RDY));
/* EFM_FWMC写入启用 */
EFM_FWMC_Cmd(ENABLE);
/* 扇区13区范围:0x00018000 ~ 0x00019FFF */
u32Addr = EFM_SECTOR_ADDR(EFM_SECTOR13_NUM);
EFM_ReadByte(u32Addr, (uint8_t *)&u32ReadData1, sizeof(PressData));
/* EFM_FWMC写入禁用 */
EFM_FWMC_Cmd(DISABLE);
usb_printf("Press Com_value : %d pa\r\n", u32ReadData1);
return (int)u32ReadData1;
}
/* 读取Flash中保存的占空比 */
int EFM_ReadRatio(void)
{
/* 为某些必需的外围设备注册写启用 */
LL_PERIPH_WE(EXAMPLE_PERIPH_WE);
/* 等待Flash就绪 */
while (SET != EFM_GetStatus(EFM_FLAG_RDY));
/* 启用EFM_FWMC写入 */
EFM_FWMC_Cmd(ENABLE);
/* 扇区13区范围:0x00018000 ~ 0x00019FFF */
u32Addr = EFM_SECTOR_ADDR(EFM_SECTOR13_NUM) + 32;
EFM_ReadByte(u32Addr, (uint8_t *)&u32ReadData2, sizeof(RatioData));
/* EFM_FWMC写入禁用 */
EFM_FWMC_Cmd(DISABLE);
usb_printf("duty cycle : %d %\r\n", u32ReadData2);
return (int)u32ReadData2;
}
/* 往Flash里保存数据 */
void EFM_WriteData(void)
{
uint32_t PressData = value;
uint32_t RatioData = ratio;
/* 为某些必需的外围设备注册写启用 */
LL_PERIPH_WE(EXAMPLE_PERIPH_WE);
/* 等待Flash就绪 */
while (SET != EFM_GetStatus(EFM_FLAG_RDY));
/* EFM_FWMC写入启用 */
EFM_FWMC_Cmd(ENABLE);
/* 删除扇区13 13区范围:0x0001a000 ~ 0x0001bFFF */
u32Addr = EFM_SECTOR_ADDR(EFM_SECTOR13_NUM);
(void)EFM_SectorErase(u32Addr);/* EFM扇区擦除 */
/* 把压力补偿值写到13扇区的闪存 */
while(LL_OK != EFM_ProgramWordReadBack(u32Addr, PressData));
/* 移动指向13扇区闪存的目标地址,继续写入数据 */
u32Addr += 32;
/* 把占空比写到13扇区的闪存 */
while(LL_OK != EFM_ProgramWordReadBack(u32Addr, RatioData));
/* EFM_FWMC写入禁用 */
EFM_FWMC_Cmd(DISABLE);
/* 为某些必需的外围设备注册写保护 */
LL_PERIPH_WP(EXAMPLE_PERIPH_WE);
usb_printf("Com_value setting %d pa\r\n", PressData);
usb_printf("duty ratio setting %d %\r\n", RatioData);
}
切记,往Flash存储器保存新数据时,需要考虑扇区的对齐和数据管理。Flash存储器的读写操作通常是以扇区为单位进行的,每个扇区的大小通常是固定的。因此,在写入新数据之前,需要确保目标位置是在扇区的边界之内,否则可能会导致数据写入错误或损坏。
此外,为了防止在写入新数据时误删自己的程序或其他重要数据,建议在写入新数据之前先备份程序或其他重要数据。同时,在写入新数据之前,也需要确保目标位置没有其他重要的数据,以避免误删其他数据。
最后,在写入新数据时,也需要按照Flash存储器的读写规范进行操作,避免不当的操作导致Flash存储器的损坏或数据丢失。建议在使用Flash存储器之前先仔细阅读相关技术文档或参考手册,并遵循正确的操作步骤。