FLASH的基本原理与读写操作笔记

 一、概念:

每个文件对应多个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;
}

​

 

 

  • 20
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
串行 Flash 存储器通常采用 SPI(Serial Peripheral Interface)或 I2C(Inter-Integrated Circuit)等串行通信协议与 MCU 进行通信。这里以 SPI 为例,简要介绍 SPI 读写串行 Flash 的原理: 1. 写入数据到 Flash 在写入数据到 Flash 之前,需要先发送写入使能命令(Write Enable,WREN),以激活写入状态。然后,将数据和指令按照 SPI 协议依次发送到 Flash 内部,写入数据的地址也会随着指令一起发送。Flash 内部会将数据写入到指定地址,写入完成后会自动返回读取状态。 2. 读取数据从 Flash 读取数据时,需要先发送读取命令(Read),并且指定要读取的数据地址。Flash 内部会将数据读取到内部缓存区中,并通过 SPI 接口传输给 MCU。如果需要连续读取多个数据,可以发送读取连续数据命令(Read Continuously),Flash 在连续发送数据时不需要再次发送地址。 3. 擦除 Flash 数据 Flash 存储数据时需要先擦除原有数据。擦除操作通常需要使用擦除命令(Erase),并且要指定擦除的起始地址和擦除的范围。和写入数据时一样,也需要发送擦除使能命令(Erase Enable,EREN)。 4. 更新 Flash 数据 更新 Flash 数据时,需要先读取原有数据,然后修改数据后再写入。这个过程需要谨慎处理,确保数据的完整性和正确性。 总的来说,SPI 读写串行 Flash 的原理是通过 SPI 协议传输数据和指令完成的,需要注意的是,Flash读写速度较慢,且擦除操作会导致整块存储器的数据丢失,所以需要谨慎处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值