【CS32L015C8T6】内部FLASH读写方法(内附完整代码及注释)
本文介绍了芯海CS32L015C8T6单片机内部FLASH操作方法。该芯片具有64KB FLASH(128个512B扇区)和8KB SRAM,文章详细讲解了FLASH地址定义差异,并提供了基于HAL库的读写函数代码:写入函数包含解锁、擦除(以扇区为单位)、编程(双字写入)和上锁流程;读取函数采用memcpy实现数据复制。文末附有完整代码注释,并提示需要官方支持库可联系作者或芯海官方。
目录
三、如果这篇文章能帮助到你,请点个赞鼓励一下吧ξ( ✿>◡❛)~
前言:
长颈鹿最近在使用芯海的CS32L015C8T6单片机进行工程开发,发现网上有关这款单片机的资料非常少,而且官方提供的驱动代码有些不适用,因此决定记录一下造轮子的过程,前车之鉴,后车之师,希望能够帮助后来的开发者减少一些重复性造轮子的工作,少走一些弯路。
本文介绍了芯海的CS32L015C8T6单片机的内部FLASH擦除、写入、读取数据的操作方法,例程中的代码函数都是基于芯海CS32L015芯片对应的HAL库开发,需要对应官方支持库的话可以私信我提供或者联系芯海官方支持
一、CS32L015C8T6存储空间介绍:
这款单片机主打性价比,有64KB的内部FLASH存储空间,8KB的SRAM存储空间,需要注意的是,CS32L015C8T6单片机的单个扇区只有512B,也就是0.5KB大小,每次擦除也是以扇区为单位,64KB大小的FLASH共有128个扇区。与FLASH相关的地址在库中有两处定义:
#define FLASH_BASE 0x40020400UL
#define EFLASH_MEM_BASE 0x00000000UL
第一个FLASH_BASE地址指的是FLASH控制寄存器对应的起始地址
第二个EFLASH_MEM_BASE地址对应的才是存储代码和数据的FLASH地址,如果需要计算扇区页码的话,使用第二个FLASH地址作为起始地址。
二、内部FLASH操作函数代码及注释:
1、写入&擦除操作
/*****************************************************************************
[函数名称]u32WriteData
[函数功能]写入数据
[参 数] pu8Address [in] 开始地址
pvBuff [in] 缓冲区地址
u32Length [in] 写入长度
[返 回 值]写入的字节数
[备 注]注意: CS32L015 擦除每节 是 512 个字节,STM32擦除是2K
*****************************************************************************/
uint32 u32WriteData(const uint8 *pu8Address, const void *pvBuff, const uint32 u32Length)
{
uint32 u32Address = (uint32)pu8Address;
uint64 *pu64Buffer = (uint64*)pvBuff; //先把地址传入,转换为64指针
static FLASH_EraseInitTypeDef EraseInitStruct = {0};
uint32_t PageError = 0;
//根据传入的地址选择内部FLASH页进行擦除,CS32的起始地址为0x0
uint32_t FirstPage = u32Address;
do{
HAL_FLASH_OPERATION_Unlock(FLASH_ALLPAGE_SELECTED); //FLASH解锁
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; //FLASH选择扇区擦除
EraseInitStruct.PageAddress = FirstPage;
EraseInitStruct.NbPages = 1;
if (HAL_FLASH_Erase(&EraseInitStruct, &PageError) != HAL_OK)
{
// 擦除出错,则返回
}
uint16 i = 0;
for(i=0; i<u32Length/8; i++) //根据Length写入数据
{
// 双字编程
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, u32Address, pu64Buffer[i]) == HAL_OK)
{
u32Address += 8; //地址增加8
}
else
{
Error_Handler();
}
}
HAL_FLASH_OPERATION_Lock(FLASH_ALLPAGE_SELECTED); //上锁
if(i >= u32Length/2)
break;
}while(TRUE);
return u32Length;
}
2、读取操作
/*****************************************************************************
[函数名称]u32ReadData
[函数功能]读取数据
[参 数]pu8Address [in] 开始地址
pvBuff [out] 缓冲区地址
u32Length [in] 写入长度
[返 回 值]实际读出的字节数
[备 注]
*****************************************************************************/
uint32 u32ReadData(const uint8 *pu8Address, void *pvBuff, const uint32 u32Length)
{
do{
int i = 0;
memcpy(pvBuff, pu8Address, u32Length); //将内部FLASH中存储的数据复制到数组
//比较内容是否相同
for(i = 0;i < u32Length;i++)
{
uint8 *pu8AddrFlash = (uint8*)(pu8Address + i);
uint8 *pu8AddrData = (uint8*)((uint8*)pvBuff + i);
if((*pu8AddrFlash) != (*pu8AddrData))
{
break;
}
}
if(i >= u32Length)
{
break;
}
}while(TRUE);
return u32Length;
}
三、如果这篇文章能帮助到你,请点个赞鼓励一下吧ξ( ✿>◡❛)~
更多推荐



所有评论(0)