一、概念:
每个文件对应多个block,每个block对对应多个扇区sector,每个sector对应有多个页。
一般一个扇区(sector)多个页(page) , 一个块 (bank)又有多个扇区 (sector)
块(bank) > 扇区(sector) > 页(page)
二、FLASH读写操作
/*******************************************************************************
写入数据流程:
1.写入数据到内部flash
2.FLASH 解锁
3.擦除扇区
4.写数据到指定的地址空间
5.上锁写保护
6. 写数据成功
W25Q128 将 16M 的容量分为 256 个块(Block),每个块大小为 64K 字节,每个块又分为
16 个扇区(Sector),每个扇区 4K 个字节。 W25Q128 的最小擦除单位为一个扇区,也就是每次
必须擦除 4K 个字节。这样我们需要给 W25Q128 开辟一个至少 4K 的缓存区,这样对 SRAM 要
求比较高,要求芯片必须有 4K 以上 SRAM 才能很好的操作
*******************************************************************************/
/********************define the size of sector*******************************/
u8 SPI_FLASH_BUF[4096];
/*******************************************************************************
* Function Name : SPI_FLASH_WRITE(u8 * pBuffer,u32 WriteAddr,u16 NumbyteToWrite)
* Description : 在指定的地址进行写入数据
* @param1 : 写指针
* @param2 : 开始写入的地址(24bit)
* @param3 : 要写入的字节数
* Return : void
*******************************************************************************/
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u32 secpos;
u16 secoff;
u16 secremain;
u16 i;
secpos=WriteAddr/4096;//扇区地址 0~511 for w25x16
secoff=WriteAddr%4096;//在扇区内的偏移
secremain=4096-secoff;//扇区剩余空间大小
if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节
while(1)
{
SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容
for(i=0;i<secremain;i++)//校验数据
{
if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//需要擦除
}
if(i<secremain)//需要擦除
{
SPI_Flash_Erase_Sector(secpos);//擦除这个扇区
for(i=0;i<secremain;i++) //复制
{
SPI_FLASH_BUF[i+secoff]=pBuffer[i];
}
SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区
}else SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间.
if(NumByteToWrite==secremain)break;//写入结束了
else//写入未结束
{
secpos++;//扇区地址增1
secoff=0;//偏移位置为0
pBuffer+=secremain; //指针偏移
WriteAddr+=secremain;//写地址偏移
NumByteToWrite-=secremain; //字节数递减
if(NumByteToWrite>4096)secremain=4096; //下一个扇区还是写不完
else secremain=NumByteToWrite; //下一个扇区可以写完了
}
};
}
//写一个字节
void SPI_Flash_Write_OneByte(u8 DataToWrite,u32 WriteAddr)
{
u8 buff[1] = {0};
buff[0] = DataToWrite;
SPI_Flash_Write(buff,WriteAddr,1);
}
//写四个字节
void SPI_Flash_Write_FourByte(u32 DataToWrite,u32 WriteAddr)
{
u8 temp[4]={0,0,0,0};
temp[0]=(u8)DataToWrite;
temp[1]=(u8)(DataToWrite>>8);
temp[2]=(u8)(DataToWrite>>16);
temp[3]=(u8)(DataToWrite>>24);
SPI_Flash_Write(temp,WriteAddr,4);
}
u32 SPI_FLAsh_ReadFourByte(u32 ReadAddr)
{
u8 temp[4] = {0,0,0,0};
u32 val = 0;
SPI_Flash_Read(temp,ReadAddr,4);
val = (temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|(temp[0]);
return val;
}