写出GD32L233/235在读写flash的区别(用于OTA功能)

1.说到OTA功能,实际上 往flash 指定区域写 数据, 拷贝数据,然后 跳转, 必要时 注意单片机的偏移量。

2.不多说废话,进入正题,区别这两款 单片机的在读写flash的 不同点. go

在写本文时,L233支持单字写入,而L235只有双字写入. 一个写入地址+4 一个写入地址+8

在单片机里面表示 大概是 address += sizeof(uint32_t) address += sizeof(uint64_t)

下面是写入flash 代码:

记得在写入前 擦除

cpp 复制代码
void fmc_flags_clear(void)
{
    fmc_flag_clear(FMC_FLAG_END);
    fmc_flag_clear(FMC_FLAG_WPERR);
    fmc_flag_clear(FMC_FLAG_PGAERR);
    fmc_flag_clear(FMC_FLAG_PGERR);
}
void WriteFlash(uint32_t address,const uint8_t *pBuffer,uint32_t Numlengh)
{
    #ifdef GD32E230  //GD32L233
	uint32_t i,temp;
  	fmc_unlock();
	for(i = 0; i < Numlengh;i+= 4)
	{
		temp =  (uint32_t)pBuffer[i+3]<<24;
		temp |=  (uint32_t)pBuffer[i+2]<<16;
		temp |=  (uint32_t)pBuffer[i+1]<<8;
		temp |=  (uint32_t)pBuffer[i];
		fmc_word_program(address+i,temp);
		fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
	}
  	fmc_lock();
    #endif

    #ifdef GD32L235
	uint32_t i;
    uint32_t temp1,temp2;
    uint64_t temp_v;
  	fmc_unlock();
	for(i = 0; i < Numlengh;i+=8)
	{
        temp1 =  (uint32_t)pBuffer[i+3]<<24;
		temp1 |=  (uint32_t)pBuffer[i+2]<<16;
		temp1 |=  (uint32_t)pBuffer[i+1]<<8;
		temp1 |=  (uint32_t)pBuffer[i];

        temp2 =   (uint32_t)pBuffer[i+7]<<24;
		temp2 |=  (uint32_t)pBuffer[i+6]<<16;
		temp2 |=  (uint32_t)pBuffer[i+5]<<8;
		temp2 |=  (uint32_t)pBuffer[i+4];

        temp_v = ((uint64_t)temp2) << 32 | temp1;

        fmc_doubleword_program(address+i,temp_v);
		fmc_flags_clear();
	}
  	fmc_lock();
    #endif
}

这个是 自己写的擦除一页 数据,当然可以参考 提供的demo去实现,看自己需求

cpp 复制代码
uint8_t EarseFlash_1K(uint32_t address){
    //PR_INFO("begin_earse,0x%X\r\n",address);
    fmc_state_enum fmc_state;
	if(address % 1024 == 0)
	{
        fmc_unlock();
        fmc_flags_clear();
		fmc_state = fmc_page_erase(address);
        if(fmc_state == FMC_READY){
            PR_INFO("erase_ok\r\n");
        }else{
            PR_ERR("erase_fail\r\n");
        }
        fmc_flags_clear();
        fmc_lock();
	}
	else
	{
        PR_NOTICE("without_EarseFlash_1K\r\n");
		return 0;
	}
	return 1;
}

接下来是 读取 双字,也就是在L235上的读取

cpp 复制代码
void ReadFlashTwoWorld(uint32_t address,uint8_t *Nbuffer,uint32_t  length){
    uint64_t temp = 0;
    uint32_t count = 0;
	while(count < length){
        temp = *((volatile uint64_t *)address);
        *Nbuffer++ = (temp & 0xff);
		count++;
        if(count >= length)break;
        *Nbuffer++ = (temp >> 8) & 0xff;
		count++;
        if(count >= length)break;
        *Nbuffer++ = (temp >> 16) & 0xff;
		count++;
        if(count >= length)break;
        *Nbuffer++ = (temp >> 24) & 0xff;
		count++;
        if(count >= length)break;
        *Nbuffer++ = (temp >> 32) & 0xff;
		count++;
        if(count >= length)break;
        *Nbuffer++ = (temp >> 40) & 0xff;
		count++;
        if(count >= length)break;
        *Nbuffer++ = (temp >> 48) & 0xff;
		count++;
        if(count >= length)break;
        *Nbuffer++ = (temp >> 56) & 0xff;
		count++;
        if(count >= length)break;
        address += sizeof(uint64_t);
    }
}

以及 下面的 读取单字的 ( GD32L233 以及 GD32E230 )

cpp 复制代码
void ReadFlash(uint32_t address,uint8_t *Nbuffer,uint32_t  length)
{
	uint32_t temp = 0;
	uint32_t count = 0;
	while(count < length)
	{
		temp = *((volatile uint32_t *)address);
		*Nbuffer++ = (temp & 0xff);
		count++;
    if(count >= length)
      break;
	  *Nbuffer++ = (temp >> 8) & 0xff;
		count++;
		if(count >= length)
      break;
		*Nbuffer++ = (temp >> 16) & 0xff;
		count++;
		if(count >= length)
      break;
		*Nbuffer++ = (temp >> 24) & 0xff;
		count++;
		if(count >= length)
      break;

        #ifdef GD32E230       //GD32L233
		    address += 4;
        #endif
	}
}
相关推荐
黑白园19 分钟前
ADC读取XY二轴操纵杆数据通过I2C_GPIO模拟 控制0.96寸OLED显示
stm32·单片机·嵌入式硬件
一个平凡而乐于分享的小比特1 小时前
还在手动挡写单片机?MicroPython 一脚油门踩进 Python 硬件世界
单片机·嵌入式硬件·micropython
FreakStudio2 小时前
WIZnet-EVB-Pico2开始,用MicroPython玩转以太网开发
python·单片机·嵌入式·大学生·面向对象·技术栈·并行计算·电子diy·电子计算机
LCG元2 小时前
STM32实战:基于STM32F103的工业仪表数据采集(多路ADC)
stm32·单片机·嵌入式硬件
BT-BOX3 小时前
Stm32CubeMX+Proteus仿真--STM32外部中断
stm32·单片机·proteus
瑶池酒剑仙3 小时前
C++类和对象完全指南:从封装继承多态到内存布局的面向对象宝典(雨夜论道)
c语言·开发语言·c++·visual studio
三品吉他手会点灯3 小时前
C语言学习笔记 - 27.C编程预备计算机专业知识 - 什么是字节
c语言·开发语言·笔记·学习
森利威尔电子-4 小时前
森利威尔SL8700 降压型大功率 LED 恒流驱动器:5A/95%效率,支持 PWM/模拟调光
单片机·嵌入式硬件·集成电路·芯片·电源芯片
三佛科技-187366133974 小时前
GP8892SEH贴片SOP7省外围5V2A隔离型原边反馈芯片直接替代MT3723
单片机·嵌入式硬件
Quinn274 小时前
正点原子 STM32MP257 修复异核 FreeRTOS 例程 osDelay() 函数比 HAL_Delay() 延时快的问题
stm32·单片机·嵌入式硬件