单片机之flash读写

单片机之flash读写,第1张

文章目录
  • 《雅特力MCU的flash读写 *** 作》

    • 一、背景知识


    • 二、雅特力官方固件提供的API接口函数

      • 2-1解锁上锁函数
      • 2-2获取flash状态函数
      • 2-3擦除函数
      • 2-4写 *** 作函数
      • 2-5等待 *** 作完成函数
      • 2-6读 *** 作

    • 三、 *** 作步骤

      • 3-1流程

    • 四、注意事项

《雅特力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、写入数据之前需要擦除地址上的数据(每次擦除以整页擦除为单位)

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/langs/584850.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-04-12
下一篇2022-04-12

发表评论

登录后才能评论

评论列表(0条)

    保存