#include "main.h" #include "soft_flash.h" #include #include "soft_crc.h" #include "stm32f4xx_hal_flash_ex.h" extern UART_HandleTypeDef huart2; uint32_t sectStartAddr[12]= { 0x08000000,//0 0x08004000,//1 0x08008000,//2 0x0800c000,//3 0x08010000,//4 0x08020000,//5 0x08040000,//6 0x08060000, //7 0x08080000, //8 0x080A0000, //9 0x080C0000, //10 0x080E0000, //11 }; int GetSectorFromAddress(uint32_t address) { int sect = 0; if( address < 0x08000000 || address > 0x08100000 ) return -1; for( int i=0; i<8; i++ ) { if( address >= sectStartAddr[i] && address < sectStartAddr[i+1] ) { sect = i; break; } } return sect; } //FLASH写 uint32_t Flash_WriteData(uint32_t addr, uint16_t *data, uint16_t Size) { static int8_t cur_sector = -1; uint8_t tar_sector = 0; __disable_irq(); HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);//清除一些错误标志 //是否要擦扇区 tar_sector = GetSectorFromAddress(addr);//获取地址所在的扇区 if(tar_sector != cur_sector) { FLASH_Erase_Sector(tar_sector,FLASH_VOLTAGE_RANGE_3);//擦除指定的闪存扇区(0~11) cur_sector = tar_sector; } uint16_t TempBuf = 0; for (uint16_t i = 0; i < Size; i++) { TempBuf = *(data + i); HAL_StatusTypeDef a = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr + i * 2, TempBuf); if (a != HAL_OK) { HAL_FLASH_Lock(); __enable_irq(); return WRITE_FAIL; } } HAL_FLASH_Lock(); __enable_irq(); return WRITE_SUCCESS; } bool wirte_update_flag() { uint8_t sect = 0; HAL_StatusTypeDef status; __disable_irq(); HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);//清除一些错误标志 sect = GetSectorFromAddress(FLASH_UPDATE_ADDR);//获取地址所在的扇区 FLASH_Erase_Sector(sect,FLASH_VOLTAGE_RANGE_3);//擦除指定的闪存扇区(0~11) status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FLASH_UPDATE_ADDR, 0XF); HAL_FLASH_Lock(); __enable_irq(); if(status == HAL_OK) return true; else return false; } //FLASH读地址 uint16_t ReadFlashNBtye(uint32_t ReadAddress, uint16_t *ReadBuf, int32_t ReadNum) { int DataNum = 0; uint16_t up_flag = 0; *ReadBuf = *(__IO uint16_t *)ReadAddress; up_flag = *ReadBuf; DataNum++; return up_flag; } //读取标志位 uint32_t flash_read_updata_flag(void) { uint16_t temp_buff = 0; uint32_t Address = 0; temp_buff = ReadFlashNBtye(FLASH_UPDATE_ADDR, (uint16_t *)&Address, 1); return temp_buff; }