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

📄 sst_spi_w25x.c

📁 大容量Flash存储器W25X16,W25X32,W25X64读写擦除程序
💻 C
字号:
/****************************************************************************/

/****************************************************************************/
#include <SST89x5xxRD2.H>
#include <W25X.H>
#include <intrins.h>

#define	SST_SPI

extern	uint8 upper_128[16];
extern	uint8 tx_buff[16];
//=================================================================================================
void	delay_nms(uchar i)
{	uchar  j;
	i=i*2;
	for(;i>0;i--)	{   j = 246;	while(--j);	}
}
void	delay(uchar tt)
{	while(tt--);}
//=================================================================================================
//SPI_Read_StatusReg		Reads the status register of the serial flash
//SPI_Write_StatusReg		Performs a write to the status register
//SPI_Write_Enable			Write enables the serial flash
//SPI_Write_Disable			Write disables the serial flash
//SPI_Read_ID1				Reads the device ID using the instruction 0xAB
//SPI_Read_ID2				Reads the manufacturer ID and device ID with 0x90
//SPI_Read_ID3()			Reads the JedecDevice ID
//SPI_Read_Byte				Reads one byte from the serial flash and returns byte(max of 20 MHz CLK frequency)
//SPI_Read_nBytes			Reads multiple bytes(max of 20 MHz CLK frequency)
//SPI_FastRead_Byte			Reads one byte from the serial flash and returns byte(max of 33 MHz CLK frequency)
//SPI_FastRead_nBytes		Reads multiple bytes(max of 33 MHz CLK frequency)
//SPI_Write_Byte			Program one byte to the serial flash
//SPI_Write_nBytes			Program n bytes to the serial flash, n<=256
//SPI_Erase_Chip			Erases entire serial flash
//SPI_Erase_Sector			Erases one sector (64 KB) of the serial flash
//SPI_Wait_Busy				Polls status register until busy bit is low
//=================================================================================================
uchar	SPI_Read_StatusReg()
{	uchar byte = 0;
	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_ReadStatusReg);		//	send Read Status Register command
	byte = SPI_Get_Byte();					//	receive byte
	W25X_CS = 1;							//	disable device	
	return byte;
}
void	SPI_Write_StatusReg(byte)
{	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_WriteStatusReg);		//	select write to status register
	SPI_Send_Byte(byte);					//	data that will change the status(only bits 2,3,7 can be written)
	W25X_CS = 1;							//	disable the device
}
void	SPI_Write_Enable()
{	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_WriteEnable);		//	send W25X_Write_Enable command
	W25X_CS = 1;							//	disable device
}
void	SPI_Write_Disable()
{	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_WriteDisable);		//	send W25X_WriteW25X_DIsable command
	W25X_CS = 1;							//	disable device
}
uchar	SPI_Read_ID1()
{	uchar byte;
	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_DeviceID);			//	send read device ID command (ABh)
    SPI_Send_Byte(0);						//	send address
	SPI_Send_Byte(0);						//	send address
	SPI_Send_Byte(0);						//	send 3_Dummy address
	byte = SPI_Get_Byte();					//	receive Device ID byte	
	W25X_CS  = 1;							//	disable device
	delay(4);								//	remain CS high for tRES2 = 1.8uS
	return byte;
}
uint	SPI_Read_ID2(uchar ID_Addr)
{	uint IData16;
	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_ManufactDeviceID);	//	send read ID command (90h)
    SPI_Send_Byte(0x00);					//	send address
	SPI_Send_Byte(0x00);					//	send address
	SPI_Send_Byte(ID_Addr);					//	send W25Pxx selectable ID address 00H or 01H
	IData16 = SPI_Get_Byte()<<8;			//	receive Manufature or Device ID byte
	IData16 |= SPI_Get_Byte();				//	receive Device or Manufacture ID byte
	W25X_CS = 1;							//	disable device	
	return IData16;
}
uint	SPI_Read_ID3()
{	uint IData16;
	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_JedecDeviceID);		//	send read ID command (9Fh)
	IData16 = SPI_Get_Byte()<<8;			//	receive Manufature or Device ID byte
	IData16 |= SPI_Get_Byte();				//	receive Device or Manufacture ID byte
	tx_buff[2] = SPI_Get_Byte();	
	W25X_CS = 1;							//	disable device	
	return IData16;
}
uchar	SPI_Read_Byte(uint32 Dst_Addr) 
{	uchar byte = 0;	
	W25X_CS = 0;										//	enable device
	SPI_Send_Byte(W25X_ReadData);						//	read command
	SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFFFF) >> 16));//	send 3 address bytes
	SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFF) >> 8));
	SPI_Send_Byte((uchar)(Dst_Addr & 0xFF));
	byte = SPI_Get_Byte();
	W25X_CS = 1;										//	disable device	
	return byte;										//	return one byte read
}
void	SPI_Read_nBytes(uint32 Dst_Addr, uchar nBytes_128)
{	uint32 i = 0;	
	W25X_CS = 0;										//	enable device
	SPI_Send_Byte(W25X_ReadData);						//	read command
	SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));		//	send 3 address bytes
	SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
	SPI_Send_Byte(Dst_Addr & 0xFF);
	for (i = 0; i < nBytes_128; i++)					//	read until no_bytes is reached
		upper_128[i] = SPI_Get_Byte();					//	receive byte and store at address 80H - FFH
	W25X_CS = 1;										//	disable device
}
uchar	SPI_FastRead_Byte(uint32 Dst_Addr) 
{	uchar byte = 0;
	W25X_CS = 0;										//	enable device
	SPI_Send_Byte(W25X_FastReadData);					//	fast read command
	SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));		//	send 3 address bytes
	SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
	SPI_Send_Byte(Dst_Addr & 0xFF);
	SPI_Send_Byte(0xFF);								//	dummy byte
	byte = SPI_Get_Byte();
	W25X_CS = 1;										//	disable device	
	return byte;										//	return one byte read
}
void	SPI_FastRead_nBytes(uint32 Dst_Addr, uchar nBytes_128)
{	uchar i = 0;	
	W25X_CS = 0;										//	enable device
	SPI_Send_Byte(W25X_FastReadData);					//	read command
	SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));		//	send 3 address bytes
	SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
	SPI_Send_Byte(Dst_Addr & 0xFF);
	SPI_Send_Byte(0xFF);								//	dummy byte
	for (i = 0; i < nBytes_128; i++)					//	read until no_bytes is reached
		upper_128[i] = SPI_Get_Byte();					//	receive byte and store at address 80H - FFH
	W25X_CS = 1;										//	disable device
}
void	SPI_Write_Byte(uint32 Dst_Addr, uchar byte)
{	W25X_CS = 0;									//	enable device
	SPI_Write_Enable();								//	set WEL
	SPI_Wait_Busy();	
	W25X_CS = 0;	
	SPI_Send_Byte(W25X_PageProgram);				//	send Byte Program command
	SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));	//	send 3 address bytes
	SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
	SPI_Send_Byte(Dst_Addr & 0xFF);
	SPI_Send_Byte(byte);							//	send byte to be programmed
	W25X_CS = 1;									//	disable device
}
void	SPI_Write_nBytes(uint32 Dst_Addr, uchar nBytes_128)
{	
	uchar i, byte;	
	W25X_CS = 0;					/* enable device */
	SPI_Write_Enable();				/* set WEL */
	W25X_CS = 0;
	SPI_Send_Byte(W25X_PageProgram); 		/* send Byte Program command */
	SPI_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));	/* send 3 address bytes */
	SPI_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
	SPI_Send_Byte(Dst_Addr & 0xFF);
	
	for (i = 0; i < nBytes_128; i++)
	{
		byte = upper_128[i];
		SPI_Send_Byte(byte);		/* send byte to be programmed */
	}	
	W25X_CS = 1;				/* disable device */
}
void	SPI_Erase_Chip()
{
	W25X_CS = 0;										//	enable device
	SPI_Write_Enable();									//	set WEL
	W25X_CS = 0;
	SPI_Wait_Busy();
	W25X_CS = 0;
	SPI_Send_Byte(W25X_ChipErase);						//	send Chip Erase command
	W25X_CS = 1;										//	disable device
}
void	SPI_Erase_Sector(uint32 Dst_Addr)
{	W25X_CS = 0;										//	enable device
	SPI_Write_Enable();									//	set WEL
	W25X_CS = 0;
	SPI_Send_Byte(W25X_SectorErase);					//	send Sector Erase command
	SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFFFF) >> 16));//	send 3 address bytes
	SPI_Send_Byte((uchar)((Dst_Addr & 0xFFFF) >> 8));
	SPI_Send_Byte((uchar)Dst_Addr & 0xFF);
	W25X_CS = 1;										//	disable device
}
void	SPI_Wait_Busy()
{	while (SPI_Read_StatusReg() == 0x03)
		SPI_Read_StatusReg();				//	waste time until not busy WEL & Busy bit all be 1 (0x03)
}
void	SPI_PowerDown()
{	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_PowerDown);			//	send W25X_PowerDown command 0xB9
	W25X_CS = 1;							//	disable device
	delay(6);								//	remain CS high for tPD = 3uS
}
void	SPI_ReleasePowerDown()
{	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_ReleasePowerDown);	//	send W25X_PowerDown command 0xAB
	W25X_CS = 1;							//	disable device
	delay(6);								//	remain CS high for tRES1 = 3uS
}

#ifdef	SST_SPI
void	SPI_init()
{	P1 = 0xFF;
	SPCR = 0x50;
}
void	SPI_Send_Byte(uchar out)
{	unsigned char temp;
	SPDR = out;
	do	{	temp = SPSR & 0x80;	}	while (temp != 0x80);
	SPSR = SPSR & 0x7F;
}
uchar	SPI_Get_Byte()
{	unsigned char temp;
	SPDR = 0x00;
	do	{	temp = SPSR & 0x80;	}	while (temp != 0x80);
	SPSR = SPSR & 0x7F;
	return SPDR;
}
#endif

#ifndef	SST_SPI
void	SPI_init()
{	W25X_CLK = 0;							//	set clock to low initial state for SPI operation mode 0
//	W25X_CLK = 1;							//	set clock to High initial state for SPI operation mode 3
//	_hold = 1;
	W25X_WP = 1;
	W25X_CS = 1;	
	SPI_Write_Disable();	
}
void	SPI_Send_Byte(uchar out)
{	uchar i = 0;	
	for (i = 0; i < 8; i++)
	{	if ((out & 0x80) == 0x80)			//	check if MSB is high
			W25X_DI = 1;
		else
			W25X_DI = 0;					//	if not, set to low
		W25X_CLK = 1;						//	toggle clock high
		out = (out << 1);					//	shift 1 place for next bit
		nop();nop();nop();nop();
		W25X_CLK = 0;						//	toggle clock low
	}
}
uchar	SPI_Get_Byte()
{	uchar i = 0, in = 0, temp = 0;	
	for (i = 0; i < 8; i++)
	{	in = (in << 1);						//	shift 1 place to the left or shift in 0
		temp = W25X_DO;						//	save input
		W25X_CLK = 1;						//	toggle clock high
		if (temp == 1)						//	check to see if bit is high
			in |= 0x01;						//	if high, make bit high
		W25X_CLK = 0;						//	toggle clock low
	}	
	return in;
}
#endif
//=================================================================================================

⌨️ 快捷键说明

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