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

📄 spidrv_p1.c

📁 大容量Flash存储器W25X16,W25X32,W25X64读写擦除程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************/
/*     深圳恒森微电子有限公司  (华邦单片机香港及中国区代理商)		        */
/*     香港恒森科技有限公司    (华邦单片机香港及中国区代理商)		        */
/*     陈文    email:chenwen@hengsen.cn (有 bug 请提交)                   */
/****************************************************************************/
/*  文件名:	spidrv.c														*/
/*	版本					1.0												*/
/*  创建日期:				2007-10-29 10:58								*/
/*  概述:	本文件为 w79e823   读写 SPI flash程序							*/
/*--------------------------------------------------------------------------*/
/*  历史修改记录:															*/
/*  名字                   日期                   注释						*/
/*  陈文                   2007.10.28           ver 1.0						*/
/****************************************************************************/
#include <SST89x5xxRD2.H>
#include <intrins.h>
#define uint8 unsigned char
#define uint16 unsigned int
#define uchar unsigned char
#define uint unsigned int
#define uint32 unsigned long

sbit	W25X_WP	= P1^3;
sbit	W25X_CS	= P1^4;
sbit	W25X_DO	= P1^5;
sbit	W25X_DI	= P1^6;
sbit	W25X_CLK= P1^7;


#define W25X_WriteEnable		0x06
#define W25X_WriteDisable		0x04
#define W25X_ReadStatusReg		0x05
#define W25X_WriteStatusReg		0x01
#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

	
void	init_cpu(void);
void	delay(uchar tt);
void	trace(uchar *str,uchar len);
void	test_page(uchar addr);
void	read_page(uchar addr);
void	Verify(uchar byte, uchar cor_byte);

void	SPI_init();

void	SPI_Send_Byte(uchar out);
uchar	SPI_Get_Byte();
void	SPI_Wait_Busy();

uchar	SPI_Read_StatusReg();
void	SPI_Write_StatusReg(byte);
void	SPI_Write_Enable();
void	SPI_PowerDown();
void	SPI_ReleasePowerDown();

uchar	SPI_Read_Byte(uint32 Dst_Addr);
void	SPI_Read_nBytes(uint32 Dst_Addr, uchar nBytes_128);
uchar	SPI_FastRead_Byte(uint32 Dst_Addr);
void	SPI_FastRead_nBytes(uint32 Dst_Addr, uchar nBytes_128);

void	SPI_Write_Byte(uint32 Dst_Addr, uchar byte);
void	SPI_Write_nBytes(uint32 Dst_Addr, uchar nBytes_128);
void	SPI_WriteW25X_Disable();

void	SPI_Erase_Chip();
void	SPI_Erase_Sector(uint32 Dst_Addr);

uchar	SPI_Read_ID1();
uint	SPI_Read_ID2(uchar ID_Addr);
uint	SPI_Read_ID3();



uint8 Rxtemp;
bit MYTI;
uint8 tx_buff[16];
uint8 upper_128[16];
bit rx_ok;
#define nop() _nop_()

void delay_nms(uchar i)
{	uchar  j;
	i=i*2;
	for(;i>0;i--)	{   j = 246;	while(--j);	}
}

void main(void)
{	uint i;
	
	init_cpu();	
	SPI_init();

	tx_buff[0]='O';
	tx_buff[1]='K';
	trace(tx_buff,2);

	for(;;)
	{	if(rx_ok == 1)
		{	rx_ok = 0;
			switch(Rxtemp)
			{	case 0x01:
					Rxtemp = 0;
					tx_buff[0] = SPI_Read_ID1();
					trace(tx_buff,1);
					break;
				case 0x02:
					i = SPI_Read_ID2(0x00);
					tx_buff[1] = (uchar)i;
					tx_buff[0] = (uchar)(i>>8);
					trace(tx_buff,2);
					break;
				case 0x03:
					i = SPI_Read_ID3();
					tx_buff[1] = (uchar)i;
					tx_buff[0] = (uchar)(i>>8);
					trace(tx_buff,3);
					break;
				case 0x04:
					tx_buff[0] = SPI_Read_Byte(0x00000000);
					trace(tx_buff,1);
					break;
				case 0x05:
					tx_buff[0] = 0x55;
					SPI_Write_Byte(0x00000000,0xa5);
					trace(tx_buff,1);
					break;
				case 0x06:
					tx_buff[0] = SPI_Read_StatusReg();
					trace(tx_buff,1);
					break;
				case 0x07:
					SPI_Write_Enable();	
					break;
				case 0x08:
					upper_128[0]=0x01;upper_128[1]=0x02;upper_128[2]=0x03;upper_128[3]=0x04;
					SPI_Write_nBytes(0x00000000,4);
					break;
				case 0x09:
					SPI_Erase_Chip();
					break;
				case 0x0a:
					SPI_Erase_Sector(0x000ff000);
					while(1)
					{	tx_buff[0] = SPI_Read_StatusReg();
						if(tx_buff[0] == 0)
						{	trace(tx_buff,1);
							break;
						}
					}
					break;
				case 0x0b:
					test_page(0x00);
					break;
				case 0x0c:
					read_page(0x00);
					break;
				default:
					break;
			}			
		}			
	}
}

void init_cpu(void)
{	TMOD = 0x21;			
	PCON = PCON | 0x80;		//波特率加倍
	SCON  = 0x50;			//异步、10位、波特率可变,无校验位
	TH1   = 0xfd;            //在11.0592M晶振下,波特率是9600,
    TL1   = 0xfd;			
    TR1   = 1;  			//T1 timer run
    ES    = 1;				//uart interrupt enable	
	EA = 1;					//all interrupt enable
}
//串口中断程序
void UART_isr(void) interrupt 4
{ 
	if(RI)
    {
        RI = 0;
        Rxtemp = SBUF;   //接收
        //SBUF = Rxtemp; 	 //发送
        rx_ok = 1;
		return;
	}
	if(TI)
	{
		TI = 0;
		MYTI = 1;		
 	}
}

void SPI_Send_Byte(uchar out)
{
	uchar i = 0;	
	W25X_CS = 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;	
	W25X_CS = 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;
}
//=================================================================================================
void delay(uchar tt)
{
	while(tt--);
}
//=================================================================================================
void SPI_Wait_Busy()
{
/* 	waste time until not busy WEL & Busy bit all be 1 (0x03).	*/
	while (SPI_Read_StatusReg() == 0x03)
		SPI_Read_StatusReg();
}
//=================================================================================================
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_WriteW25X_Disable();	
}
//=================================================================================================
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_PowerDown()
{	W25X_CS = 0;							//	enable device
	SPI_Send_Byte(W25X_PowerDown);			//	send W25X_PowerDown command 0xB9

⌨️ 快捷键说明

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