型号
使用的GD32C103CB等引脚替换STM32F103CB
问题
使用hal库的flash操作接口,片上flash可以正常擦除,但是无法写入,使用jflash读取相应的地址内容为FF
解决办法
下载gd的fmc操作库
GD资料下载传送门
下载完之后解压,在Firmware\GD32C10x_standard_peripheral路径下分别找到gd32c10x_fmc.c gd32c10x_fmc.h
修改fmc文件
修改.h文件的开头如下
//#include "gd32c10x.h"
#include "stm32f1xx_hal.h"
/*从gd的其他头文件拷贝过来的宏 fmc文件要用到*/
#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr))
#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr))
#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr))
#define BIT(x) ((uint32_t)((uint32_t)0x01U<<(x)))
#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end))))
#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start))
/* FMC and option bytes definition */
/*原来是FMC_BASE 需要找到stm32f10x的和FMC_BASE相同的地址或自定义一个也行,c103cb的地址和stm的FLASH_R_BASE是一致的
*查询datesheet,找到Memory map中FMC的地址为AHB1下的0x40023000 - 0x400233FF这个地址,即FMC指向0x40023000
*/
#define FMC FLASH_R_BASE /*FMC_BASE*//*!< FMC register base address */
/*以下部分不用写到.h中*/
/*gd32c10x.h中*/
#define AHB1_BUS_BASE ((uint32_t)0x40018000U) /*!< ahb1 base address */
#define FMC_BASE (AHB1_BUS_BASE + 0x0000A000U) /*!< FMC base address */
/*stm32f100xb.h中*/
#define PERIPH_BASE 0x40000000UL /*!< Peripheral base address in the alias region */
#define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000UL)
#define FLASH_R_BASE (AHBPERIPH_BASE + 0x00002000UL) /*!< Flash registers base address */
/*两者均为0x40023000 这个地址*/
FMC的内存映射如下:
修改完毕之后将fmc文件加入到项目中即可
使用
需要注意 flash只能由1写为0 所以写数据之前需要先擦除(置为FF)
根据用户手册可知,闪存一页的大小为1k
擦除一页
/*擦除一页 起始地址为address*/
/* unlock the flash program/erase controller */
fmc_unlock();
/* clear all pending flags */
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGAERR | FMC_FLAG_PGERR);
/* erase the flash pages */
fmc_page_erase(address);
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGAERR | FMC_FLAG_PGERR);
/* lock the main FMC after the erase operation */
fmc_lock();
写一页
/*写一页 起始地址为address,数据为char* program 数据大小为1k*/
uint32_t fldata32;
fmc_unlock();
for (i = 0; i < 256; i++)
{
fldata32 = (program[i*4+0] << 0) + (program[i*4+1] << 8) + (program[i*4+2] << 16) + (program[i*4+3] << 24);
fmc_word_program((address+i*4), fldata32);
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGAERR | FMC_FLAG_PGERR );
}
fmc_lock();