#include "FLASH.h" #include "calib_piecewise_linear.h" #include "usart.h" #include "cmsis_os.h" #include "stdio.h" #include // 包含 strlen 的头文件 /*************下面所有的数都必须是4字节对齐的******************/ /*************************************************************** * 函数名称: Flash_GetBank * 说 明: 获得传入地址所在Bank * 参 数: faddr,Flash地址 * 返 回 值: Bank值 ***************************************************************/ uint32_t Flash_GetBank(uint32_t faddr) { if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_MEM_MODE_Pos) == 0) { if (faddr < (FLASH_BASE + FLASH_BANK_SIZE)) return FLASH_BANK_1; else return FLASH_BANK_1; } else { if (faddr < (FLASH_BASE + FLASH_BANK_SIZE)) // bank swap return FLASH_BANK_1; else return FLASH_BANK_1; } } /*************************************************************** * 函数名称: Flash_GetPage * 说 明: 获得传入地址所在Page * 参 数: faddr,Flash地址 * 返 回 值: Bank值 双Bank STM32L431CCT6只有一个Bank ***************************************************************/ //uint32_t Flash_GetPage(uint32_t faddr) // 双Bank //{ // if (faddr < (FLASH_BASE + FLASH_BANK_SIZE)) // return (faddr - FLASH_BASE) / FLASH_PAGE_SIZE; // else // return (faddr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE; //} uint32_t Flash_GetPage(uint32_t faddr) // 单Bank { return (faddr - FLASH_BASE) / FLASH_PAGE_SIZE; } /*************************************************************** * 函数名称: Flash_ReadOneWord * 说 明: 从指定地址中读取一个32位的数据 * 参 数: faddr,Flash地址 * 返 回 值: Flash地址内的一个32位的数据 ***************************************************************/ uint32_t Flash_ReadOneWord(uint32_t faddr) { return *(__IO uint32_t *)faddr; } /*************************************************************** * 函数名称: Flash_ErasePages * 说 明: 擦除页 * 参 数: faddr,起始地址 * fdataNum,要擦除的字节数,实际上也是整页擦除 * 返 回 值: 无 ***************************************************************/ void Flash_ErasePages(uint32_t faddr,uint32_t fdataNum) { // 连续擦除多个页(按字数计算) if(fdataNum == 0||faddr>FLASH_ADDR_MAX) { return; } uint32_t PageError = 0; HAL_FLASH_Unlock(); FLASH_EraseInitTypeDef FLASH_EraseInitSturcture; __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); FLASH_EraseInitSturcture.TypeErase = FLASH_TYPEERASE_PAGES; FLASH_EraseInitSturcture.Banks = Flash_GetBank(faddr); FLASH_EraseInitSturcture.Page = Flash_GetPage(faddr); FLASH_EraseInitSturcture.NbPages = Flash_GetPage(faddr + 4 * fdataNum - 1) - FLASH_EraseInitSturcture.Page + 1; if(HAL_FLASHEx_Erase(&FLASH_EraseInitSturcture,&PageError) != HAL_OK) { HAL_FLASH_Lock(); return; } } /*************************************************************** * 函数名称: Flash_WriteOneWord * 说 明: 向指定地址中写入一个32位的数据 * 参 数: faddr,Flash地址 * fdata32,Flash地址内的一个32位的数据 * 返 回 值: 写FLASH返回的状态 ***************************************************************/ uint8_t Flash_WriteOneWord(uint32_t faddr,uint32_t fdata32) { if(faddrFLASH_ADDR_MAX) //地址小于STM32L431RC的flash地址最大值 return; for(i=0;iFLASH_ADDR_MAX) //地址小于STM32L431的flash地址最大值 return; for(i=0;i FLASH_ADDR_MAX || (faddr % 4 != 0)) { // 检查地址对齐 return; } uint32_t *pSrc = (uint32_t *)faddr; uint32_t *pDest = (uint32_t *)fdata8; uint32_t wordNum = (fdata8Num + 3) / 4; // 转换为32位字数 for (uint32_t i = 0; i < wordNum; i++) { pDest[i] = pSrc[i]; // 按32位读取,避免字节访问异常 } } /*************************************************************** * 函数名称: Flash_WriteRead * 说 明: Flash数据写入、读取测试 * 参 数: fAdress,flash地址 * *wData,向flash地址里写入的数据 * wDataLen,写入数据的长度 * *rData,从flash地址里读出的数据 * 返 回 值: ERROR,失败 * SUCCESS,成功 ***************************************************************/ uint8_t Flash_WriteRead(uint32_t fAdress, uint8_t *wData, uint32_t wDataLen, uint8_t *rData) { char str_adc_vol[200]; char str_read_vol[200]; if (wData == NULL) { return ERROR; } uint16_t strWriteLen = (wDataLen % 4) == 0 ? (wDataLen / 4) : (wDataLen / 4 + 1); // 将 wData 转换为十六进制字符串 str_adc_vol[0] = '\0'; for (uint32_t i = 0; i < wDataLen; i++) { sprintf(str_adc_vol + strlen(str_adc_vol), "%02X ", wData[i]); } // DEBUG_PRINTF("Flash_Write32: %s\r\n", str_adc_vol); Flash_ErasePages(fAdress, 1); // 擦除flash Flash_Write32(fAdress, (uint32_t *)wData, strWriteLen); // 写入数据 Flash_ReadBytes(fAdress,rData, wDataLen); // 读出数据 // 将 rData 转换为十六进制字符串 str_read_vol[0] = '\0'; for (uint32_t i = 0; i < wDataLen; i++) { sprintf(str_read_vol + strlen(str_read_vol), "%02X ", rData[i]); } // DEBUG_PRINTF("Flash_ReadBytes: %s\r\n", str_read_vol); return SUCCESS; } /****************************************************************************************/ /* 分段线性插值 */ //void Save_CalibPoints_ToFlash(void) //{ // Flash_ErasePages(CALIB_PARAM_ADDR, sizeof(CalibPoints_t)); // Flash_Write32(CALIB_PARAM_ADDR, (uint32_t *)&g_calibPoints, sizeof(CalibPoints_t) / sizeof(uint32_t)); //} //void Load_CalibPoints_FromFlash(void) //{ // CalibPoints_t CalibPoints_flashparams; // Flash_ReadBytesto32(CALIB_PARAM_ADDR, (uint8_t *)&CalibPoints_flashparams, sizeof(CalibPoints_t)); // if (CalibPoints_flashparams.magic == CALIB_MAGIC) { // memcpy(g_calibPoints.cap_values, CalibPoints_flashparams.cap_values, sizeof(CalibPoints_flashparams.cap_values)); // } else { // Load_Default_CalibPoints(); // Save_CalibPoints_ToFlash(); // } // print_calibPoints_params(); //} void Save_Calib_residualheight_ToFlash(void) { // 余油标定值 } void Save_Calib_rodvol_ToFlash(void) { // 阀杆标定值 } /**********************END OF FILE**********************/