文章目录
前言
准备
上一篇
一、函数
1、单字节写
/*!
\brief FLASH写
@Address 操作地址
@pData 数据指针
@Size 数据长度
*/
uint8_t FMC_FLASH_Write( uint32_t Address, uint8_t *pData, uint16_t Size )
{
fmc_state_enum FLASHStatus;
uint16_t i;
uint32_t AddressTemp = 0;
/*写入数据*/
AddressTemp = Address;
/* 解锁 */
fmc_unlock();
/* 操作FMC前先清空STAT 状态寄存器,非常必要*/
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
for (i=0; i<Size; i++)
{
FLASHStatus = fmc_byte_program(AddressTemp, pData[i]);
if (*((volatile uint8_t*)AddressTemp) != pData[i])
{
return 1; //校验错误
}
if (FLASHStatus != FMC_READY)
{
return 1; //写错误
}
AddressTemp += 1;//地址累加
}
/* 上锁 */
fmc_lock();
return 0;
}
2、字节读
/*!
\brief FLASH读
@Address 操作地址
@pData 数据指针
@Size 数据长度
*/
uint8_t FMC_FLASH_Read( uint32_t Address, uint8_t *pData, uint16_t Size )
{
uint32_t rdAddr = Address;
for( uint16_t dataIndex = 0; dataIndex < Size; dataIndex++ )
{
pData[dataIndex] = *( __IO uint8_t* ) rdAddr;
rdAddr += 1;//地址累加
}
return 0;
}
3、页擦除
/*!
\brief FLASH页擦除
@PageAddress 操作页起始地址
@PageNum 擦除页数
*/
uint8_t FMC_FLASH_ErasePage( uint32_t PageAddress, uint8_t PageNum )
{
uint8_t i;
uint32_t erase_addr = PageAddress & (~(PAGE_SIZE-1));//保证地址4K对齐
/* 解锁 */
fmc_unlock();
/* 操作FMC前先清空STAT 状态寄存器,非常必要*/
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
for (i=0; i < PageNum; i++)
{
if (fmc_page_erase(erase_addr) != FMC_READY)
{
return 1;
}
erase_addr += PAGE_SIZE;
}
/* 上锁 */
fmc_lock();
return 0;
}
其中 页大小为4K,#define PAGE_SIZE (4096U)
二、实验例程
1、把第四扇区的第一和第二页作为存储测试
地址定义
#define PAGESIZE 4096U
#define PAGE1_START_ADDR 0x08010000 //扇区4的起始地址,第一页 地址
#define PAGE2_START_ADDR (PAGE1_START_ADDR+PAGESIZE )// 第二页 地址
2、测试程序
3、测试步骤和结果
进入仿真,打上如上图断点,查看这两个页地址数据
a、第一个断点时,查看第一页地址看是否写入成功
b、第二个断点时,查看第二页地址看是否写入成功
c、第三个断点时,查看第一页地址看是否读数据成功
d、第四个断点时,查看第一页是否页擦除成功
e、第五个断点,查看第二页是否页擦除成功