#include "FLASH.h" #include "usart.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值 ***************************************************************/ uint32_t Flash_GetPage(uint32_t faddr) { 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; } /*************************************************************** * 函数名称: 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) //地址小于STM32L431RC的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]); } // 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]); } // printf("Flash_ReadBytes: %s\r\n", str_read_vol); return SUCCESS; } void load_params_from_flash(void) { DeviceParams_t flashParams; Flash_ReadBytes(FLASH_PARAM_ADDR, (uint8_t *)&flashParams, sizeof(DeviceParams_t)); if (flashParams.magic == FLASH_PARAMS_MAGIC) { g_deviceParams = flashParams; } else { // 使用默认值并保存 g_deviceParams = (DeviceParams_t){ .Firmware_Version = 0x0007B94F, .SlaveDevice_addr = 0x00FF, .Serial_baud_rate = 0x0002, .Device_SN = {0x00FF, 0x1906, 0x0A01}, .magic = FLASH_PARAMS_MAGIC }; save_params_to_flash(); } } void save_params_to_flash(void) { Flash_ErasePages(FLASH_PARAM_ADDR, 1); // Flash_Write32(FLASH_PARAM_ADDR, (uint32_t *)&g_deviceParams, sizeof(DeviceParams_t) / 4 + 1); // 计算完整的32位字数(包括填充) uint32_t wordSize = (sizeof(DeviceParams_t) + 3) / 4; Flash_Write32(FLASH_PARAM_ADDR, (uint32_t *)&g_deviceParams, wordSize); } void SaveBootloaderParams(void) { Flash_ErasePages(PARAM_ADDR, sizeof(BootParams) / FLASH_PAGE_SIZE + 1); Flash_Write64(PARAM_ADDR, (uint64_t*)¶ms, sizeof(BootParams) / 8); } /**********************END OF FILE**********************/