STM学习笔记------W25Qxx

当初学习这个时觉得挺简单的,不用做什么笔记,可是过了也才两个星期之后,再回过头来用到的时候,竟然全部忘完了。。。所有又来记录一下笔记。

W25QXX 由每页 256 字节组成。 容量为 (XX/8)M 字节。每页的 256 字节用一次页编程指令即可完成。 每次可以擦除 16 页(1 个扇区,最小擦除单位)、 128 页(32KB 块)、 256 页(64KB 块)和全片擦除。存储数据地址为24位,

W25Qxx写入数据时:必须先写使能,才能写入数据,写入数据包括存储的数据和擦除扇区数据(写入寄存器指令时不算,也就是选中片选时,可直接写入,和写入要操作的储存器地址)。而写入数据每次页写指令后最多写如256个字节,写满整页。因为超出之后就会从该页头又写一遍,会覆盖已经写入的数据。
读写数据时:都要确认状态寄存器1最低位处于‘0’,也就是工作状态、可读可写状态。
读数据时: 地址会自动增加, 允许连续的读取数据。这意味着读取整个内存的数据,只要用一个指令就可以读完。

W25Qxx地址含义:
高性能模式0xA3,W25Q128貌似没有该模式。

#define W25X_WriteEnable 0x06 //写使能,常用
#define W25X_WriteDisable 0x04 //写失能
#define W25X_ReadStatusReg 0x05 //读取W25QXX的状态寄存器1指令,(常用),0x35-SR2;0x15-SR3
#define W25X_WriteStatusReg 0x01 //写状态寄存器1,0x31-SR2;0x11-SR3
#define W25X_ReadData 0x03 //读数据(常用)
#define W25X_FastReadData 0x0B //快速读数据
#define W25X_PageProgram 0x02//页写指令 (常用)
#define W25X_BlockErase 0xD8 //64k擦除指令
#define W25X_SectorErase 0x20 //扇区擦除(常用)
#define W25X_ChipErase 0xC7 //或0x60,全片擦除
#define W25X_PowerDown 0xB9 //低功耗指令

#define W25X_ReleasePowerDown 0xAB //解除低功耗或高性能模式
#define W25X_DeviceID 0xAB //芯片ID,和上面一样
#define W25X_ManufactDeviceID 0x90 //芯片ID(校验用),W25Q64为EF16,W25Q128为EF17
#define W25X_JedecDeviceID 0x9F //JEDECID,不知道什么东西

写使能:

/*
W25Q64写入数据时必须写使能
指令0x06
*/
void W25Q64_WriteEnabled(void)
{
	W25Q64_CS=0;
	SPI_ReadWriteOneData(0x06);
	W25Q64_CS=1;
}

读取状态寄存器1

/*
等待状态寄存器状态为可操作状态。状态寄存器最低位1代表忙,不可工作,0代表可写可读,可放在读、写代码后,保证下次可进行操作
*/
void W25Q64_GetSR(void)
{
	u8 state=1;
	while(state&0x01)
	{
		W25Q64_CS=0;
		SPI_ReadWriteOneData(0x05);
		state=SPI_ReadWriteOneData(0xff);
		W25Q64_CS=1;
	}
}

页写:

/*
页写,不考虑数据的擦除,擦除的最小单位为一个扇区
一页256字节
一个扇区4096字节
W25Q64地址为24位
addr:要写入的地址,data写入的数据,len写入的长度
页写命令:0x02
*/

void W25Q64_PageWriteData(u32 addr,u8 *data,u32 len)
{
	u32 i=0;
	W25Q64_WriteEnabled();//写使能
	W25Q64_CS=0;
	SPI_ReadWriteOneData(0x02);//页写命令
	SPI_ReadWriteOneData(addr>>16);
	SPI_ReadWriteOneData(addr>>8);
	SPI_ReadWriteOneData(addr);
	
	for(i=0;i<len;i++)
	{
		SPI_ReadWriteOneData(data[i]);
	}
	W25Q64_CS=1;
	W25Q64_GetSR();//等待状态寄存器最低位为0,处于不忙状态
}

擦除:

/*
函数功能: 擦除扇区sector erase
函数参数:
				u32 addr: 擦除扇区的起始地址。
说明: 一个扇区是4096字节。  0~4095是第一个扇区  4096+....第二个扇区

填100、200、345、78时都代表第0个扇区
*/
void W25Q64_SectorErase(u32 addr)
{
		W25Q64_WriteEnabled(); //发送写使能指令
	  W25Q64_CS=0; //拉低片选
	  SPI_ReadWriteOneData(0x20); //扇区擦除指令
		//24位的地址
		SPI_ReadWriteOneData(addr>>16);
	  SPI_ReadWriteOneData(addr>>8);
	  SPI_ReadWriteOneData(addr);
		
	  W25Q64_CS=1; //拉高片选
		
		//等待擦除完成
		W25Q64_GetSR();
}

无校验写满一个扇区:

/*
无检验写入数据,写满一个扇区,自动换页。
addr:
data:
len:
*/
void W25Q64_NoCheckPageWrite(u32 addr,u8 *data,u32 len)
{
	u32 page_remain = 256-addr%256;//算出开始写入数据的某一页的剩余未写字节数
	if(page_remain>=len)//该页剩余的空间足够写入这些数据时
	{
		page_remain=len;//把写入长度赋值
	}
	while(1)
	{
		W25Q64_PageWriteData(addr,data,page_remain);
		if(page_remain==len) break;//判断是否写完,如果剩余的空间足够写入这些数据,就执行一次上面的函数,如果不够则进行下面的语句。
		
		addr+=page_remain;//如果不相等说明len比page_remain大,则地址偏移已经写入的长度
		data+=page_remain;//数据偏移
		len-=page_remain;//总长度减去已经写入的长度
		if(len<256)//判断剩余长度是否够写一整页,不够就赋值实际剩余长度,够就赋值256
		{
			page_remain=len;
		}
		else
		{
			page_remain=256;
		}
	}
	//W25Q64_GetSR();//等待写入完成,不用写,因为该函数基于W25Q64_PageWriteData();
}

写满一个扇区的原理和写满一页的原理一样,溢出都会覆盖已经写入的数据,所有可仿照上面写满一扇区的原理,来利用上面的函数写,写整片芯片的函数。

  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值