void Flash_Erase(void)
{
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.Banks=FLASH_BANK_2;
EraseInitStruct.Sector=7;
EraseInitStruct.NbSectors= 1;
EraseInitStruct.VoltageRange=FLASH_VOLTAGE_RANGE_3;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
{
HAL_FLASH_Lock();
printf(" Error...1\r\n");
Error_Handler();
}
}
void Flash_Write(u32 Flash_data)
{
HAL_FLASH_Unlock(); //解锁
Flash_Erase( ); //先擦除
//再写入
// printf(" 擦除完成,准备写入......\r\n");
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, Flash_Add, Flash_data) != HAL_OK)
{
printf(" Error...2\r\n");
Error_Handler( );
}
HAL_FLASH_Lock(); //上锁
}
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
{
HAL_StatusTypeDef status;
__IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress;
__IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
uint32_t bank;
uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
/* Check the parameters */
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
/* Process Locked */
__HAL_LOCK(&pFlash);
#if defined (FLASH_OPTCR_PG_OTP)
if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
#else
if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
#endif /* FLASH_OPTCR_PG_OTP */
{
bank = FLASH_BANK_1;
}
#if defined (DUAL_BANK)
else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
{
bank = FLASH_BANK_2;
}
#endif /* DUAL_BANK */
else
{
return HAL_ERROR;
}
/* Reset error code */
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
if(status == HAL_OK)
{
#if defined (DUAL_BANK)
if(bank == FLASH_BANK_1)
{
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* Set OTP_PG bit */
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
/* Set PG bit */
SET_BIT(FLASH->CR1, FLASH_CR_PG);
}
}
else
{
/* Set PG bit */
SET_BIT(FLASH->CR2, FLASH_CR_PG);
}
#else /* Single Bank */
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* Set OTP_PG bit */
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
/* Set PG bit */
SET_BIT(FLASH->CR1, FLASH_CR_PG);
}
#endif /* DUAL_BANK */
__ISB();
__DSB();
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* Program an OTP word (16 bits) */
*(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
/* Program the flash word */
do
{
*dest_addr = *src_addr;
dest_addr++;
src_addr++;
row_index--;
} while (row_index != 0U);
}
__ISB();
__DSB();
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
#if defined (DUAL_BANK)
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* If the program operation is completed, disable the OTP_PG */
CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
if(bank == FLASH_BANK_1)
{
/* If the program operation is completed, disable the PG */
CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
}
else
{
/* If the program operation is completed, disable the PG */
CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
}
}
#else /* Single Bank */
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* If the program operation is completed, disable the OTP_PG */
CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
/* If the program operation is completed, disable the PG */
CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
}
#endif /* DUAL_BANK */
}
/* Process Unlocked */
__HAL_UNLOCK(&pFlash);
return status;
}
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
很明显第三参数是要写入的数据的地址,而不是要写入的数据,所以要用
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, Flash_Add, &Flash_data) != HAL_OK)
但是我看我这里的HAL库,已经是直接写数据的了,可能版本不同
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
{
HAL_StatusTypeDef status = HAL_ERROR;
/* Process Locked */
__HAL_LOCK(&pFlash);
/* Check the parameters */
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
if(status == HAL_OK)
{
if(TypeProgram == FLASH_TYPEPROGRAM_BYTE)
{
/*Program byte (8-bit) at a specified address.*/
FLASH_Program_Byte(Address, (uint8_t) Data);
}
else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
{
/*Program halfword (16-bit) at a specified address.*/
FLASH_Program_HalfWord(Address, (uint16_t) Data);
}
else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
{
/*Program word (32-bit) at a specified address.*/
FLASH_Program_Word(Address, (uint32_t) Data);
}
else
{
/*Program double word (64-bit) at a specified address.*/
FLASH_Program_DoubleWord(Address, Data);
}
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
/* If the program operation is completed, disable the PG Bit */
FLASH->CR &= (~FLASH_CR_PG);
}
/* Process Unlocked */
__HAL_UNLOCK(&pFlash);
return status;
}
static void FLASH_Program_Byte(uint32_t Address, uint8_t Data)
{
/* Check the parameters */
assert_param(IS_FLASH_ADDRESS(Address));
/* If the previous operation is completed, proceed to program the new data */
CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
FLASH->CR |= FLASH_PSIZE_BYTE;
FLASH->CR |= FLASH_CR_PG;
*(__IO uint8_t*)Address = Data;
}