家星 · 2022年04月04日

【GD32F310开发板试用】FMC功能测试

简介

FMC是GD32MCU的内部flash读写控制器,主要功能是对主编程块和选项字节的擦写。
本次测试使用的是GD32F310K8T6,
其flash大小为64K,共64页,每页大小1K,对应的地址为0x0800 0000--0x0800 FFFF

本次实验的串口部分的代码来源于
https://aijishu.com/a/1060000000314295

实验流程

  • 开机自动在0x08008000-0x0800C000区域内写入数据,之后对写入的数据重新读取,判断是否写入成功
  • 通过串口0输出

    使用到的固件库函数

  • 页擦除函数:
    fmc_state_enum fmc_page_erase(uint32_t page_address);
  • 字写入函数
    fmc_state_enum fmc_word_program(uint32_t address, uint32_t data);

    代码部分

    .c文件

    #include "gd32f3x0.h"
    #include "bsp_interflash.h"
    #include "bsp_usart.h"
    
    
    int InternalFlash_Test(void)
    {
        uint32_t EraseCounter = 0x00;     //记录要擦除多少页
        uint32_t Address = 0x00;                //记录写入的地址
        uint32_t Data = 0x3210ABCD;            //记录写入的数据
        uint32_t NbrOfPage = 0x00;            //记录写入多少页
        
        fmc_state_enum FLASHStatus = FMC_READY; //记录每次擦除的结果    
        TestStatus MemoryProgramStatus = PASSED;//记录整个测试结果
        
    
      /* 解锁 */
      fmc_unlock();
    
      /* 计算要擦除多少页 */
      NbrOfPage = (WRITE_END_ADDR - WRITE_START_ADDR) / FLASH_PAGE_SIZE;
    
    
      /* 按页擦除*/
      for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FMC_READY); EraseCounter++)
      {
        FLASHStatus = fmc_page_erase(WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter));
        }
      
      /* 向内部FLASH写入数据 */
      Address = WRITE_START_ADDR;
    
      while((Address < WRITE_END_ADDR) && (FLASHStatus == FMC_READY))
      {
        FLASHStatus = fmc_word_program(Address, Data);
        Address = Address + 4;
      }
    
      fmc_lock();
      
      /* 检查写入的数据是否正确 */
      Address = WRITE_START_ADDR;
    
      while((Address < WRITE_END_ADDR) && (MemoryProgramStatus != FAILED))
      {
        if((*(__IO uint32_t*) Address) != Data)
        {
    MemoryProgramStatus = FAILED;
        }
        Address += 4;
      }
        return MemoryProgramStatus;
    }
    

.h文件

#ifndef BSP_INTERFLASH_H
#define BSP_INTERFLASH_H

#include "gd32f3x0.h"

#define FLASH_PAGE_SIZE    ((uint16_t)0x400)    //1024


//写入的起始地址与结束地址
#define WRITE_START_ADDR  ((uint32_t)0x08008000)
#define WRITE_END_ADDR    ((uint32_t)0x0800C000)



typedef enum 
{
    FAILED = 0, 
  PASSED = !FAILED
} TestStatus;


int InternalFlash_Test(void);

#endif

main.c

#include "gd32f3x0.h"
#include "gd32f310k_start.h"
#include "systick.h"
#include "bsp_interflash.h"
#include "bsp_usart.h"
#include "usart.h"
#include "gpio.h"
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{  
    systick_config();
    My_GPIO_Init();
    My_Usart_MspInit();
    My_Usart_Init();
    /* enable the LED GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    /* configure led GPIO port */ 
    gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
    
    gpio_bit_reset(GPIOA, GPIO_PIN_8);
    usart0_printf("Hello,GD32!\r\n");
    usart0_printf("正在进行读写内部FLASH实验,请耐心等待\r\n");
    
    if(InternalFlash_Test()== PASSED)
    {
        gpio_bit_write(GPIOA, GPIO_PIN_8, SET);
        usart0_printf("读写内部FLASH测试成功\r\n");

    }
    else
    {
        usart0_printf("读写内部FLASH测试失败\r\n");
        gpio_bit_write(GPIOA, GPIO_PIN_8, RESET);
    }    
    
    
    while(1){

    }
}

实验结果

0x0800 8000--0x0800BFFF区域写满0x3210ABCD
1.JPG
2.JPG
3.JPG

推荐阅读
关注数
10694
内容数
187
中国高性能通用微控制器领域的领跑者兆易创新GD系列芯片技术专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息