⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sst25vf016bdrv.c

📁 PWM语音播放器基于单片机PwmVoice.ewd
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			SST25VF016BDrv.c
** Descriptions:		SPI下的SST25VF016B操作函数库 
**
**------------------------------------------------------------------------------------------------------
** Created by:			Litiantian
** Created date:		2007-04-16
** Version:				1.0
** Descriptions:		The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:	                柴利明		
** Modified date:	       2008-07-18
** Version:                           1.1
** Descriptions:		
********************************************************************************************************/
#include        "SSTconfig.h"

/* 移植本软件包时需要修改以下的函数或宏 */

/*********************************************************************************************************
** 函数名称: SPIInit
** 函数功能: 初始化控制SSI的管脚
** 入口参数:    无 
** 出口参数:    无                         
** 返回值:      无
*********************************************************************************************************/
void  SPI_Init(void)
{  
  
  
  SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI);                            /*  为SSI提供时钟               */
  
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);                          /*  使能GPIOA                   */

  /*  配置SPI为模式0,主机模式,波特率,数据宽度为8位     */
  SSIConfig(SSI_BASE, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, BitRate, DataWidth);
  SSIEnable(SSI_BASE);                                                  /*  允许对SSI进行操作          */
  
  /*  设置GPIOA2,4,5引脚为SSI配置功能                       */
  GPIOPinTypeSSI(GPIO_PORTA_BASE, (GPIO_PIN_2 | GPIO_PIN_4 |
                 GPIO_PIN_5));
   
  GPIODirModeSet(GPIO_PORTA_BASE, PINS, GPIO_DIR_MODE_OUT);             /*  配置片选管脚为输出         */
  GPIOPadConfigSet(GPIO_PORTA_BASE, PINS, GPIO_STRENGTH_2MA,
                    GPIO_PIN_TYPE_STD);                                 /*  配置片选管脚为上拉,2MA输出*/
  CE_High();

}
/*********************************************************************************************************
** 函数名称: Send_Byte
** 函数功能: 通过硬件SPI发送一个字节到SST25VF016B
** 入口参数: data   发送的数据
** 出口参数:   无
** 返回值:     无

*********************************************************************************************************/
void Send_Byte(uint8 data)
{
   uint32 NullData;
   SSIDataPut(SSI_BASE, data);	
   SSIDataGet(SSI_BASE, &NullData);                                               
}
/*********************************************************************************************************
** 函数名称: Get_Byte
** 函数功能: 通过硬件SPI接口接收一个字节到处理器	
** 入口参数:    无
** 出口参数:    无
** 返回值:   ReadData  读回的数据
*********************************************************************************************************/

uint8 Get_Byte(void)
{
   uint32 ReadData;

   SSIDataPut(SSI_BASE, 0xFF);                                      /*  发送一个无效字节,以产生接收时钟*/
   SSIDataGet(SSI_BASE, &ReadData);
   return (uint8)ReadData;

}
 
/************************************************************************
** 函数名称:SSTF016B_RD																										
** 函数功能:SST25VF016B的读函数,可选择读ID和读数据操作				
** 入口参数:
**			uint32 Dst:目标地址,范围 0x0 - MAX_ADDR(MAX_ADDR = 0x1FFFFF)				
**      	       uint32 NByte:	要读取的数据字节数
**			uint8* RcvBufPt:接收缓存的指针			
** 出口参数:操作成功则返回OK,失败则返回ERROR		
** 注	 意:若某功能下,某一入口参数无效,可在该入口参数处填Invalid,该参数将被忽略
************************************************************************/
uint8 SSTF016B_RD(uint32 Dst, uint32 NByte,uint8* RcvBufPt)
{
	uint32 i = 0;
	if ((Dst+NByte > MAX_ADDR)||(NByte == 0))	return (ERROR);	 //	检查入口参数
	
	CE_Low();			
	Send_Byte(0x0B); 						// 发送读命令
	Send_Byte(((Dst & 0xFFFFFF) >> 16));	// 发送地址信息:该地址由3个字节组成
	Send_Byte(((Dst & 0xFFFF) >> 8));
	Send_Byte(Dst & 0xFF);
	Send_Byte(0xFF);						// 发送一个哑字节以读取数据
	for (i = 0; i < NByte; i++)		
	{
		RcvBufPt[i] = Get_Byte();		
	}
	CE_High();			
	return (OK);
}

/************************************************************************
** 函数名称:SSTF016B_RdID																										
** 函数功能:SST25VF016B的读ID函数,可选择读ID和读数据操作				
** 入口参数:
**			idtype IDType:ID类型。用户可在Jedec_ID,Dev_ID,Manu_ID三者里选择
**			uint32* RcvbufPt:存储ID变量的指针
** 出口参数:操作成功则返回OK,失败则返回ERROR		
** 注	 意:若填入的参数不符合要求,则返回ERROR
************************************************************************/
uint8 SSTF016B_RdID(idtype IDType,uint32* RcvbufPt)
{
	uint32 temp = 0;
        
      
	if (IDType == Jedec_ID)
	{
		CE_Low();			
		Send_Byte(0x9F);		 		/*  发送读JEDEC ID命令(9Fh)  */
    	        
        temp = (temp | Get_Byte()) << 8;                       /*  接收数据                  */ 
		temp = (temp | Get_Byte()) << 8;	
                temp = (temp | Get_Byte()); 	             /*  在本例中,temp的值应为0xBF2541 */
                CE_High();		
		*RcvbufPt = temp;
		return (OK);
	}
	
	if ((IDType == Manu_ID) || (IDType == Dev_ID) )
	{
		CE_Low();			
		Send_Byte(0x90);				/*  发送读ID命令 (90h or ABh)  */
    	Send_Byte(0x00);				       /*  发送地址                    */
		Send_Byte(0x00);		              /*  发送地址                     */
		Send_Byte(IDType);		              /*  发送地址 - 不是00H就是01H    */
		temp = Get_Byte();			      /*  接收获取的数据字节           */
		CE_High();			
		*RcvbufPt = temp;
		return (OK);
	}
	else
	{
		return (ERROR);	
	}
}

/************************************************************************
** 函数名称:SSTF016B_WR											
** 函数功能:SST25VF016B的写函数,可写1个和多个数据到指定地址									
** 入口参数:
**			uint32 Dst:目标地址,范围 0x0 - MAX_ADDR(MAX_ADDR = 0x1FFFFF)				
**			uint8  SndbufPt:发送的数据    	  
** 出口参数:操作成功则返回OK,失败则返回ERROR		
** 注	 意:若某功能下,某一入口参数无效,可在该入口参数处填Invalid,该参数将被忽略
************************************************************************/
uint8 SSTF016B_WR(uint32 Dst,uint8 SendData)
{ 
	        CE_Low();			
		Send_Byte(0x06);		           /*  发送写使能命令         */
		CE_High();			
                CE_Low();			
		Send_Byte(0x02); 			  /*  发送字节数据烧写命令    */
		Send_Byte(((Dst & 0xFFFFFF) >> 16));      /*  发送3个字节的地址信息   */ 
		Send_Byte(((Dst & 0xFFFF) >> 8));
		Send_Byte(Dst & 0xFF);
		Send_Byte(SendData);		         /*  发送被烧写的数据         */
		CE_High();	

return (OK);		
}

/*******************************************************************************
** 函数名称:SSTF016B_WRSTART										
** 函数功能:SST25VF016B的起始函数									
** 入口参数: 无 
** 出口参数:操作成功则返回OK,失败则返回ERROR		
********************************************************************************/
uint8 SSTF016B_WRSTART()
{      
        CE_Low();			 
	Send_Byte(0x05);				  /*  发送读状态寄存器命令   */
						          /*  保存读得的状态寄存器值 */
	CE_High();								

	CE_Low();			
	Send_Byte(0x50);				  /*  使状态寄存器可写        */
	CE_High();			
	CE_Low();			
	Send_Byte(0x01);			          /*  发送写状态寄存器指令    */
	Send_Byte(0);					  /* 清0BPx位,使Flash芯片全区可写  */
	CE_High();
      	
   return (OK);
      
}

/************************************************************************
** 函数名称:SSTF016B_Erase												
** 函数功能:根据指定的扇区号选取最高效的算法擦除								
** 入口参数:
**			uint32 sec1:起始扇区号,范围(0~499)
**			uint32 sec2:终止扇区号,范围(0~499)
** 出口参数:操作成功则返回OK,失败则返回ERROR		
************************************************************************/
uint8 SSTF016B_Erase(uint32 sec1, uint32 sec2)
{
	uint8  temp1 = 0,temp2 = 0,StatRgVal = 0;
    uint32 SecnHdAddr = 0;	  			
	uint32 no_SecsToEr = 0;				   /*  要擦除的扇区数目    */
	uint32 CurSecToEr = 0;	  			   /* 当前要擦除的扇区号   */
	
	/*  检查入口参数 */
	if ((sec1 > SEC_MAX)||(sec2 > SEC_MAX))	
	{
		return (ERROR);	
	}
   	
   	CE_Low();			 
	Send_Byte(0x05);				  /*  发送读状态寄存器命令   */
	temp1 = Get_Byte();				  /*  保存读得的状态寄存器值  */
	CE_High();								

	CE_Low();			
	Send_Byte(0x50);				  /*  使状态寄存器可写        */
	CE_High();			
	CE_Low();								  	
	Send_Byte(0x01);				/*  发送写状态寄存器指令      */
	Send_Byte(0);					/*  清0BPx位,使Flash芯片全区可写  */ 
	CE_High();
	
	CE_Low();			
	Send_Byte(0x06);				/*  发送写使能命令             */
	CE_High();			

	/* 如果用户输入的起始扇区号大于终止扇区号,则在内部作出调整 */
	if (sec1 > sec2)
	{
	   temp2 = sec1;
	   sec1  = sec2;
	   sec2  = temp2;
	} 
	/* 若起止扇区号相等则擦除单个扇区 */
	if (sec1 == sec2)	
	{
	    SecnHdAddr = SEC_SIZE * sec1;		/*  计算扇区的起始地址       */
	    CE_Low();	
    	Send_Byte(0x20);				/*  发送扇区擦除指令         */
	    Send_Byte(((SecnHdAddr & 0xFFFFFF) >> 16)); /*  发送3个字节的地址信息    */
   		Send_Byte(((SecnHdAddr & 0xFFFF) >> 8));
   		Send_Byte(SecnHdAddr & 0xFF);
  		CE_High();			
		do
		{
		  	CE_Low();			 
			Send_Byte(0x05);		/*  发送读状态寄存器命令     */
			StatRgVal = Get_Byte();	        /*  保存读得的状态寄存器值    */
			CE_High();								
  		}
		while (StatRgVal == 0x03);		/*  一直等待,直到芯片空闲    */
		return (OK);			
	}
	
        /*  根据起始扇区和终止扇区间距调用最快速的擦除功能    */	
	
	if (sec2 - sec1 == SEC_MAX)	
	{
		CE_Low();			
		Send_Byte(0x60);			/*  发送芯片擦除指令(60h or C7h)  */
		CE_High();			
		do
		{
		  	CE_Low();			 
			Send_Byte(0x05);		/*  发送读状态寄存器命令      */
			StatRgVal = Get_Byte();		/*  保存读得的状态寄存器值    */
			CE_High();								
  		}
		while (StatRgVal == 0x03);		/*  一直等待,直到芯片空闲    */
   		return (OK);
	}
	
	no_SecsToEr = sec2 - sec1 +1;		       /*  获取要擦除的扇区数目       */
	CurSecToEr  = sec1;			       /*  从起始扇区开始擦除         */
	
	/* 若两个扇区之间的间隔够大,则采取16扇区擦除算法 */
	while (no_SecsToEr >= 16)
	{
	    SecnHdAddr = SEC_SIZE * CurSecToEr;		       /*  计算扇区的起始地址    */
	    CE_Low();	
	    Send_Byte(0xD8);				       /*  发送64KB块擦除指令     */
	    Send_Byte(((SecnHdAddr & 0xFFFFFF) >> 16));        /*  发送3个字节的地址信息  */
   		Send_Byte(((SecnHdAddr & 0xFFFF) >> 8));
   		Send_Byte(SecnHdAddr & 0xFF);
  		CE_High();			
		do
		{
		  	CE_Low();			 
			Send_Byte(0x05);		        /*  发送读状态寄存器命令     */
			StatRgVal = Get_Byte();		        /*  保存读得的状态寄存器值    */
			CE_High();								
  		}
		while (StatRgVal == 0x03);			/*  一直等待,直到芯片空闲    */
		CurSecToEr  += 16;				/*  计算擦除了16个扇区后,和擦除区域相邻的待擦除扇区号*/
		no_SecsToEr -=  16;				/*  对需擦除的扇区总数作出调整*/
	}
	/* 若两个扇区之间的间隔够大,则采取8扇区擦除算法 */
	while (no_SecsToEr >= 8)
	{
	    SecnHdAddr = SEC_SIZE * CurSecToEr;			/*  计算扇区的起始地址    */
	    CE_Low();	
	    Send_Byte(0x52);				        /*  发送32KB擦除指令      */
	    Send_Byte(((SecnHdAddr & 0xFFFFFF) >> 16));         /*  发送3个字节的地址信息  */
   		Send_Byte(((SecnHdAddr & 0xFFFF) >> 8));
   		Send_Byte(SecnHdAddr & 0xFF);
  		CE_High();			
		do
		{
		  	CE_Low();			 
			Send_Byte(0x05);			/*  发送读状态寄存器命令   */
			StatRgVal = Get_Byte();		        /*  保存读得的状态寄存器值  */
			CE_High();								
  		}
		while (StatRgVal == 0x03);		        /*  一直等待,直到芯片空闲   */	
		CurSecToEr  += 8;
		no_SecsToEr -=  8;
	}
	/* 采用扇区擦除算法擦除剩余的扇区 */
	while (no_SecsToEr >= 1)
	{
	    SecnHdAddr = SEC_SIZE * CurSecToEr;			/*  计算扇区的起始地址     */
	    CE_Low();	
    	Send_Byte(0x20);					/*  发送扇区擦除指令       */
	    Send_Byte(((SecnHdAddr & 0xFFFFFF) >> 16));         /*  发送3个字节的地址信息   */
   		Send_Byte(((SecnHdAddr & 0xFFFF) >> 8));
   		Send_Byte(SecnHdAddr & 0xFF);
  		CE_High();			
		do
		{
		  	CE_Low();			 
			Send_Byte(0x05);			/*  发送读状态寄存器命令  */
			StatRgVal = Get_Byte();			/*  保存读得的状态寄存器值 */
			CE_High();								
  		}
		while (StatRgVal == 0x03);			/*  一直等待,直到芯片空闲  */
		CurSecToEr  += 1;
		no_SecsToEr -=  1;
	}
/*  擦除结束,恢复状态寄存器信息	 */
	CE_Low();			
	Send_Byte(0x06);					/*  发送写使能命令         */
	CE_High();			

	CE_Low();			
	Send_Byte(0x50);					/*  使状态寄存器可写        */
	CE_High();			
	CE_Low();			
	Send_Byte(0x01);					/* 发送写状态寄存器指令  */
	Send_Byte(temp1);					/* 恢复状态寄存器设置信息    */
	CE_High();    
	return (OK);
}



























⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -