一、背景知识
1、MCU的flash是存储芯片的一种,通过特定的程序可以修改里面的数据。FLASH在电子以及半导体领域内往往表示Flash Memory的意思,即平时所说的“闪存”,全名叫Flash EEPROM Memory。 flash存储器又称闪存,它结合了ROM和RAM的长处,不仅具备电子可擦除可编程(EEPROM)的性能,还可以快速读取数据(NVRAM的优势),使数据不会因为断电而丢失 ; 本篇文章按照雅特力MCU(AT32F421)官方提供的库函数来编写的,其固件库大部分兼容ST系列的固件。
二、雅特力官方固件提供的API接口函数
2-1解锁上锁函数
- void FLASH_Unlock(void); //解锁函数:在对Flash操作之前必须解锁
- void FLASH_Lock(void); //锁定函数:同理,操作完Flash之后必须重新上锁
2-2获取flash状态函数- FLASH_Status FLASH_GetStatus(void);
2-3擦除函数- FLASH_Status FLASH_ErasePage(uint32_t Page_Address); //擦除一页
- FLASH_Status FLASH_EraseAllPages(void); //擦除所有页
2-4写操作函数- FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data); //32位字写入函数
- FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); //16位半字写入函数
- FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data); //一个字节写入函数
- FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data); //用户选择字节写入函数
2-5等待操作完成函数- FLASH_Status FLASH_WaitForProcess(uint32_t Timeout)
注:在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。所以在每次操作之前,我们都要等待上一次操作完成这次操作才能开始。
2-6读操作
该操作没有相对应的API函数,而是直接从地址处把地址的内容通过指针赋予数组或者变量来保存使用。
三、操作步骤
注:任何有关于flash的操作都必须通过解锁操作来进行接下来的步骤
3-1流程
- 写入数据程序
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_FLASH_WriteBuffer
- * 功能说明: 写数据到 CPU FLASH
- * 形 参:
- * ulFlashAddr: FLASH地址
- * pByte: 数据缓冲区(2个字节)
- * ulSize: 数据大小
- * 返 回 值:
- * FLASH_BSY = 1 忙
- * FLASH_PGRM_FLR 编程错误
- * FLASH_WRPRT_FLR 写保护错误
- * FLASH_PRC_DONE 操作结束
- * FLASH_TIMEOU 超时
- *
- *********************************************************************************************************
- */
- uint16_t bsp_FLASH_WriteBuffer(uint32_t ulFlashAddr, uint16_t *pByte, uint32_t ulSize)
- {
- uint16_t ulCnt;
- uint16_t sign = 0; //标志位
- if (ulFlashAddr < FLASH_BASE || ulFlashAddr + ulSize >= USER_FLASH_END_ADDRESS)
- {
- return FLASH_PGRM_FLR;
- }
- if (ulSize == 0)
- {
- return FLASH_PGRM_FLR;
- }
- /* FLASH 解锁 */
- FLASH_Unlock();
- FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_PRCDN | FLASH_FLAG_PRGMFLR | FLASH_FLAG_WRPRTFLR | FLASH_FLAG_UOBFLR)
- sign = FLASH_ErasePage(STARTADDR); //擦除整页
- if(sign != FLASH_PRC_DONE) //如果没有擦除完成则返回
- return;
- for (ulCnt = 0; ulCnt < ulSize; ulCnt++)
- {
- if (FLASH_ProgramHalfWord(ulFlashAddr, *pByte++) != FLASH_PRC_DONE)
- {
- return FLASH_PGRM_FLR;
- }
- ulFlashAddr+=2;
- }
- /* FLASH加锁,禁止写FLASH控制寄存器 */
- FLASH_Lock();
- return FLASH_PRC_DONE;
- }
- <blockquote><b>读出数据程序</b>
四、注意事项1、每一次的读写操作都需要解锁和上锁,否则可能会造成MCU内地址的读写错乱。
2、写入数据之前需要擦除地址上的数据(每次擦除以整页擦除为单位)
|