#include "../main/SystemInclude.h" //擦除一页扇区(只操作需要操作的扇区)如果仅擦除1个页面,则Endpage与Startpage相同。 void FLASH_Erase_Data_Page(u8 UserPage) { u32 flashAddr = FLASH_PAGE_29; switch(UserPage) { case USER_DCOEF_TAG_PAGE:flashAddr= USER_DCOEF_TAG_ADDR; break; case USER_PARAMS_PAGE :flashAddr= USER_PARAMS_ADDR ; break; case VENDER_PARAMS_PAGE :flashAddr= VENDER_PARAMS_ADDR ; break; default : return; } if(LHL_FLASH_Erase(flashAddr, flashAddr, LHL_LNG_TIMEOUT) != LHL_OK) { while(1); } } //按整页写入 void FLASH_Write_Data_Page(u8 UserPage, void *pBuffer, u32 byteSize) { //1 地址映射 uint32_t flashAddr = 0; switch(UserPage) { case USER_DCOEF_TAG_PAGE: flashAddr = USER_DCOEF_TAG_ADDR ; break; case USER_PARAMS_PAGE : flashAddr = USER_PARAMS_ADDR ; break; case VENDER_PARAMS_PAGE : flashAddr = VENDER_PARAMS_ADDR ; break; default : return; } //2 向上对齐到 4 字节 u32 wordCount = (byteSize + 3U)/4U; // 等价于 ((byteSize + 3) & ~3) / 4 //3 限制不超过一页(word 数) if (wordCount > FLASH_PAGE_SIZE/4U) wordCount = FLASH_PAGE_SIZE/4U; //4 写入 if(LHL_FLASH_Program(flashAddr ,(u32 *)pBuffer, (u16)wordCount, LHL_LNG_TIMEOUT) != LHL_OK) { while(1); } } //Application ****************************************************************** //API // 定义指向固定地址的指针 volatile u8 * const USER_PARAMS = (u8*)USER_PARAMS_ADDR; volatile u8 * const VENDER_PARAMS = (u8*)VENDER_PARAMS_ADDR; volatile u8 * const CORRECT_DATA = (u8 *)CORRECT_DATA_ADDR; volatile u8 * const CORRECT2_DATA = (u8 *)CORRECT2_DATA_ADDR; // 通用参数读取函数 void ReadParameterFromFlash( void *value,u16 offset, u8 size ,u8 UserPage ) { if(offset + size <= FLASH_PAGE_BYTE_SIZE) //不超过一页大小 { switch(UserPage) { case USER_PARAMS_PAGE :memcpy(value,(void*)&USER_PARAMS[offset] , size);break; //读用户数据页 case VENDER_PARAMS_PAGE :memcpy(value,(void*)&VENDER_PARAMS[offset], size);break; //读厂家数据页 default : break ; } } } //APP u8 mucSaveParams; //Flash状态标志 u8 munWriteParams;//Flash写寄存器参数标志 #define ParamsBufSize FLASH_PAGE_BYTE_SIZE/4u //4K大小(缓冲区不够了用的1K) u8 unParamsBuf[ParamsBufSize]; //用于按byte存储flash页中间缓冲 /* 保存系统参数(整合到一起批量传入) */ void SaveSysParams(void) { if(munWriteParams == WP_NOT) return;//不写寄存器 //0- 是否恢复默认值 if(munWriteParams == WP_DEF)//寄存器恢复默认值 { mucSaveParams = PARAMS_ING;//写入中 memcpy(unParamsBuf, (void*)VENDER_PARAMS, ParamsBufSize);//从Flash出厂数据页装填unParamsBuf FLASH_Erase_Data_Page(USER_PARAMS_PAGE);//擦除用户数据页 FLASH_Write_Data_Page(USER_PARAMS_PAGE, unParamsBuf, ParamsBufSize);//将unParamsBuf写入用户数据页 munWriteParams = WP_NOT; //恢复无写入状态 mucSaveParams = PARAMS_COMPL;//Flash写入完成 } //1- 准备需要写入的FLASH数据 //1-1 从Flash更新一下历史参数 memcpy(unParamsBuf, (void*)USER_PARAMS, ParamsBufSize); //1-2 为unParamsBuf传入可修改部分的新值 memcpy((void *)&unParamsBuf[OFFSET_AIR], &offsetAir, OFFSET_AIR_WIDTH); memcpy((void *)&unParamsBuf[OFFSET_GAS], &offsetGas, OFFSET_GAS_WIDTH); memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*1],&meterSN1,SENSOR_SN_WIDTH); memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*2],&meterSN2,SENSOR_SN_WIDTH); memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*3],&meterSN3,SENSOR_SN_WIDTH); memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*4],&meterSN4,SENSOR_SN_WIDTH); memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*5],&meterSN5,SENSOR_SN_WIDTH); memcpy((void *)&unParamsBuf[SERIES_BASE+SENSOR_SN_WIDTH*6],&meterSN6,SENSOR_SN_WIDTH); //...... //2- 开始写入Flash //写厂家及用户区 if(munWriteParams == WP_VENDER) { FLASH_Erase_Data_Page(USER_PARAMS_PAGE);//擦除指定页 FLASH_Write_Data_Page(USER_PARAMS_PAGE,unParamsBuf, ParamsBufSize);//按页写入 FLASH_Erase_Data_Page(VENDER_PARAMS_PAGE);//擦除指定页 FLASH_Write_Data_Page(VENDER_PARAMS_PAGE,unParamsBuf, ParamsBufSize);//按页写入 } //写用户区 else if(munWriteParams == WP_USER) { FLASH_Erase_Data_Page(USER_PARAMS_PAGE);//擦除指定页 FLASH_Write_Data_Page(USER_PARAMS_PAGE,unParamsBuf, ParamsBufSize);//按页写入 } //写二次修正区 else if(munWriteParams == WP_DCOEF_TAG) { } munWriteParams = WP_NOT;//恢复无写入状态 mucSaveParams = PARAMS_COMPL;//Flash写入完成 } /******************************************************************************/ /* 写校准到指定页的FLASH数据,每次传输一帧内的数量 */ void FLASH_Write_Calib_Data_ToFlash(u16 FrameN, u8 *pBuffer ) { u32 ADDR; ADDR = FrameN * CALIB_WIDTH + CORRECT_DATA_ADDR; if((ADDR&0x0FFF) == 0x000)LHL_FLASH_Erase(ADDR,ADDR,LHL_LNG_TIMEOUT);//ADDR跨页即ADDR为页首地址 if(ADDR >(CORRECT_DATA_ADDR+CALIB_REAL_SIZE)) MBBuf.BusError = SLAVE_DEVICE_FAILURE; LHL_FLASH_Program(ADDR,(u32 *)pBuffer,CALIB_WIDTH/4u ,LHL_LNG_TIMEOUT); } /* 写校准到指定页的FLASH数据,每次传输一帧内的数量*/ void FLASH_Write_Calib2_Data_ToFlash(u16 FrameN, u8 *pBuffer ) { u32 ADDR; ADDR = FrameN * CALIB_WIDTH + CORRECT2_DATA_ADDR; if((ADDR&0x0FFF) == 0x000)LHL_FLASH_Erase(ADDR,ADDR,LHL_LNG_TIMEOUT);//ADDR跨页即ADDR为页首地址 if(ADDR >(CORRECT2_DATA_ADDR+CALIB_REAL_SIZE))MBBuf.BusError = SLAVE_DEVICE_FAILURE; LHL_FLASH_Program(ADDR,(u32*)pBuffer ,CALIB_WIDTH/4u ,LHL_LNG_TIMEOUT ); } /******************************************************************************/ /* 按页读校准区域数据*/ void ReadCalibDataFromFlash(u32 frameN , u8 *data ,u16 size ) { memcpy(data,(void*)&CORRECT_DATA[frameN*size], size); } void ReadCalib2DataFromFlash(u32 frameN , u8 *data ,u16 size ) { memcpy(data,(void*)&CORRECT2_DATA[frameN*size], size); } /******************************************************************************/ /* 按索引读取校准区域数据*/ void ReadDataFromFlash(u32 offset , u8 *data ,u16 size ) { memcpy(data,(void*)&CORRECT_DATA[offset], size); // if(offsetAir)memcpy(data,(void*)&CORRECT_DATA[offset], size); // else memcpy(data,(void*)&CORRECT2_DATA[offset], size); }