本文主要是介绍华大flash EFM使用(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1,嵌入式 Flash 具有三个主接口:
· 64 位 ITCM 接口:
– 该接口连接 Cortex-M7 的 ITCM 总线,用于指令执行以及数据读访问。
– ITCM 接口不支持写访问。
– 支持 64 个标准化缓存行, 256 位宽( ART 加速器)。
· 64 位 AHB 接口:
– 该接口通过 AHB 总线矩阵连接 Cortex-M7 的 AXI 总线,用于代码执行以及读写
访问。
– 无论寻址的 Flash 接口是 TCM 还是 AHB, Flash 上的 DMA 和外设 DMA 数据传输
均通过 AHB 接口完成。
· 32 位 AHB 寄存器接口:
– 用于访问控制寄存器和状态寄存器。
2,Flash 中断
如果将 FLASH_CR 寄存器中的操作结束中断使能位 (EOPIE) 置 1,则在擦除或编程操作结
束时,即 FLASH_SR 寄存器中的繁忙位 (BSY) 清零(操作成功完成或未成功完成)时,将
产生中断。此时, FLASH_SR 寄存器中的操作结束 (EOP) 位置 1。
如果在请求编程、擦除或读操作期间出现错误,则 FLASH_SR 寄存器中的以下错误标志位之
一将置 1:
· PGAERR、 PGPERR、 ERSERR(编程错误标志)
· WRPERR(保护错误标志)
这种情况下, FLASH_CR 寄存器中的错误中断使能位 (ERRIE) 置 1,并且如果 FLASH_SR
寄存器中的操作错误位 (OPERR) 置 1,则将产生一个中断。
3,FLASH 具有以下主要特性:
容量高达 2Mbytes,由两块 1Mbytes 的 FLASH 构成,共 256 个扇区,每个扇区为
8Kbytes。 块 0 中扇区 0~扇区 15 为可配置为 OTP 区域。
OTP(One Time Program)区域共 134KBytes, 其中 128Kbytes 配置在块 0 地址
0x0000_0000~0x0001_FFFF, 6Kbytes 配置在地址 0x0300_0000~0x0300_17FF。地址
0x0300_1800~0x0300_1AD7 为 OTP 数据锁存区。
128 位宽数据读取,读缓存 128 位宽缓冲,加速代码执行。
编程单位为 4bytes,擦除单位为 8Kbytes。
4,flash编程常用接口举例读写说明:
单次编程无回读功能
单编程无回读模式设定步骤如下:
1) 解除 FLASH 的寄存器写保护。 (EFM_FAPRT 先写 0x0123, 再写 0x3210)
2) 解除 EFM_KEY1 锁定。 (EFM_KEY1 先写 0x01234567, 再写 0xFEDCBA98)
3) 设定单次编程模式。 (EFM_FWMC.PEMODE[2:0]=001)
4) 解除写保护。 (EFM_ F0/1NWPRTx(x=0~3)对应位设定为 1)
5) 对编程地址写入 32 位数据
6) 等待 FLASH 处于空闲状态。 (EFM_FSR.RDY0/1=1)
7) 判断编程自读取结果标志位。 (EFM_FSR.MISMTCH0/1)
如为 0,则表示编程成功;为 1 表示该 FLASH 地址已遭破坏,永久废弃。
8) 清除编程结束标志位。 (EFM_FSR.OPTEND0/1)
对 已 锁 存 的 OTP 地 址 发 行 单 编 程 回 读 写 操 作 , 编 程 不 成 功 , 标 志 位
EFM_FSR.OTPWERR0 置位。
a,解除 FLASH 的寄存器写保护
__STATIC_INLINE void EFM_REG_Lock(void);
b,解除 EFM_KEY1 锁定
void EFM_FWMC_Cmd(en_functional_state_t enNewState)
{
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));if (ENABLE == enNewState) {
WRITE_REG32(CM_EFM->KEY1, 0x01234567UL);
WRITE_REG32(CM_EFM->KEY1, 0xFEDCBA98UL);
} else {
SET_REG32_BIT(CM_EFM->FWMC, EFM_FWMC_KEY1LOCK);
}
}调用:EFM_FWMC_Cmd(ENABLE);
c,解除写保护
void EFM_SequenceSectorOperateCmd(uint32_t u32StartSectorNum, uint16_t u16Count, en_functional_state_t enNewState)
解除从u32StartSectorNum开始的u16Count个sector的写保护锁。
调用:EFM_SequenceSectorOperateCmd(0, 256U, ENABLE);
也有单个的解保护锁:
void EFM_SingleSectorOperateCmd(uint8_t u8SectorNum, en_functional_state_t enNewState)
d,单个数据的写入
int32_t EFM_SingleProgram(uint32_t u32Addr, uint32_t u32Data)
批量数据的写入:
int32_t EFM_Program(uint32_t u32Addr, uint8_t *pu8Buf, uint32_t u32Len)
int32_t EFM_SequenceProgram(uint32_t u32Addr, uint32_t u32Len, const uint32_t * pu32Buf)
e,写完后带回读校验,看返回值推测校验结果
不带校验的读:
int32_t EFM_ReadByte(uint32_t u32Addr, uint8_t *pu8ReadBuf, uint32_t u32ByteLen)
待校验的读:
int32_t EFM_ProgramWordReadBack(uint32_t u32Addr, uint32_t u32Data)
f, 等待 FLASH 处于空闲状态
#define SET 1
do {
flag1 = EFM_GetStatus(EFM_FLAG_RDY);
flag2 = EFM_GetStatus(EFM_FLAG_RDY1);
} while ((SET != flag1) || (SET != flag2));
g, 清除编程结束标志位
EFM_SequenceSectorOperateCmd(0, 256U, DISABLE);
EFM_FWMC_Cmd(DISABLE);
__STATIC_INLINE void EFM_REG_UNLock(void);
单编程回读功能:判断编程自读取结果标志位。 (EFM_FSR.MISMTCH0/1)
如为 0,则表示编程成功;为 1 表示该 FLASH 地址已遭破坏,永久废弃
5,擦除功能
对 FLASH 进行扇区擦除操作后,该扇区内地址(8KBytes 空间)数据刷新为全 1。扇区擦
除操作设定步骤如下:
1) 解除 FLASH 的寄存器写保护(EFM_FAPRT 先写 0x0123, 再写 0x3210)。
2) 解除 EFM_KEY1 锁定。 (EFM_KEY1 先写 0x01234567, 再写 0xFEDCBA98)
3) 设定擦除模式(EFM_FWMC.PEMOD[2:0]=100)。
4) 解除写保护。 (EFM_ F0/1NWPRTx(x=0~3)对应位设定为 1)
5) 对需要擦除扇区内的任意地址(地址需以 4 对齐)写入 32 位任意值。
6) 等待 FLASH 处于空闲状态。 (EFM_FSR.RDY0/1=1)
7) 清除擦除结束标志位。 (EFM_FSR.OPTEND0/1)
对已锁存的 OTP 地址发行擦除操作,擦除不成功, OTP 区域数据保留,标志位
EFM_FSR.OTPWERR0 置位。
获取块的基地址:
#define SECTOR_SIZE (0x2000UL)
#define SECTOR_ADDR(X) (uint32_t)(SECTOR_SIZE *(x))en_result_t EFM_SectorErase(uint32_t u32Addr);
这篇关于华大flash EFM使用(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!