C51读写W25Q测试通过

电路:
C51读写W25Q测试通过_第1张图片
C51读写W25Q测试通过_第2张图片
最简单粗暴的:

//管脚定义
sbit fwcs   =P1^7;
sbit fwsck  =P5^4;
sbit fwsi   =P5^5;
sbit fwso   =P1^6;

//spi模拟写
void w25wspi(uchar dat)
{
	uchar i;
	for(i=0;i<8;i++)
	{
		if(dat & 0x80)
		{
			fwso=1;
		}
		else
		{
			fwso=0;
		}
		fwsck=1;
		dat=dat<<1;
		fwsck=0;
	}
	fwso=1;
	fwsck=0;
}
//spi模拟读
uchar w25rspi()
{
	uchar i;
	uchar rs;
	
	for(i=0;i<8;i++)
	{
		fwsck=0;
		rs=rs<<1;
		if(fwsi)
			rs=rs | 1;
		fwsck=1;
	}
	fwsck=0;
	return rs;
}
//双倍速读
uchar w25frspi()
{
	uchar i;
	uchar rs;
	for(i=0;i<4;i++)
	{
		rs=rs<<2;
		fwsck=0;
		if(fwsi)
			rs=rs | 0x02;
		if(fwso)
			rs=rs | 0x01;
		fwsck=1;
	}
	fwso=1;
	fwsck=0;
	return rs;
}


//读取状态寄存器1
uchar readrs1()
{
	uchar rs;
	fwcs=0;
	w25wspi(ReadStatusRegister1);
	rs=w25rspi();
	fwcs=1;
	return rs;
}

//读取状态寄存器2
uchar readrs2()
{
	uchar rs;
	fwcs=0;
	w25wspi(ReadStatusRegister2);
	rs=w25rspi();
	fwcs=1;
	return rs;
}

//读取状态寄存器3
uchar readrs3()
{
	uchar rs;
	fwcs=0;
	w25wspi(ReadStatusRegister3);
	rs=w25rspi();
	fwcs=1;
	return rs;
}
//初始化
void init_w25q128()
{
	int i,j;
	P1M1 = 0xC0;  //开漏 1.6 、1.7
	P1M0 = 0xC0;  //开漏
	P5M1 = 0x30;  //开漏 5.4 、5.5
	P5M0 = 0x30;  //开漏
	fwcs=1;
	fwso=1;
	fwsck=0;
	//fwrst=1;
	for(j=0;j<200;j++)
	{
		for(i=0;i<200;i++);
	}
	reset_w25q128();
}


//复位w25q128
void reset_w25q128()
{
	uchar i;
	fwcs=0;
	w25wspi(EnableReset);
	fwcs=1;
	for(i=0;i<100;i++);
	fwcs=0;
	w25wspi(ResetDevice);
	fwcs=1;
	for(i=0;i<240;i++);
}

//读取数据
//buf:读出数据缓冲区f
//black_numb:块号
//page_numb:页号
//len:读取长度为 len+1,最多读256个字节
//成功返回 1,失败返回 0
uchar readdata(uchar * buf,uchar block_numb,uchar page_numb,uchar len)
{
	uchar i,j;
	uchar rs[4];
	
	i=BUSY;
	j=0;
	//是否忙
	while(i==BUSY)
	{
		fwcs=0;
		w25wspi(ReadStatusRegister1);
		i=w25rspi();
		fwcs=1;
		i=i & BUSY;
		ms1(1);
		j++;
		if(j==128)
			return 0;
	}
	
	rs[0]=ReadData;
	rs[1]=block_numb;
	rs[2]=page_numb;
	rs[3]=0;
	
	fwcs=0;
	for(i=0;i<4;i++)
	{
		w25wspi(rs[i]);
	}
	for(i=0;i

/头文件*******

#ifndef	_W25Q128_H_
#define	_W25Q128_H_

#include "STC8.H"

#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long

//------------------------命令段----------------------------
#define WriteEnable                  0x06    //写使能
#define WriteEnableVolatile          0x50    //易失性寄存器写使能
#define WriteDisable                 0x04    //写禁止
#define ReadStatusRegister1          0x05    //读状态寄存器1
#define ReadStatusRegister2          0x35    //读状态寄存器2
#define ReadStatusRegister3          0x15    //读状态寄存器3
#define WriteStatusRegister1         0x01    //写状态寄存器1
#define WriteStatusRegister2         0x31    //写状态寄存器2
#define WriteStatusRegister3         0x11    //写状态寄存器3
#define ReadData                     0x03    //读数据
#define PageProgram                  0x02    //页编程
#define SectorErase64k               0xd8    //扇区擦除
#define ChipErase                    0xc7    //芯片擦除
#define ReadUniqueIDNumber           0x4b    //读取唯一设备号
#define ReadSFDPRegister             0x5a    //读sfpd寄存器
#define EraseSecurityRegisters       0x44    //擦除安全寄存器
#define ProgramSecurityRegisters     0x42    //安全寄存器编程
#define ReadSecurityRegisters        0x48    //读取安全寄存器
#define IndividualBlockSectorLock    0x36    //单个块/扇区锁定
#define IndividualBlockSectorUnlock  0x39    //单个块/扇区解锁
#define ReadBlockSectorLock          0x3d    //读取单个块/扇区锁
#define GlobalBlockSectorLock        0x7e    //全局加锁
#define GlobalBlockSectorUnlock      0x98    //全局解锁
#define EnableReset                  0x66    //复位使能
#define ResetDevice                  0x99    //系统复位
#define FastReadData                 0x3b    //快速读取

//-----------------------------状态----------------------------------
#define BUSY              0x01   //W25Q128工作状态
#define WEL               0X02   //W25Q128写使能位

void ms1(uchar time);

void init_w25q128();  //加载W25Q128
void reset_w25q128();  //复位W25q128

uchar readrs1();
uchar readrs2();
uchar readrs3();

//读取数据
//buf:读出数据缓冲区f
//black_numb:块号
//page_numb:页号
//len:读取长度为 len+1,最多读256个字节
//成功返回 1,失败返回 0
uchar readdata(uchar * buf,uchar block_numb,uchar page_numb,uchar len);
uchar fastreaddata(uchar * buf,uchar block_numb,uchar page_numb,uchar len);

//块擦除命令
//block_numb:块号
//成功返回 1,失败返回 0
uchar eraseblock(uchar block_numb);

//页编程
//buf:要写入数据
//black_numb:块号
//page_numb:页号
//len:编程长度为 len+1,最写入256个字节
//成功返回 1,失败返回 0
uchar pageprogramblock(uchar * buf,uchar block_numb,uchar page_numb,uchar len);

void sendchr(uchar a1);

#endif

你可能感兴趣的:(C51)