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

📄 main.c

📁 25aa320 SPI串行eeprom的烧写程序
💻 C
字号:
#include <atmel\REG2051.H>
#include <INTRINS.H>

//引脚定义,可以自行定义使用
#define IC_P1		P1_1  //cs
#define IC_P2		P1_2  //sk
#define IC_P3		P1_3  //DI
#define IC_P4		P1_4  //DO
#define IC_P5		P1_5  //GND
#define IC_P6		P1_6  //nc
#define IC_P7		P1_7  //nc
#define LED			P3_7  //VCC

/*这个需要改,因为25xx320指令不一样
#define EWEN	0x98
#define ERAL	0x90
#define EWDS	0x80 //93CXX用 0x98 EWEN写允许 0x80EWDS写禁止 0x90擦除
*/
#define EWEN	0x06  //0x06  WREN写允许  25XX用
//#define ERAL	0x90  //0x90擦除,25XX没有这个
#define EWDS	0x04  //0x04  WRDI写禁止 


static unsigned char Pack[4]; //数据包数组
static unsigned char PN = 0; //接收指针


void InitCom(void);                         //串口初始化 晶振为11.0592M 方式1 波特率57600
//void InitIC(void);                          
void ComOutChar(unsigned char OutData);     //向串口输出一个字符(非中断方式)
void Init_93C(void);                        //引脚初始化
void Read_93C(unsigned char AH,AL);         //读
void Write_93C(unsigned char AH,AL,Data);   //写
void COM_93C(unsigned char Data);           //93C命令函数
void Erasure_93C(void);                     //擦除

void main(void)
{
	unsigned int TempCyc;

	InitCom();

	while(1)
	{						
		for (TempCyc=0; TempCyc<30000; TempCyc++) //状态灯闪
			LED = 1;
		for (TempCyc=0; TempCyc<20000; TempCyc++)
			LED = 0;
	}
}

//串口初始化 晶振为11.0592M 方式1 波特率57600
void InitCom(void)
{
	SCON = 0x50; //串口方式1,允许接收
	TMOD = 0x21; //定时器1定时方式2,定时0为模式1,16位模式
	TCON = 0x40; //设定时器1开始计数
	TH1 = 255;	//设波特率为57600
	TL1 = 255;
	PCON = 0x80; //波特率加倍控制,SMOD位
	RI = 0;	//清收发标志
	TI = 0;
	TR1 = 1; //启动定时器
	EA = 1; //开总中断
	ES = 1; //开串口中断
}

//向串口输出一个字符(非中断方式)
void ComOutChar(unsigned char OutData)
{
	SBUF = OutData; //输出字符
	while(!TI); //空语句判断字符是否发完
	TI = 0; //清TI
}

//串口接收中断
void ComInINT(void) interrupt 4
{
	if (RI) //判断是不是收完字符
		{
			RI = 0; //RI清零
			Pack[PN] = SBUF; //存数据
			PN++;  //指针加1
			if (PN == 4)
				{
					PN = 0; //指针清零 一帧数据收完后
					switch (Pack[0])
						{
							case 0: Read_93C(Pack[1],Pack[2]); break;
							case 1: Write_93C(Pack[1],Pack[2],Pack[3]); break;
							case 2: Erasure_93C(); break; 
						}		
				}
		}

}

////////MicroWire 93CXX芯片函数////////////////
////////SPI 25XX320芯片函数////////////////
//引脚初始化
void Init_93C(void)
{
	IC_P5 = 0; //GND
	IC_P1 = 0; //CS
	IC_P2 = 0; //SK
	IC_P3 = 0; //DI
	IC_P4 = 1; //DO 置1让MCU为可读
	IC_P6 = 0; //选择为8位数据模式
	IC_P7 = 0; //
}

//93C命令函数
void COM_93C(unsigned char Data)
{
	unsigned char TempCyc;
	unsigned int  TempCycB;

	TempCycB = Data;   //Data: 0x98 EWEN写允许 0x80EWDS写禁止 0x90擦除

	Init_93C();        //初始化引脚 

	IC_P1 = 1;         //CS
//	for(TempCyc=10; TempCyc!=0; TempCyc--)	//94C64的8位模式起始位+命令代码+地址位是共10位
    for(TempCyc=8; TempCyc!=0; TempCyc--)	//25XX320 SI 数据
	{
		IC_P3 = Data & 0x80; //数据 DI
  	        IC_P2 = 1; //SK
		_nop_();
		IC_P2 = 0; //时钟 /SK
		Data <<= 1; //左移
	}

	IC_P1 = 0;	//CS

	if (TempCycB==ERAL) //擦除命令
		{
			IC_P2 = 1; //SK	
			_nop_();
			IC_P2 = 0; //SK
			IC_P1 = 1; //CS
			_nop_();
			for (TempCycB=0; TempCycB<0xFFFF; TempCycB++)
				{
					IC_P2 = 1;
					_nop_();
					_nop_();
					IC_P2 = 0;
					if (IC_P4) 
						{
							break; //检测就绪信号
						}
				}
			IC_P1 = 0;
			if (TempCycB!=0)
				ComOutChar(0); //成功返回0
			else
				ComOutChar(1); //失败返回1
		}
}

//擦除
void Erasure_93C(void)
{
	COM_93C(EWEN);
//	COM_93C(ERAL);
Write_93C(0x00,0x00,0xFF);

	COM_93C(EWDS);
}

//写
void Write_93C(unsigned char AH,AL,SData)
{
	unsigned int Data=0, TempCycB;

	COM_93C(EWEN); //写允许
	
	Init_93C();
	
	IC_P1 = 1; //CS			
			
	Data = AH*0x100+AL;
//	Data = Data<<6; //地址组合、移动
//	Data |= 0xA000; //加上起始位和操作码
	for(TempCycB=16; TempCycB!=0; TempCycB--) //发送地址码
		{
			IC_P3 = Data & 0x8000; //数据 DI
			IC_P2 = 1; //SK
			_nop_();
			IC_P2 = 0; //时钟 /SK
			Data <<= 1; //左移
		}
			
	Data = SData*0x100; //数据

	for(TempCycB=8; TempCycB!=0; TempCycB--) //发送8位数据
		{
			IC_P3 = Data & 0x8000; //数据 DI
			IC_P2 = 1; //SK
			_nop_();
			IC_P2 = 0; //时钟 /SK
			Data <<= 1; //左移
		}
		
	IC_P1	=	0;	//CS
			
	IC_P2 = 1; //SK	
	_nop_();
	IC_P2 = 0; //SK
	IC_P1 = 1; //CS
	_nop_();
	for (TempCycB=0; TempCycB<0xFFFF; TempCycB++)
		{
			IC_P2 = 1;
			_nop_();
			_nop_();
			IC_P2 = 0;
			if (IC_P4) 
				{
					break; //检测就绪信号
				}
		}
	if (TempCycB!=0)  //当TempCycB=0说明没有出现过BUY
		ComOutChar(0); //成功返回
	else
		ComOutChar(1); //失败返回1

	COM_93C(EWDS); //写禁止
}

//读
void Read_93C(unsigned char AH,AL)
{
	unsigned char TempCycB;
	unsigned int Data=0;

	Init_93C();

	IC_P1 = 1; //CS			
			
	Data = AH*0x100+AL;
//	Data = Data<<6; //地址组合、移动
//	Data |= 0xC000; //加上起始位和操作码
	for(TempCycB=8; TempCycB!=0; TempCycB--) //地址码
		{
			IC_P3 = Data & 0x8000; //数据 DI
			IC_P2 = 1; //SK
			_nop_();
			IC_P2 = 0; //时钟 /SK
			Data <<= 1; //左移
		}
		
	for(TempCycB=0; TempCycB<8; TempCycB++) //读数据
		{
			IC_P2 = 1; //SK
			_nop_();
			_nop_();
			Pack[3] = Pack[3] << 1;
			if (IC_P4)
				Pack[3]++;
			IC_P2 = 0; //时钟 /SK1
		}
	IC_P1	=	0;	//CS

	ComOutChar(Pack[3]); //返回
}


void WIPCHK(void) //reentrant //检查WIP位,判断是否写入完成
{
unsigned char Temp,TempCyc;

for(TempCyc=0;TempCyc<50;TempCyc++)
{
Temp = RSDR(); //读状态寄存器
if (Temp&0x01==0)
TempCyc = 50; 
}
}

⌨️ 快捷键说明

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