W25QXX使用教程

article/2025/11/7 11:39:50

W25QXX是华邦公司生产的一块FLASH储存芯片

那W25Q256为例:驱动方式:单路双路四路SPI、QSPI;
擦写周期:10W次
支持电压:2.7~3.6V
频率:单路最大104Mhz、双路208Mhz、四路416Mhz
容量:容量为32M字节;
它将32M的容量分为512个块(Block),那么每个块的容量就是64K字节;
每个块又分为16个扇区(Sector),每个扇区4K个字节;
在这里插入图片描述

那我们需要给W25Q256开辟一个至少4K的缓存区,这样对SRAM要求较高,芯片必须有4K以上的SRAM才能很好的操作,因为它的写操作需要先计算出它的扇区,把这个扇区的内容全部读出来,存放到芯片的SRAM里面进行修改,然后在一次性吧内容写入芯片。

引脚排列

在这里插入图片描述

引脚描述

在这里插入图片描述

硬件连接

在这里插入图片描述
操作指令:
在这里插入图片描述
w25qxx.h

#ifndef __W25QXX_H
#define __W25QXX_H
#include "sys.h"// 	//W25X系列/Q系列芯片列表	   
//W25Q80  ID  0XEF13
//W25Q16  ID  0XEF14
//W25Q32  ID  0XEF15
//W25Q64  ID  0XEF16	
//W25Q128 ID  0XEF17	
//W25Q256 ID  0XEF18
#define W25Q80 	0XEF13 	
#define W25Q16 	0XEF14
#define W25Q32 	0XEF15
#define W25Q64 	0XEF16
#define W25Q128	0XEF17
#define W25Q256 0XEF18extern u16 W25QXX_TYPE;					//定义W25QXX芯片型号		   #define	W25QXX_CS 		PFout(6)  		//W25QXX的片选信号// 
//指令表
#define W25X_WriteEnable		0x06 
#define W25X_WriteDisable		0x04 
#define W25X_ReadStatusReg1		0x05 
#define W25X_ReadStatusReg2		0x35 
#define W25X_ReadStatusReg3		0x15 
#define W25X_WriteStatusReg1    0x01 
#define W25X_WriteStatusReg2    0x31 
#define W25X_WriteStatusReg3    0x11 
#define W25X_ReadData			0x03 
#define W25X_FastReadData		0x0B 
#define W25X_FastReadDual		0x3B 
#define W25X_PageProgram		0x02 
#define W25X_BlockErase			0xD8 
#define W25X_SectorErase		0x20 
#define W25X_ChipErase			0xC7 
#define W25X_PowerDown			0xB9 
#define W25X_ReleasePowerDown	0xAB 
#define W25X_DeviceID			0xAB 
#define W25X_ManufactDeviceID	0x90 
#define W25X_JedecDeviceID		0x9F 
#define W25X_Enable4ByteAddr    0xB7
#define W25X_Exit4ByteAddr      0xE9void W25QXX_Init(void);
u16  W25QXX_ReadID(void);  	    		//读取FLASH ID
u8 W25QXX_ReadSR(u8 regno);             //读取状态寄存器 
void W25QXX_4ByteAddr_Enable(void);     //使能4字节地址模式
void W25QXX_Write_SR(u8 regno,u8 sr);   //写状态寄存器
void W25QXX_Write_Enable(void);  		//写使能 
void W25QXX_Write_Disable(void);		//写保护
void W25QXX_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite);
void W25QXX_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead);   //读取flash
void W25QXX_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite);//写入flash
void W25QXX_Erase_Chip(void);    	  	//整片擦除
void W25QXX_Erase_Sector(u32 Dst_Addr);	//扇区擦除
void W25QXX_Wait_Busy(void);           	//等待空闲
void W25QXX_PowerDown(void);        	//进入掉电模式
void W25QXX_WAKEUP(void);				//唤醒#endif

w25qxx.c

#include "w25qxx.h"
#include "spi.h"
#include "delay.h"
#include "usart.h"
#include "stm32f4xx_hal_gpio.h"// 	u16 W25QXX_TYPE=W25Q256;	//默认是W25Q256//4Kbytes为一个Sector
//16个扇区为1个Block
//W25Q256
//容量为32M字节,共有512个Block,8192个Sector //初始化SPI FLASH的IO口
void W25QXX_Init(void)
{ u8 temp;GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOF_CLK_ENABLE();           //使能GPIOF时钟//PF6GPIO_Initure.Pin=GPIO_PIN_6;            //PF6GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出GPIO_Initure.Pull=GPIO_PULLUP;          //上拉GPIO_Initure.Speed=GPIO_SPEED_FAST;     //快速         HAL_GPIO_Init(GPIOF,&GPIO_Initure);     //初始化W25QXX_CS=1;			                //SPI FLASH不选中SPI5_Init();		   			        //初始化SPISPI5_SetSpeed(SPI_BAUDRATEPRESCALER_2); //设置为45M时钟,高速模式W25QXX_TYPE=W25QXX_ReadID();	        //读取FLASH ID.if(W25QXX_TYPE==W25Q256)                //SPI FLASH为W25Q256{temp=W25QXX_ReadSR(3);              //读取状态寄存器3,判断地址模式if((temp&0X01)==0)			        //如果不是4字节地址模式,则进入4字节地址模式{W25QXX_CS=0; 			        //选中SPI5_ReadWriteByte(W25X_Enable4ByteAddr);//发送进入4字节地址模式指令   W25QXX_CS=1;       		        //取消片选   }}
}  //读取W25QXX的状态寄存器,W25QXX一共有3个状态寄存器
//状态寄存器1:
//BIT7  6   5   4   3   2   1   0
//SPR   RV  TB BP2 BP1 BP0 WEL BUSY
//SPR:默认0,状态寄存器保护位,配合WP使用
//TB,BP2,BP1,BP0:FLASH区域写保护设置
//WEL:写使能锁定
//BUSY:忙标记位(1,忙;0,空闲)
//默认:0x00
//状态寄存器2:
//BIT7  6   5   4   3   2   1   0
//SUS   CMP LB3 LB2 LB1 (R) QE  SRP1
//状态寄存器3:
//BIT7      6    5    4   3   2   1   0
//HOLD/RST  DRV1 DRV0 (R) (R) WPS ADP ADS
//regno:状态寄存器号,范:1~3
//返回值:状态寄存器值
u8 W25QXX_ReadSR(u8 regno)   
{  u8 byte=0,command=0; switch(regno){case 1:command=W25X_ReadStatusReg1;    //读状态寄存器1指令break;case 2:command=W25X_ReadStatusReg2;    //读状态寄存器2指令break;case 3:command=W25X_ReadStatusReg3;    //读状态寄存器3指令break;default:command=W25X_ReadStatusReg1;    break;}    W25QXX_CS=0;                            //使能器件   SPI5_ReadWriteByte(command);            //发送读取状态寄存器命令    byte=SPI5_ReadWriteByte(0Xff);          //读取一个字节  W25QXX_CS=1;                            //取消片选     return byte;   
} 
//写W25QXX状态寄存器
void W25QXX_Write_SR(u8 regno,u8 sr)   
{   u8 command=0;switch(regno){case 1:command=W25X_WriteStatusReg1;    //写状态寄存器1指令break;case 2:command=W25X_WriteStatusReg2;    //写状态寄存器2指令break;case 3:command=W25X_WriteStatusReg3;    //写状态寄存器3指令break;default:command=W25X_WriteStatusReg1;    break;}   W25QXX_CS=0;                            //使能器件   SPI5_ReadWriteByte(command);            //发送写取状态寄存器命令    SPI5_ReadWriteByte(sr);                 //写入一个字节  W25QXX_CS=1;                            //取消片选     	      
}   
//W25QXX写使能	
//将WEL置位   
void W25QXX_Write_Enable(void)   
{W25QXX_CS=0;                            //使能器件   SPI5_ReadWriteByte(W25X_WriteEnable);   //发送写使能  W25QXX_CS=1;                            //取消片选     	      
} 
//W25QXX写禁止	
//将WEL清零  
void W25QXX_Write_Disable(void)   
{  W25QXX_CS=0;                            //使能器件   SPI5_ReadWriteByte(W25X_WriteDisable);  //发送写禁止指令    W25QXX_CS=1;                            //取消片选     	      
} //读取芯片ID
//返回值如下:				   
//0XEF13,表示芯片型号为W25Q80  
//0XEF14,表示芯片型号为W25Q16    
//0XEF15,表示芯片型号为W25Q32  
//0XEF16,表示芯片型号为W25Q64 
//0XEF17,表示芯片型号为W25Q128 	  
//0XEF18,表示芯片型号为W25Q256
u16 W25QXX_ReadID(void)
{u16 Temp = 0;	  W25QXX_CS=0;				    SPI5_ReadWriteByte(0x90);//发送读取ID命令	    SPI5_ReadWriteByte(0x00); 	    SPI5_ReadWriteByte(0x00); 	    SPI5_ReadWriteByte(0x00); 	 			   Temp|=SPI5_ReadWriteByte(0xFF)<<8;  Temp|=SPI5_ReadWriteByte(0xFF);	 W25QXX_CS=1;				    return Temp;
}   		    
//读取SPI FLASH  
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(24bit)
//NumByteToRead:要读取的字节数(最大65535)
void W25QXX_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)   
{ u16 i;   										    W25QXX_CS=0;                            //使能器件   SPI5_ReadWriteByte(W25X_ReadData);      //发送读取命令  if(W25QXX_TYPE==W25Q256)                //如果是W25Q256的话地址为4字节的,要发送最高8位{SPI5_ReadWriteByte((u8)((ReadAddr)>>24));    }SPI5_ReadWriteByte((u8)((ReadAddr)>>16));   //发送24bit地址    SPI5_ReadWriteByte((u8)((ReadAddr)>>8));   SPI5_ReadWriteByte((u8)ReadAddr);   for(i=0;i<NumByteToRead;i++){ pBuffer[i]=SPI5_ReadWriteByte(0XFF);    //循环读数  }W25QXX_CS=1;  				    	      
}  
//SPI在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!	 
void W25QXX_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{u16 i;  W25QXX_Write_Enable();                  //SET WEL W25QXX_CS=0;                            //使能器件   SPI5_ReadWriteByte(W25X_PageProgram);   //发送写页命令   if(W25QXX_TYPE==W25Q256)                //如果是W25Q256的话地址为4字节的,要发送最高8位{SPI5_ReadWriteByte((u8)((WriteAddr)>>24)); }SPI5_ReadWriteByte((u8)((WriteAddr)>>16)); //发送24bit地址    SPI5_ReadWriteByte((u8)((WriteAddr)>>8));   SPI5_ReadWriteByte((u8)WriteAddr);   for(i=0;i<NumByteToWrite;i++)SPI5_ReadWriteByte(pBuffer[i]);//循环写数  W25QXX_CS=1;                            //取消片选 W25QXX_Wait_Busy();					   //等待写入结束
} 
//无检验写SPI FLASH 
//必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
//具有自动换页功能 
//在指定地址开始写入指定长度的数据,但是要确保地址不越界!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)
//CHECK OK
void W25QXX_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   
{ 			 		 u16 pageremain;	   pageremain=256-WriteAddr%256; //单页剩余的字节数		 	    if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//不大于256个字节while(1){	   W25QXX_Write_Page(pBuffer,WriteAddr,pageremain);if(NumByteToWrite==pageremain)break;//写入结束了else //NumByteToWrite>pageremain{pBuffer+=pageremain;WriteAddr+=pageremain;	NumByteToWrite-=pageremain;			  //减去已经写入了的字节数if(NumByteToWrite>256)pageremain=256; //一次可以写入256个字节else pageremain=NumByteToWrite; 	  //不够256个字节了}};	    
} 
//写SPI FLASH  
//在指定地址开始写入指定长度的数据
//该函数带擦除操作!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)						
//NumByteToWrite:要写入的字节数(最大65535)   
u8 W25QXX_BUFFER[4096];		 
void W25QXX_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   
{ u32 secpos;u16 secoff;u16 secremain;	   u16 i;    u8 * W25QXX_BUF;	  W25QXX_BUF=W25QXX_BUFFER;	     secpos=WriteAddr/4096;//扇区地址  secoff=WriteAddr%4096;//在扇区内的偏移secremain=4096-secoff;//扇区剩余空间大小   //printf("ad:%X,nb:%X\r\n",WriteAddr,NumByteToWrite);//测试用if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节while(1) {	W25QXX_Read(W25QXX_BUF,secpos*4096,4096);//读出整个扇区的内容for(i=0;i<secremain;i++)//校验数据{if(W25QXX_BUF[secoff+i]!=0XFF)break;//需要擦除  	  }if(i<secremain)//需要擦除{W25QXX_Erase_Sector(secpos);//擦除这个扇区for(i=0;i<secremain;i++)	   //复制{W25QXX_BUF[i+secoff]=pBuffer[i];	  }W25QXX_Write_NoCheck(W25QXX_BUF,secpos*4096,4096);//写入整个扇区  }else W25QXX_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间. 				   if(NumByteToWrite==secremain)break;//写入结束了else//写入未结束{secpos++;//扇区地址增1secoff=0;//偏移位置为0 	 pBuffer+=secremain;  //指针偏移WriteAddr+=secremain;//写地址偏移	   NumByteToWrite-=secremain;				//字节数递减if(NumByteToWrite>4096)secremain=4096;	//下一个扇区还是写不完else secremain=NumByteToWrite;			//下一个扇区可以写完了}	 };	 
}
//擦除整个芯片		  
//等待时间超长...
void W25QXX_Erase_Chip(void)   
{                                   W25QXX_Write_Enable();                  //SET WEL W25QXX_Wait_Busy();   W25QXX_CS=0;                            //使能器件   SPI5_ReadWriteByte(W25X_ChipErase);        //发送片擦除命令  W25QXX_CS=1;                            //取消片选     	      W25QXX_Wait_Busy();   				   //等待芯片擦除结束
}   
//擦除一个扇区
//Dst_Addr:扇区地址 根据实际容量设置
//擦除一个扇区的最少时间:150ms
void W25QXX_Erase_Sector(u32 Dst_Addr)   
{  //监视falsh擦除情况,测试用   //printf("fe:%x\r\n",Dst_Addr);	  Dst_Addr*=4096;W25QXX_Write_Enable();                  //SET WEL 	 W25QXX_Wait_Busy();   W25QXX_CS=0;                            //使能器件   SPI5_ReadWriteByte(W25X_SectorErase);   //发送扇区擦除指令 if(W25QXX_TYPE==W25Q256)                //如果是W25Q256的话地址为4字节的,要发送最高8位{SPI5_ReadWriteByte((u8)((Dst_Addr)>>24)); }SPI5_ReadWriteByte((u8)((Dst_Addr)>>16));  //发送24bit地址    SPI5_ReadWriteByte((u8)((Dst_Addr)>>8));   SPI5_ReadWriteByte((u8)Dst_Addr);  W25QXX_CS=1;                            //取消片选     	      W25QXX_Wait_Busy();   				    //等待擦除完成
}  
//等待空闲
void W25QXX_Wait_Busy(void)   
{   while((W25QXX_ReadSR(1)&0x01)==0x01);   // 等待BUSY位清空
}  
//进入掉电模式
void W25QXX_PowerDown(void)   
{ W25QXX_CS=0;                            //使能器件   SPI5_ReadWriteByte(W25X_PowerDown);     //发送掉电命令  W25QXX_CS=1;                            //取消片选     	      delay_us(3);                            //等待TPD  
}   
//唤醒
void W25QXX_WAKEUP(void)   
{  W25QXX_CS=0;                                //使能器件   SPI5_ReadWriteByte(W25X_ReleasePowerDown);  //  send W25X_PowerDown command 0xAB    W25QXX_CS=1;                                //取消片选     	      delay_us(3);                                //等待TRES1
}   

W25QXX_Write函数思路

  1. 每个扇区(sector)是4K,也就是4096个地址

  2. 在写任何一个地址之前,如果该地址的值不是0xFF,必须先擦除对应的扇区(sector),然后再写。

  3. 最大支持写操作的单元是page(页)一个扇区4K字节

  4. 根据要写的起始地址,确定要写的起始区域的扇区(Sector)号以及在起始扇区(Sector)中的偏移量。

  5. 根据要写的起始地址和字节数,确定要写的数据是否跨扇区(Sector)。

  6. 确定好要操作的扇区(Sector)以及扇区(Sector)的地址范围。

  7. 对每个扇区(Sector),先遍历要写的地址区域保存的数据是不是0xff,如果都是,就不用擦除。如果有不是0xff的区域,先读出里面的数据,保存在缓存W25QXX_BUFFER,然后擦除里面的内容。然后把这个sector要操作的数据,写到缓存。最后一次性吧缓存W25QXX_BUFFER的数据写到这个对应的扇区(Sector)。

main.c

//要写入到W25Q256的字符串数组
const u8 TEXT_Buffer[]={"Apollo STM32F4 SPI TEST"};
#define SIZE sizeof(TEXT_Buffer)	 int main(void)
{     u8 key;u16 i=0;u8 datatemp[SIZE];u32 FLASH_SIZE;Stm32_Clock_Init(360,25,2,8);//设置时钟,180Mhzdelay_init(180);			//初始化延时函数 uart_init(90,115200);		//初始化串口波特率为115200usmart_dev.init(90);		//初始化USMARTLED_Init();					//初始化与LED连接的硬件接口SDRAM_Init();				//初始化SDRAM LCD_Init();					//初始化LCD	KEY_Init(); 				//按键初始化 W25QXX_Init();				//W25QXX初始化POINT_COLOR=RED;LCD_ShowString(30,50,200,16,16,"Apollo STM32F4/F7"); LCD_ShowString(30,70,200,16,16,"SPI TEST");	LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,110,200,16,16,"2021/01/24");	 		LCD_ShowString(30,130,200,16,16,"KEY1:Write  KEY0:Read");	//显示提示信息		while(W25QXX_ReadID()!=W25Q256)								//检测不到W25Q256{LCD_ShowString(30,150,200,16,16,"W25Q256 Check Failed!");delay_ms(500);LCD_ShowString(30,150,200,16,16,"Please Check!        ");delay_ms(500);LED0=!LED0;		//DS0闪烁}LCD_ShowString(30,150,200,16,16,"W25Q256 Ready!"); FLASH_SIZE=32*1024*1024;	//FLASH 大小为32M字节POINT_COLOR=BLUE;			//设置字体为蓝色	  while(1){key=KEY_Scan(0);if(key==KEY1_PRES)//KEY1按下,写入W25Q256{LCD_Fill(0,170,239,319,WHITE);//清除半屏    LCD_ShowString(30,170,200,16,16,"Start Write W25Q256....");W25QXX_Write((u8*)TEXT_Buffer,FLASH_SIZE-100,SIZE);		//从倒数第100个地址处开始,写入SIZE长度的数据LCD_ShowString(30,170,200,16,16,"W25Q256 Write Finished!");	//提示传送完成}if(key==KEY0_PRES)//KEY0按下,读取字符串并显示{LCD_ShowString(30,170,200,16,16,"Start Read W25Q256.... ");W25QXX_Read(datatemp,FLASH_SIZE-100,SIZE);					//从倒数第100个地址处开始,读出SIZE个字节LCD_ShowString(30,170,200,16,16,"The Data Readed Is:   ");	//提示传送完成LCD_ShowString(30,190,200,16,16,datatemp);					//显示读到的字符串} i++;delay_ms(10);if(i==20){LED0=!LED0;//提示系统正在运行	i=0;}		   }	  
}

http://chatgpt.dhexx.cn/article/828Flfyt.shtml

相关文章

flash spi w25q128 w25q64 w25q32 w25q16 verilog fpga程序代码

flash spi w25q128 w25q64 w25q32 w25q16 verilog fpga程序代码 fpga w25q128/64/32/16 verilog代码 资料包清单&#xff1a; 1.w25qxx_code_uart_top&#xff1a;altera工程代码&#xff0c;可移植ise&#xff0c;后续会出&#xff0c;需要的话提前加好友 2.功能说明书 注1&a…

STM32读写W25Q

文章目录 硬件外观引脚说明代码摘要代码获取 硬件外观 引脚说明 关于如何接线&#xff1f; 1&#xff0c;CS 2&#xff0c;MISO 3&#xff0c;3.3V 4&#xff0c;GND 5&#xff0c;MOSI 6&#xff0c;SCK 7&#xff0c;3.3V 8&#xff0c;3.3V 关于如何查询芯片引脚&#xff…

SPI Flash芯片W25Q32英文版数据手册解读(三)---------程序编写,电路应用

一、序言 序言对这篇文章进行一个总体的说明&#xff1a; 1、这部分是根据手册写程序&#xff0c;因此采用手册截图程序截图的形式&#xff0c;对图片不进行标号&#xff0c;而且对重点部分进行颜色标注。 2、考虑到很多读者&#xff08;包括我&#xff09;&#xff0c;使用…

K_A39_012 基于STM32驱动W25Q32 模块读写数据 串口+OLED0.96显示

K_A39_012 基于STM32驱动W25Q32 模块读写数据 串口OLED0.96显示 所有资源导航一、资源说明二、基本参数参数引脚说明 三、驱动说明时序对应程序: 四、部分代码说明1、接线引脚定义1.2、STM32F103C8T6W25Q32 模块 五、基础知识学习与相关资料下载六、视频效果展示与程序资料获取…

W25Q16编址详解

W25Q16是一款基于SPI接口Flash存储器。 但往往我们对一串长长的16进制地址无从下手&#xff0c;以至于数据存储位置不当。 先看一下官方的数据手册 看着比较乱&#xff0c;我们自己画一个思维导图帮助理解 可以看到W25Q16最大寻址范围为0x000000H~0x1FFFFFH &#xff0c;根据…

rt-thread通过spi连接W25Q32后无法读取ID

注意&#xff0c;cs引脚必须由rtt控制&#xff0c;但是我这个cs引脚用的是PA15&#xff0c;它默认是jlink的引脚&#xff0c;所以首先要将jlink禁用&#xff0c;如下&#xff1a; rcu_periph_clock_enable(RCU_AF);rcu_periph_clock_enable(RCU_GPIOA);rcu_periph_clock_enable…

stm32 操作W25Q256 W25Q16 spi flash

硬件连接 今天我使用W25Q16做了一个测试&#xff0c;发现了W25Q16内部是一个环形缓冲区&#xff0c;在0x200000地址处写入数据&#xff0c;我可以在0x000000处读取到0x200000地址的数据&#xff0c;从这里就可以正面W25Q16是一个环形缓冲区的norfalsh 本函数库来自正点原子官…

W25Q32的使用

一、W25Q32简介 W25Q32是华邦公司推出的大容量“SPI FLASH” 产品。 1、容量 32M-Bit/4M-byte(4,194,304)2、存储结构 页:256-bytes扇区:4K-bytes块:64K_bytes是故: 页:16384个扇区:1024个块:64个3、速度 时钟速度最高:80MHz4、特性 擦除、写次数:高达100,000次数据保…

基于STM32实现W25Q16读写操作(spi)

文章目录 前言一、W25Q161.介绍2.SPI2.1. 简介2.2. 特性2.3. 功能说明2.4. 工作模式2.5. 引脚说明 二、代码开发1.SPI初始化2.读取厂商ID2.1.读写字节2.2.读取ID 3.其他的一些操作4.完整代码 三、效果演示 前言 在之前我们学习了flash闪存&#xff0c;这个更多的是内部数据存储…

GD32F303访问W25Q32异常问题解决

最近在使用国产化GD32F303替换STM32F103芯片&#xff0c;驱动代码使用的STM32的库函数&#xff0c;调试过程中发现MCU通过SPI访问W25Q32芯片时&#xff0c;会出现写入异常的情况&#xff0c;不是全部错误&#xff0c;是中间某段数据错误。 左侧&#xff1a;待写入文件内容 右侧…

stm32读写w25qxx

一&#xff0c;w25qxx简介。 二&#xff0c;stm32CubeIDE配置。 三&#xff0c;代码 1,w25qxx.c #include "W25Qxx.h"/*********************************************************************************** 函数功能: 模块初始化*/ uint8_t BSP_W25Qx_Init(void) …

STM32(八)W25Q(16/32/64/128)芯片学习总结

系列文章目录 文章目录 系列文章目录前言一、硬件和数据手册部分翻译1.W25Q64硬件设计2.数据手册解读 二、指令 前言 按项目需求&#xff0c;近期调试了W25Q32芯片&#xff0c;W25Q系列芯片是华邦公司推出的大容量SPI FLASH产品&#xff0c;W25Q32是3V&#xff0c;32M-bit 串行…

STC89C52驱动W25Q32测试笔记

STC89C52是经典的C51单片机&#xff0c;该芯片不自带硬件SPI接口&#xff0c;正好有手上一块W25Q32的存储模块&#xff08;某宝上买的2.2元&#xff09;&#xff0c;试着使用89C52模拟SPI接口驱动W25Q32&#xff0c;在驱动的过程中遇到了几个问题&#xff0c;首先的问题是电平不…

SPI Flash芯片W25Q32英文版数据手册解读(二)---------存储器知识,寄存器

接着上一篇文章&#xff0c;由于W25Q32芯片是一个存储器芯片&#xff0c;先对这个芯片有关存储器的一些概念进行解读。 一、存储器相关知识 1、存储器的三个单位&#xff1a; 存储器三个等级&#xff1a;页&#xff08;Page&#xff09;&#xff0c;扇区&#xff08;sector&a…

SPI Flash芯片W25Q32英文版数据手册解读(一)---------引脚功能,工作模式

W25Q32芯片是一个可以通过SPI&#xff08;串行外围设备接口&#xff09;操作的flash存储器&#xff0c;这篇文章备忘和总结一下英文版数据手册的一些解读。有关时序及具体用STC单片机编写程序的内容等下一篇文章。 一、芯片引脚功能 我买的是8引脚、SOIC封装的芯片&#xff0…

w25q32 内存分布

说明 ESP826612F/E里面使用w25q32作为了flash存储. 提前说下哈,bit代表位 也就是 0 1 0 1 , Bit代表字节 ,一字节就是8位 w25q32的容量是32Mbit 也就是 32/8 4MB字节 4*1024 4096KB字节 然后 w25q32 这个芯片规定每 64KB字节作为一个块 所以呢w25q32总共分成了 4096…

基于STM32+SPI+W25Qxx存储芯片指令,时序和函数讲解

前言 本次我们学习一下STM32F103关于SPI对存储芯片的读写&#xff0c;介绍W25QXX芯片和对芯片内部讲解和代码解读&#xff0c;学习W25QXX芯片的各种读写指令&#xff0c;操作芯片读写&#xff0c;认识底层驱动&#xff0c;本篇内容主要目的是教会大家看手册写代码&#xf…

ButterKnife9.0.0-rc2 配置

升级了AndroidStudio到3.4之后&#xff0c;发现项目中的很多依赖库都不能用&#xff0c;原因是随着AS升级之后&#xff0c;Gradle随之升级到3.4.1&#xff0c;很多第三方库也需要更高版本的支撑&#xff0c;今天遇到ButterKnife失效的问题&#xff0c;原本是8.5.1的版本&#x…

How to install Bromine3 RC2

When I install Bromine RC2, I met bellow issues: “Server could not contact itself at the specified address: 127.0.0.1:80” “Error: Database table jobs for model job was not found.” etc. Now I show my exact way to install RC2 successfully: 1. Downl…

fabric1.4.0-rc2快速入门

软件环境 VMware 10.0.4 CentOS-7-x86_64-Minimal-1708 搭建过程 go安装 docker安装 docker-compose安装 一、fabric的编译和安装 1. 创建目录&#xff08;GOPATH变量在安装go的时候就配置好了&#xff09; mkdir -p $GOPATH/src/github.com/hyperledger 2. 下载fabri…