STM32之W25Qxx(Flash)掉电保存

简单说一下W25Qxx芯片:W25Qxx芯片为Flash芯片,可以实现数据保存,且掉电不丢失。

部分AT24Cxx的容量如图,该芯片通过 SPI 总线与 STM32 连接

                                        

电路如下(原子的):

                            

讲实现之前,简单介绍一下SPI:

SPI 是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口。是 Motorola首先在其 MC68HCXX 系列处理器上定义的。SPI 接口主要应用在 EEPROM,FLASH,实时时钟,AD 转换器,还有数字信号处理器和数字信号解码器之间。SPI 是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为 PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,STM32F1 也有 SPI 接口。

SPI 接口一般使用 4 条线通信:
MISO 主设备数据输入,从设备数据输出。
MOSI 主设备数据输出,从设备数据输入。
SCLK 时钟信号,由主设备产生。
CS 从设备片选信号,由主设备控制。

SPI 主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。SPI 总线四种工作方式 SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果 CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果 CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果 CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI 主模块和与之通信的外设备时钟相位和极性应该一致。

SPI  总线时序图

                  

 STM32F1 的 SPI 功能很强大,SPI 时钟最高可以到 18Mhz,支持 DMA,可以配置为 SPI协议或者 I2S 协议。

代码实现:

稍微讲一下代码以及使用 :

W25Q128写数据:

//SPI在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!	 
void SPI_Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
 	u16 i;  
    SPI_FLASH_Write_Enable();                  //SET WEL 
	SPI_FLASH_CS=0;                            //使能器件   
    SPI1_ReadWriteByte(W25X_PageProgram);      //发送写页命令   
    SPI1_ReadWriteByte((u8)((WriteAddr)>>16)); //发送24bit地址    
    SPI1_ReadWriteByte((u8)((WriteAddr)>>8));   
    SPI1_ReadWriteByte((u8)WriteAddr);   
    for(i=0;i<NumByteToWrite;i++)SPI1_ReadWriteByte(pBuffer[i]);//循环写数  
	SPI_FLASH_CS=1;                            //取消片选 
	SPI_Flash_Wait_Busy();					   //等待写入结束
} 

W25Q128 读数据

//读取SPI FLASH  
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(24bit)
//NumByteToRead:要读取的字节数(最大65535)
void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)   
{ 
 	u16 i;    												    
	SPI_FLASH_CS=0;                            //使能器件   
    SPI1_ReadWriteByte(W25X_ReadData);         //发送读取命令   
    SPI1_ReadWriteByte((u8)((ReadAddr)>>16));  //发送24bit地址    
    SPI1_ReadWriteByte((u8)((ReadAddr)>>8));   
    SPI1_ReadWriteByte((u8)ReadAddr);   
    for(i=0;i<NumByteToRead;i++)
	{ 
        pBuffer[i]=SPI1_ReadWriteByte(0XFF);   //循环读数  
    }
	SPI_FLASH_CS=1;                            //取消片选     	      
}  

初始化代码之后,可以往W25Q128(Flash),写入字符、字符串、数字等,

断电之后,数据还保存在W25Q128里面,只要使用读函数,就可以将数据读出来

示例:

const u8 TEXT_Buffer[]={12,2,34,54};

          //TEXT_Buffer[]={"dafeacaeceawa"}; 可以是字符串

#define SIZE sizeof(TEXT_Buffer)                                                                                        

W25QXX_Write((u8*)TEXT_Buffer,        FLASH_SIZE-100,        SIZE);            //从倒数第100个地址处开始,写入SIZE长度的数据

       // (u8*)TEXT_Buffer, :数据 ,要写入的数据,这里是数组

        //FLASH_SIZE-100  开始写入的地址

       //  SIZE:写入的字节数,就是数组的大小

W25QXX_Read(datatemp,          FLASH_SIZE-100,          SIZE);                    //从倒数第100个地址处开始,读出SIZE个字节

       // (u8*)TEXT_Buffer, :数据 ,要读出的数据,这里是数组

        //FLASH_SIZE-100  开始读的地址

       //  SIZE:读出的字节数,就是数组的大小

开始写入的数据为TEXT_Buffer[]={12,2,34,54};;  

因此读出时,datatemp []={12,2,34,54};  要什么数据直接对数组操作就行  

W25Q 128 初始化


//4Kbytes为一个Sector
//16个扇区为1个Block
//W25Q64
//容量为8M字节,共有128个Block,2048个Sector 

//初始化SPI FLASH的IO口
void SPI_Flash_Init(void)
{
	RCC->APB2ENR|=1<<2;       	//PORTA时钟使能  
	GPIOA->CRL&=0XFFF000FF; 
	GPIOA->CRL|=0X00033300;		//PA2.3.4 推挽 	    
	GPIOA->ODR|=0X7<<2;    		//PA2.3.4上拉
	SPI1_Init();		   		//初始化SPI1
	SPI1_SetSpeed(SPI_SPEED_4);	//设置为18M时钟,高速模式
	SPI_FLASH_TYPE=SPI_Flash_ReadID();//读取FLASH ID.
}

 

接下来这部分的代码主要是SPI的初始化以及一些驱动,就粘贴出来,不作详细的介绍了

//这里针是对SPI1的初始化
void SPI1_Init(void)
{	 
	RCC->APB2ENR|=1<<2;       //PORTA时钟使能 	 
	RCC->APB2ENR|=1<<12;      //SPI1时钟使能 
		   
	//这里只针对SPI口初始化
	GPIOA->CRL&=0X000FFFFF; 
	GPIOA->CRL|=0XBBB00000;//PA5.6.7复用 	    
	GPIOA->ODR|=0X7<<5;    //PA5.6.7上拉
		
	SPI1->CR1|=0<<10;//全双工模式	
	SPI1->CR1|=1<<9; //软件nss管理
	SPI1->CR1|=1<<8;  

	SPI1->CR1|=1<<2; //SPI主机
	SPI1->CR1|=0<<11;//8bit数据格式	
	SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1
	SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1  
	SPI1->CR1|=7<<3; //Fsck=Fcpu/256
	SPI1->CR1|=0<<7; //MSBfirst   
	SPI1->CR1|=1<<6; //SPI设备使能
	SPI1_ReadWriteByte(0xff);//启动传输(主要作用:维持MOSI为高)		 
}   
//SPI1 速度设置函数
//SpeedSet:0~7
//SPI速度=fAPB2/2^(SpeedSet+1)
//APB2时钟一般为72Mhz
void SPI1_SetSpeed(u8 SpeedSet)
{
	SpeedSet&=0X07;			//限制范围
	SPI1->CR1&=0XFFC7; 
	SPI1->CR1|=SpeedSet<<3;	//设置SPI1速度  
	SPI1->CR1|=1<<6; 		//SPI设备使能 
} 
//SPI1 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{		
	u16 retry=0;				 
	while((SPI1->SR&1<<1)==0)//等待发送区空	
	{
		retry++;
		if(retry>0XFFFE)return 0;
	}			  
	SPI1->DR=TxData;	 	  //发送一个byte 
	retry=0;
	while((SPI1->SR&1<<0)==0) //等待接收完一个byte  
	{
		retry++;
		if(retry>0XFFFE)return 0;
	}	  						    
	return SPI1->DR;          //返回收到的数据				    
}

总结:

1、STM32 与 W25Q128 通信方式为IIC通信;

2、W25Q128 为Flash 芯片,可以实现数据的掉电保存

3、往W25Q128 写入和读出数据只需要对W25Q128的地址写入和读出就行

4、读出的数据,可以保存在数组里面,操作只需要对数组进行操作

 

 

 

 

 

 

  • 6
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 不是所有的ROM都可以掉电保存。ROM(Read-Only Memory)是只读存储器,一般用于存储固定的程序代码和数据。ROM的种类很多,有EPROM、EEPROM、Flash等。其中,EPROM(可擦除可编程只读存储器)和EEPROM(电可擦除可编程只读存储器)是需要外部电压来清除数据的,掉电后数据不会保存。而Flash存储器可以在掉电情况下保存数据,因此常用于嵌入式系统和移动设备中。 ### 回答2: ROM(只读存储器)是一种基本的计算机存储器,它的特点是可以进行读取操作但不能进行写入操作。ROM存储器中的数据一般在制造过程中被写入,并且在正常情况下是不会改变的。 与RAM(随机存取存储器)不同,ROM存储器在掉电或断电的情况下可以保持数据的稳定性。即使没有外部供电,ROM中的数据仍然可以被读取。 ROM存储器的稳定性是由其物理特性决定的。在制造ROM芯片时,数据被永久地编码到硬件电路中,这个过程是不可逆的。这意味着即使没有电源供应,ROM芯片的数据仍然保持原样。 ROM存储器的不可改写性使其在计算机系统中具有重要的作用。它常被用来存储系统的固件、启动代码和其他需要长期保存的程序或数据。由于ROM存储器的稳定性和不可改写的特点,它可以保证计算机系统在掉电或断电后重新启动时,仍能正确地加载和运行存储在ROM中的程序。 总之,ROM存储器的数据在掉电或断电的情况下仍然可以保存,这是由于ROM的物理特性决定的。ROM存储器在计算机系统中扮演着重要的角色,用于存储固件、启动代码和其他长期保存的程序或数据。 ### 回答3: 不是所有的ROM都可以掉电保存。ROM代表的是只读存储器,是一种不可擦除或重写的存储器类型。常见的ROM包括Mask ROM、ROM芯片和光盘等。这些ROM在制造时被写入数据,之后数据是固定的,不能被修改或擦除。因此,即使断电或掉电,ROM中的数据也会被保留。 然而,还有一种被称为EPROM(可擦除可编程只读存储器)的ROM类型,它具有较高的可编程性。EPROM通过特殊的擦除和编程操作,可以被多次擦除和重新编写。在掉电后,EPROM中的数据仍然保持不变。但是,如果进行了擦除操作,EPROM中的数据将被清除,需要重新编程才能重新存储数据。 另外,随着技术的发展,出现了更加先进的存储器类型,如闪存和EEPROM(电子可擦除可编程只读存储器)。它们类似于EPROM,可以被擦除和编程,但在掉电后数据仍然保持。这种类型的存储器广泛应用于各种电子设备中,如移动电话、USB驱动器和固态硬盘等。 综上所述,ROM并不都可以掉电保存。只有一些可擦除和可编程的ROM类型如EPROM、EEPROM和闪存等才可以在掉电保存数据。一般的ROM是不可擦除和重写的,数据在断电后仍然保留。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值