本帖最后由 Afanx 于 2022-8-25 20:22 编辑
使用n32g45x_flash.c库函数。
Flash擦除:
擦除 1页 = 2KB = 0x800字节,填入擦除地址后,会擦除地址所在的一整页。/**
* [url=home.php?mod=space&uid=247401]@brief[/url] 擦除一页2KB (0x800字节) 用时1.6ms
* @param addr 相对FLASH_BASE(0x0800_0000)的偏移地址,范围【0~0x7FFFF】
*/
void Flash_Erase(uint32_t addr)
{
FLASH_Unlock();
FLASH_EraseOnePage(FLASH_BASE + addr); // 擦除1页约1.6ms
FLASH_Lock();
}
Flash写数据:
进行闪存编程操作时(写或擦除),必须打开内部的 RC 振荡器(HSI)。
必须擦除后按【字】写入,不可二次对Flash的位、字节、半字进行修改。(比如不可将0xFFFF_AABB改写覆盖为0xFFFF_0000)
Flash编程过程中,对Flash读操作会锁住Flash总线,此时CPU会暂停运行,等待Flash编程完成,(但不影响保存在iCache中的代码运行)。
基于以上特性,可以连续对Flash写,不需要程序等待,即删除Wait_FlashOpt_Busy()不影响功能。
/* 等待Flash操作完成 */
void Wait_FlashOpt_Busy(void)
{
uint32_t timeOut = 0x00002000; // ProgramTimeout
while (((FLASH->STS & FLASH_FLAG_BUSY) == FLASH_FLAG_BUSY) && (timeOut--)) __NOP();
}
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] Flash写操作,用时约0.112ms每字
* @param addr 相对FLASH_BASE(0x0800_0000)的偏移地址,并且必须按字对齐,范围【0~0x7FFFF】
* @param datPtr 待写入Flash的数据地址
* @param len 待写入Flash的数据长度,单位:字
*/
void Flash_Write(uint32_t addr, uint32_t* datPtr, uint32_t len)
{
if (addr >= FLASH_SIZE) return;
addr &= 0xFFFFFFFC; //字对齐
FLASH_Unlock();
FLASH_ClearFlag(FLASH_STS_CLRFLAG);
Wait_FlashOpt_Busy();
FLASH->CTRL |= FLASH_CTRL_PG;
while (len--) {
*(__IO uint32_t*)(FLASH_BASE + addr) = *(datPtr++);
Wait_FlashOpt_Busy(); // 112us
addr += 4;
}
FLASH->CTRL &= ~FLASH_CTRL_PG;
FLASH_Lock();
}
Flash 总线地址列表:
注意事项:
|