【GD32学习】五、FMC Flash 单字节读写实验

文章目录


前言

准备

上一篇


一、函数

1、单字节写

/*!
    \brief      FLASH写
    @Address    操作地址
    @pData      数据指针
    @Size       数据长度
*/
uint8_t FMC_FLASH_Write( uint32_t Address, uint8_t *pData, uint16_t Size )
{
    fmc_state_enum FLASHStatus;
    uint16_t i;    
    uint32_t AddressTemp = 0;

    /*写入数据*/
    AddressTemp = Address;
    /* 解锁 */
    fmc_unlock();
    /* 操作FMC前先清空STAT 状态寄存器,非常必要*/
    fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
    
    for (i=0; i<Size; i++)
    {
        FLASHStatus = fmc_byte_program(AddressTemp, pData[i]);
        if (*((volatile uint8_t*)AddressTemp) != pData[i])
        {
            return 1; //校验错误
        }

        if (FLASHStatus != FMC_READY)
        {
            return 1; //写错误
        }

        AddressTemp += 1;//地址累加
    }
    /* 上锁 */
    fmc_lock();
    return 0;
}

2、字节读

/*!
    \brief      FLASH读
    @Address    操作地址
    @pData      数据指针
    @Size       数据长度
*/
uint8_t FMC_FLASH_Read(  uint32_t Address, uint8_t *pData, uint16_t Size )
{
    uint32_t rdAddr = Address;

    for( uint16_t dataIndex = 0; dataIndex < Size; dataIndex++ )
    {
        pData[dataIndex] = *( __IO uint8_t* ) rdAddr;
        rdAddr += 1;//地址累加
    }
    return 0;
}

3、页擦除

/*!
    \brief          FLASH页擦除
    @PageAddress    操作页起始地址
    @PageNum        擦除页数
*/
uint8_t FMC_FLASH_ErasePage( uint32_t PageAddress, uint8_t PageNum )

    uint8_t i;
    uint32_t erase_addr = PageAddress & (~(PAGE_SIZE-1));//保证地址4K对齐
    /* 解锁 */
    fmc_unlock();
    /* 操作FMC前先清空STAT 状态寄存器,非常必要*/
    fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);    
    for (i=0; i < PageNum; i++)
    {
        if (fmc_page_erase(erase_addr) != FMC_READY)
        {
            return 1;
        }
        
        erase_addr += PAGE_SIZE;
    }
    /* 上锁 */
    fmc_lock();   
    return 0;
}

其中 页大小为4K,#define PAGE_SIZE      (4096U)

二、实验例程

1、把第四扇区的第一和第二页作为存储测试

 地址定义

#define PAGESIZE          4096U
#define PAGE1_START_ADDR  0x08010000                //扇区4的起始地址,第一页 地址
#define PAGE2_START_ADDR  (PAGE1_START_ADDR+PAGESIZE )// 第二页 地址

2、测试程序

 

3、测试步骤和结果

进入仿真,打上如上图断点,查看这两个页地址数据

a、第一个断点时,查看第一页地址看是否写入成功

 

b、第二个断点时,查看第二页地址看是否写入成功

 

 

 

c、第三个断点时,查看第一页地址看是否读数据成功

 

d、第四个断点时,查看第一页是否页擦除成功

 

e、第五个断点,查看第二页是否页擦除成功