HC32 flash 读写操作 您所在的位置:网站首页 flash编程工具 HC32 flash 读写操作

HC32 flash 读写操作

2024-06-05 14:34| 来源: 网络整理| 查看: 265

flash 读写操作 HC32 flash 简介HC32 flash 操作和时钟之间的关系Flash 的读写操作解锁寄存器单次编程无回读功能单编程有回读连续编程擦除功能全擦除功能 综合应用demo

HC32 flash 简介

HC32F4A0 的flash是两块独立 FLASH 构成 dual bank。容量高2Mbytes,由两块 1Mbytes 的 FLASH 构成,共 256 个扇区,每个扇区为8Kbytes。 块 0 中扇区 0~扇区 15 为可配置为 OTP 区域。

OTP(One Time Program)区域共 134KBytes, 其中 128Kbytes 配置在块 0 地址0x0000_0000~0x0001_FFFF, 6Kbytes 配置在地址 0x0300_00000x0300_17FF。地址0x0300_18000x0300_1AD7 为 OTP 数据锁存区。编程单位为 4bytes,擦除单位为 8Kbytes +在这里插入图片描述 HC32 flash 操作和时钟之间的关系

要正确读取 FLASH 数据,用户需要根据 CPU 动作频率在 FLASH 读模式寄存器 (EFM_FRMC)中正确设定等待周期数(FLWT[3:0])。具体可以参照下表进行相关设置。

在这里插入图片描述 对应相关处理在flash 初始化的时候,更改stc_efm_cfg_t结构体中的u32waitcycle. eg

int Init(void) { /* * Clock stc_efm_cfg_t stcEfmCfg; en_int_status_t flag1; en_int_status_t flag2; uint32_t u32Data = 0xAA5555AAU; uint32_t u32Addr; /* Unlock peripherals or registers */ Peripheral_WE(); /* Configure system clock. HClK = 240MHZ */ BSP_CLK_Init(); /* EFM default config. */ (void)EFM_StructInit(&stcEfmCfg); /* * Clock dosomething(); } //写后回读 if(Ok != EFM_ProgramReadBack(u32Addr + sizeof(u32Data), u32Data)) { dosomething(); } EFM_SectorCmd_Single(EFM_SECTOR_10, Disable); Peripheral_WP(); for (;;) { ; } } 连续编程

在这里插入图片描述 连续编程模式中特别要注意5步骤,连续编程不可以在程序运行的flash上进行,即如果程序运行在flash0 块上,只能在flash1 上进行连续编程。不然程序会死在EFM_SequenceProgram()中。

擦除功能 解除 FLASH 的寄存器写保护(EFM_FAPRT 先写 0x0123, 再写 0x3210)。解除 EFM_KEY1 锁定。 (EFM_KEY1 先写 0x01234567, 再写 0xFEDCBA98)设定擦除模式(EFM_FWMC.PEMOD[2:0]=100)。解除写保护。 (EFM_ F0/1NWPRTx(x=0~3)对应位设定为 1)对需要擦除扇区内的任意地址(地址需以 4 对齐)写入 32 位任意值。等待 FLASH 处于空闲状态。 (EFM_FSR.RDY0/1=1)清除擦除结束标志位。 (EFM_FSR.OPTEND0/1) 对已锁存的 OTP 地址发行擦除操作,擦除不成功, OTP 区域数据保留,标志位 EFM_FSR.OTPWERR0 置位。 对应的库函数为EFM_SectorErase; 全擦除功能

在这里插入图片描述 注意:不论擦除是以扇区进行的,即8K,写入的是后必须为4bytes.

综合应用demo

因为在同一个flash块上无法实现连续编程,因此要进行flash的连续的读写只能通过单次编程实现。

#define HC32FLASH_END (EFM_ADDR_SECTOR255 + 0x2000) int FLASH_ReadBytes(uint32_t readAddr, void *pBuffer, int NumToRead) { uint32_t nread = NumToRead; uint8_t* d = (uint8_t *)pBuffer; const uint8_t* s = (const uint8_t *)readAddr; //判断参数 if (!pBuffer /*|| Address < HC32FLASH_BASE*/ || ((readAddr + NumToRead) >= HC32FLASH_END)) return 0; while (nread >= sizeof(uint32_t) && (((uint32_t)s) *d++ = *s++; nread--; } return (NumToRead - nread); } //使用单次法写入多个数据 int FlashWriteBuff(uint32_t writeAddr,uint32_t u32Len, const uint32_t *pu32Buf) { uint16_t i = 0; uint32_t mm; mm = *pu32Buf; if(NULL == pu32Buf) { return 1; } for(i = 0; i return 1; } writeAddr = writeAddr + sizeof(uint32_t); pu32Buf++; } return 0; } /** * @brief: 写FLASH操作 * @param: Address -- 写入起始地址,要求必须4字节对齐!! Buffer -- 待写入的数据,(uint32_t *) NumToWrite -- 要写入的数据量,单位:字节! * @note: 该函数是用的是单次写入,非连续 * @return: none **/ int FLASH_WriteBytes(uint32_t writeAddr, uint32_t *pBuffer, int NumToWrite) { uint32_t i = 0; uint32_t sectorPos = 0; // 扇区位置 uint32_t sectorOff = 0; // 扇区内偏移地址 uint32_t sectorFre = 0; // 扇区内空余空间 uint32_t offset = 0; // Address在FLASH中的偏移 uint32_t worldNumber =(( NumToWrite %4 ==0)? (NumToWrite /4) :(NumToWrite /4 + 1)); uint32_t nwrite = worldNumber; en_result_t res; //参数判断 if ((((writeAddr) | 0xFFFFFFFCUL) != 0xFFFFFFFCUL) || writeAddr > (HC32FLASH_END - 4) || NumToWrite == 0 || pBuffer == NULL) return 0; /* 计算偏移地址 */ offset = writeAddr - HC32FLASH_BASE; /* 计算当前扇区位置 */ sectorPos = offset / HC32FLASH_SECTOR_SIZE; /* 计算要写数据的起始地址在当前页内的偏移地址 */ sectorOff = ((offset % HC32FLASH_SECTOR_SIZE) >> 2); /* 计算当前扇区内空余空间 */ sectorFre = ((HC32FLASH_SECTOR_SIZE >> 2) - sectorOff); /* 要写入的数据量低于当前扇区空余量 */ if (nwrite if (*(STMFLASHBuf + sectorOff + i) != 0xFFFFFFFF) /* FLASH擦出后默认内容全为0xFF */ break; } //设置flash单字节操作模式 EFM_SectorCmd_Single( sectorPos, Enable); //擦除 if (i break; } /* 复制到缓存 */ for (index = 0; index break; } } else { /* 直接写不需要擦除 */ res = FlashWriteBuff(writeAddr, sectorFre, pBuffer); } EFM_SectorCmd_Single( sectorPos, Disable); pBuffer += sectorFre; /* 读取地址递增 */ writeAddr += (sectorFre > 2) ? (HC32FLASH_SECTOR_SIZE >> 2) : nwrite; } /* 加锁所有扇区 */ Lock_Flash(); return ((NumToWrite - nwrite) *(uint32_t *)d = *(uint32_t *)s; d += sizeof(uint32_t); s += sizeof(uint32_t); nread -= sizeof(uint32_t); } while ((nread != 0) && (((uint32_t)s)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有