GD32替换STM32后 写片上闪存(flash)失败的解决方法

型号

使用的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();
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值