简介
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