flash的擦除非常慢,且此时无法响应中断。需要注意flash在擦除和写入时最好在空闲时间。
flash只能写0,擦除是吧0写1。如果要写的字中,只写0可以修改过去,可以不擦
--------------------.h-------------------------------
#ifndef _FLASH_H_
#define _FLASH_H_
#include "main.h"
#include "stm32f1xx_hal_flash_ex.h"
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
/*
stm32不同flash大小的,每个扇区大小不同
*/
#define STM32_FLASH_SIZE 64 //所选STM32的FLASH容量大小(单位为K)
#if STM32_FLASH_SIZE < 256 //设置扇区大小
#define STM_SECTOR_SIZE 1024 //1K字节
#else
#define STM_SECTOR_SIZE 2048 //2K字节
#endif
#define STM32_FLASH_BASE 0x08000000 //STM32 FLASH的起始地址
#define FLASH_USER_START_ADDR ( STM32_FLASH_BASE + STM_SECTOR_SIZE * 62 ) //写Flash的地址,这里从第62页开始
#define FLASH_USER_END_ADDR ( STM32_FLASH_BASE + STM_SECTOR_SIZE * 64 ) //写Flash的地址,这里以第64页结束
void Flash_Erase(void);
void Flash_Write(u32 *pBuffer,u32 NumToWrite);
void Flash_Read(u32 *pBuffer,u32 NumToRead);
#endif
---------------------------擦除参数结构体-----------------------------
typedef struct
{
uint32_t TypeErase; /*!< TypeErase: Mass erase or page erase.
This parameter can be a value of @ref FLASHEx_Type_Erase
页擦除还是全擦除
*/
uint32_t Banks; /*!< Select banks to erase when Mass erase is enabled.
This parameter must be a value of @ref FLASHEx_Banks
如果有多个flashbank在这里选,这个不清楚
*/
uint32_t PageAddress; /*!< PageAdress: Initial FLASH page address to erase when mass erase is disabled
This parameter must be a number between Min_Data = 0x08000000 and Max_Data = FLASH_BANKx_END
(x = 1 or 2 depending on devices)
擦除起始页的地址
*/
uint32_t NbPages; /*!< NbPages: Number of pagess to be erased.
This parameter must be a value between Min_Data = 1 and Max_Data = (max number of pages - value of initial page)
擦除多少页
*/
} FLASH_EraseInitTypeDef;
/** @defgroup FLASH_Type_Program FLASH Type Program
* @{
*/
#define FLASH_TYPEPROGRAM_HALFWORD 0x01U /*!<Program a half-word (16-bit) at a specified address.*/
#define FLASH_TYPEPROGRAM_WORD 0x02U /*!<Program a word (32-bit) at a specified address.*/
#define FLASH_TYPEPROGRAM_DOUBLEWORD 0x03U /*!<Program a double word (64-bit) at a specified address*/
内部flash的函数都是写好的,直接调用,下面编写成函数
------------------.c--------------------------
#include "Flash.h"
#include <stdio.h>
static FLASH_EraseInitTypeDef EraseInitStruct;//首先定义擦除用的变量
u32 PAGEError = 0;
/**********************************************************************************
* 函数功能: 页擦除
* 输入参数: 无
* 返 回 值: 无
* 说 明:
擦除流程:
1、设置变量参数
2、解锁(因为解锁在其他地方调用了,这里没写)
3、擦除
4、锁定flash(当仅擦除时锁定)一般擦除与写入在一块,在写入以后再锁定
*/
void Flash_Erase(void)
{
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = FLASH_USER_START_ADDR;
EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / STM_SECTOR_SIZE;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
{
HAL_FLASH_Lock();
printf(" Error...1\r\n");
Error_Handler( );
}
}
/**********************************************************************************
* 函数功能: 数据写入
* 输入参数: 写入数据缓存数组指针、写入数据数
* 返 回 值: 无
* 说 明:无
写入流程:
1、解锁
2、擦除
3、写入HAL_FLASH_Program(按16/32/64位写入;写入地址;写入值)
4、上锁
*/
void Flash_Write(u32 *pBuffer,u32 NumToWrite)
{
u16 i=0;
u32 Address = FLASH_USER_START_ADDR;
HAL_FLASH_Unlock(); //解锁
Flash_Erase( ); //先擦除
//再写入
printf(" 擦除完成,准备写入......\r\n");
while ( (Address < FLASH_USER_END_ADDR) && (i<NumToWrite) )
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, pBuffer[i]) == HAL_OK)
{
Address = Address + 4; //地址后移4个字节
i++;
}
else
{
printf(" Error...2\r\n");
Error_Handler( );
}
}
HAL_FLASH_Lock(); //上锁
}
/**********************************************************************************
* 函数功能: 数据读取
* 输入参数: 读取数据缓存数组指针、读出数据数
* 返 回 值: 无
* 说 明:无
读取:直接取对应位置地址的值
*/
void Flash_Read(u32 *pBuffer,u32 NumToRead)
{
u16 i=0;
u32 Address = FLASH_USER_START_ADDR;
while ( (Address < FLASH_USER_END_ADDR) && (i<NumToRead) )
{
pBuffer[i++]= *(__IO u32 *)Address;
Address = Address + 4; //地址后移4个字节
}
}