1037|1

107

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【兆易GD32H759I-EVAL】 内部Flash 读写实验 [复制链接]

 

通过本实验主要内容:

• FMC控制器原理;

• FMC擦写读操作;

 

 

GD32H7系列的MCU FLASH存储器区域分类

  • 高达3840KB主FLASH存储器;
  • 高达64KB引导装载程序(boot loader)信息块存储器;
  • 器件配置的选项字节。

 

FMC(Flash Memory Controller)为GD32H7XX系列MCU提供了全面的片上Flash内存管理功能:

  1. Flash控制器(FMC)
    • FMC负责管理和控制GD32H7XX系列MCU上的Flash内存。
    • 它提供了所有必要的接口和功能,用于执行Flash内存的读取、编程(写入)和擦除操作。
  2. Flash内存大小
    • GD32H7XX系列MCU配备了高达3840KB(或3.75MB)的片上Flash内存。
    • 这片内存可用于存储程序代码、常量数据或可修改的数据。
  3. 读取操作
    • Flash支持多种读取操作,包括64字节双字(即128位)、32位整字、16位半字和字节读操作。
    • 这些不同的读取方式可以满足不同性能和应用需求。
  4. 编程(写入)操作
    • Flash编程支持64位双字(即8字节)和32位整字编程。
    • 这意味着你可以直接写入一个完整的双字或整字到Flash内存中,而不需要单独写入每个字节。
  5. 擦除操作
    • FMC支持扇区擦除和整片擦除两种操作。
    • 扇区擦除允许你选择性地擦除Flash内存中的某个特定区域,而整片擦除则会清除整个Flash内存。
  6. 代码保护区域
    • Flash内存包含专用的代码保护区域,这些区域只能执行,不能被读取或写入。
    • 这种设计有助于保护存储在Flash中的程序代码免受未授权访问或篡改,从而增强了系统的安全性。
    • 它也支持二次合作开发,因为开发者可以在不暴露原始代码的情况下,与其他团队或合作伙伴共享硬件平台。
  7. 其他特性
    • Flash内存可能还具有其他特性,如耐久性(可擦写次数)、读取速度、写入延迟等,这些都会影响Flash内存在具体应用中的性能和用途。

 

 

 

闪存包括3840KB字节主闪存,分为960个扇区,扇区大小为4KB,和64KB用于引导加载程序的信息块。主存储闪存的每个扇区都可以单独擦除 。

 

有关Flash擦写操作均需要先解锁Flash,然后进行擦写操作,擦写完成后再进行锁Flash,注意Flash特性只能由1写0,也就是Flash需要先擦除才能写入新的数据,如果确保写入地址的数据为全0xFF,也可以直接写入。读取Flash数据可以采取直接寻址的方式进行读取。

 

函数接口

解锁FMC_CTL寄存器  fmc_unlock 函数

fmc_unlock 函数的目标是解锁 FMC(Flash Memory Controller)的控制寄存器(FMC_CTL)

 

 

锁定FMC_CTL寄存器

/*!
    \brief      unlock FMC_CTL register
    \param[in]  none
    \param[out] none
    \retval     none
*/
void fmc_unlock(void)
{
    if((RESET != (FMC_CTL & FMC_CTL_LK))) {
        /* write the FMC key */
        FMC_KEY = UNLOCK_KEY0;
        FMC_KEY = UNLOCK_KEY1;
    }
}

函数首先 ,检查是否已经解锁,如果 FMC 控制器是锁定的,函数会连续写入两个解锁密钥(UNLOCK_KEY0 和 UNLOCK_KEY1)到 FMC_KEY 寄存器中。这通常是微控制器特定的解锁序列,用于安全地解锁 Flash 控制器的配置寄存器。

 

锁定FMC_CTL寄存器
/*!
    \brief      lock FMC_CTL register
    \param[in]  none
    \param[out] none
    \retval     none
*/
void fmc_lock(void)
{
    /* set the LK bit*/
    FMC_CTL |= FMC_CTL_LK;
}

  全字编程

/*!
    \brief      FMC program a word at the corresponding address
    \param[in]  address: address to program
    \param[in]  data: word to program
    \param[out] none
    \retval     state of FMC
      \arg        FMC_READY: the operation has been completed
      \arg        FMC_BUSY: the operation is in progress
      \arg        FMC_WPERR: erase/program protection error
      \arg        FMC_PGSERR: program sequence error
      \arg        FMC_RPERR: read protection error
      \arg        FMC_RSERR: read secure error
      \arg        FMC_ECCCOR: one bit correct error
      \arg        FMC_ECCDET: two bits detect error
      \arg        FMC_OBMERR: option byte modify error
      \arg        FMC_TOERR: timeout error
*/
fmc_state_enum fmc_word_program(uint32_t address, uint32_t data)
{
    fmc_state_enum fmc_state = FMC_READY;

    /* wait for the FMC ready */
    fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);

    if(FMC_READY == fmc_state) {
        /* set the PG bit to start program */
        FMC_CTL |= FMC_CTL_PG;
        __ISB();
        __DSB();
        REG32(address) = data;
        __ISB();
        __DSB();
        /* wait for the FMC ready */
        fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
        /* reset the PG bit */
        FMC_CTL &= ~FMC_CTL_PG;
    }

    /* return the FMC state */
    return fmc_state;
}

 

 

实验代码

/*!
* 说明       读取Flash地址数据
* 输入[1]    write_read_addr:需要读取的Flash地址
* 返回值     读取的数据
*/
uint8_t fmc_read_8_data(uint32_t write_read_addr)
{
		return *(uint8_t *)write_read_addr;
}


/*!
* 说明       读取Flash地址数据
* 输入[1]    write_read_addr:需要读取的Flash地址
* 返回值     读取的数据
*/
uint8_t fmc_read_32_data(uint32_t write_read_addr)
{
		return *(uint32_t *)write_read_addr;
}


/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* enable the CPU Cache */
    cache_enable();
	  uint8_t x  = 0;
	  gd_eval_com_init(EVAL_COM);
	  printf(" address = %02x\n\r", x);
//    systick_config();
    /* initialize led on the board */
    gd_eval_led_init(LED1);
//    gd_eval_led_init(LED2);
//	
	      __disable_irq();
			  //解锁
		    fmc_unlock();

				/* 清除所有挂起的标志 */
				fmc_all_flags_clear();
				/* erase the flash sectors */
	     
				
				fmc_sector_erase(FMC_WRITE_START_ADDR);
        fmc_all_flags_clear();
			  //上锁
        fmc_lock();
			  __enable_irq(); 
				
				
	  address = fmc_read_32_data(FMC_WRITE_START_ADDR);
	
    printf(" address = %02x\n\r", address);
		 
    /* 判断要不要擦写 */
    if(fmc_read_32_data(FMC_WRITE_START_ADDR) != data)
		{
			  __disable_irq();
			  //解锁
		    fmc_unlock();

				/* 清除所有挂起的标志 */
				fmc_all_flags_clear();
				/* erase the flash sectors */
				
				fmc_sector_erase(FMC_WRITE_START_ADDR);
        fmc_all_flags_clear();
			  fmc_word_program(FMC_WRITE_START_ADDR, data);
			  fmc_all_flags_clear();
			  //上锁
        fmc_lock();
			  __enable_irq(); 
    }
    
		address = fmc_read_32_data(FMC_WRITE_START_ADDR);
    printf(" address = %02x\n\r", address);


    while(1) {
			gd_eval_led_toggle(LED1);

			
    }
}

 

 

实验现象

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

最新回复

我觉得可以打印个时间(滴答定时器)然后看看读写速率。   详情 回复 发表于 2024-6-30 11:50
点赞 关注
 
 

回复
举报

7159

帖子

2

TA的资源

版主

沙发
 

我觉得可以打印个时间(滴答定时器)然后看看读写速率。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表