单片机之flash读写

《雅特力MCU的flash读写操作》

引用:AT32F421系列超详细参考手册-中文版


一、背景知识

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);
 通过获取Flash状态函数,获取Flash的状态,以便于根据状态对Flash进行操作。该函数返回值是通过枚举类型定义的,在代码中可以看到FLASH_Status类型定义如下(具体含义看注释即可):
typedef enum
{
    
    
    FLASH_BSY = 1, //忙
    FLASH_PGRM_FLR, //编程错误
    FLASH_WRPRT_FLR,//写保护错误
    FLASH_PRC_DONE, //操作结束
    FLASH_TIMEOUT  //超时
} FLASH_Status;

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;
}

读出数据程序
/*
*********************************************************************************************************
*	函 数 名: bsp_FLASH_ReadBuffer
*	功能说明: 读取CPU Flash的内容
*	形    参: 
*	         ulFlashAddr: FLASH地址
*	         pByte: 数据缓冲区(2字节)
*	         ulSize: 数据大小
*	返 回 值: 0.成功 1.失败
*********************************************************************************************************
*/
uint16_t bsp_FLASH_ReadBuffer(uint32_t ulFlashAddr, uint16_t *pByte, uint32_t ulSize)
{
    
    
    uint16_t ulCnt;

    if (ulFlashAddr < FLASH_BASE || ulFlashAddr + ulSize >= USER_FLASH_END_ADDRESS)
    {
    
    
        return FLASH_PGRM_FLR;
    }
    if (ulSize == 0)
    {
    
    
        return 1;
    }
    for (ulCnt = 0; ulCnt < ulSize; ulCnt++)
    {
    
    
        *(pByte++) = *(uint16_t *)ulFlashAddr;
				ulFlashAddr+=2;
    }
    return 0;
}

四、注意事项

1、每一次的读写操作都需要解锁和上锁,否则可能会造成MCU内地址的读写错乱。
2、写入数据之前需要擦除地址上的数据(每次擦除以整页擦除为单位)

猜你喜欢

转载自blog.csdn.net/qq_45865868/article/details/124098225