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

📄 eeprom.c

📁 这是我在单片机c8051f020下写的SST 29LE020这款flash的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* unless preceded by the three Byte-Load sequence.						      */
/*												      */
/* Input:								   			      */
/*           None										      */
/*									                     	      */
/* Output:								          		      */
/*           None										      */
/******************************************************************************************************/

void Enable_Chip_Data_Protection()
{
	UINT8 xdata *Temp;
	AreaSelect&=0xf0;
	AreaSelect|=1;
	Temp  = (UINT8 xdata *)0x5555;			/* set up address to be C000:5555h	*/
	*Temp = 0xAA;					/* write data 0xAA to the address	*/
	AreaSelect&=~1;
	Temp  = (UINT8 xdata *)0x6AAA;			/* set up address to be C000:2AAAh	*/
	*Temp = 0x55;					/* write data 0x55 to the address	*/
	AreaSelect|=1;
	Temp  = (UINT8 xdata *)0x5555;			/* set up address to be C000:5555h	*/
	*Temp = 0xA0;					/* write data 0xA0 to the address	*/

	delay(10);
}


void SYSCLK_Init (void)
{
	int i;	

	WDTCN = 0xde;                       // disable watchdog timer
	WDTCN = 0xad;	
	
	OSCXCN = 0x67;                      // start external oscillator with 22.1184MHz crystal
	
	for (i=0; i < 256; i++) ;           // XTLVLD blanking interval (>1ms)
	
	while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle
	
	OSCICN = 0x88;                      // select external oscillator as SYSCLK source and enable missing clock detector
	
//	OSCICN = 0x97;                     //// select internal oscillator as SYSCLK
}

void eeprom_Init(void)
{
	EMI0CF = 0x29;         //地址复用方式,带块选择的分片方式,使用P4~P7端口
//	EMI0CN = 0x40;         //给出地址总线高8位
	EMI0TC = 0x4A;         //时序控制寄存器设置

	P74OUT = 0xff;
	XBR2 = 0x40;		   //弱上拉,允许交叉开关

	DATA=0x00;
	ADDR=0x40;
	AreaSelect=0xC0;       //RD,WR='1',ALE='0'
}

 void eepromErase()
 {
 	 AreaSelect =0x61;	/* WR='0', RD='1',ALE='1',片选为1 */	 
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0xAA;
	 AreaSelect = 0x60;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x2AAA) = 0x55;
	 AreaSelect = 0x61;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0x80;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0xAA;
 	 AreaSelect = 0x60;
	 *(UINT8 xdata *)(Base_ROM_ADD + 0x2AAA) = 0x55;
	 AreaSelect =0x61;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0x10;
	 delay(20);
 }

//eeprom读函数,offset为偏移量,返回读出的值
UINT8 eeprom_ReadByte(UINT8 blocknum,UINT16 offset)
{
	UINT8 result;
	UINT8 xdata *addr;
	AreaSelect = (UINT8)(blocknum|0xA0);
//	addr=(UINT16 *)(Base_ROM_ADD + (UINT16)offset);
//	DATA = (Base_ROM_ADD + (UINT16)offset)&&0x00ff;
//	ADDR  = ((Base_ROM_ADD + (UINT16)offset)>>8)&& 0x00ff; 	
//	AreaSelect |= 0x20;         //ALE置1,锁存该地址
//	AreaSelect &= 0x9f;         //ALE清零,RD='0',读选通
	addr=(UINT8 xdata *)(Base_ROM_ADD + offset);
	result= *addr;
	return result;
//	AreaSelect |= 0xd0;         //RD='1'
}

//eeprom写函数,datas为写入值
bool eeprom_Writepage(UINT8 blocknum,UINT16 offset,UINT16 number,UINT8* datas)
{
	volatile UINT8 tmp=0;
	UINT8* xdata addr;
	volatile UINT8 leftnum=0;
	
	if(number==0)
		return 1;
//	eeprom_Unlock();
//	delay(100);
	
	
	addr=(UINT8 xdata *)(Base_ROM_ADD+offset);
	leftnum=EEPROMPAGE-number;
	eeprom_Lock();
	AreaSelect = (UINT8)(blocknum|0x60);
	for(tmp=0;tmp<number;tmp++)
	{	
		*addr++=datas[tmp];
	}
	if(number<EEPROMPAGE)
	{
		for(tmp=0;tmp<leftnum;tmp++)
		{
			*addr++=0;
		}
	}

	/* loop read until is sticks */
	delay(100);
//	eeprom_Unlock();
	
//	DATA = ((Base_ROM_ADD + (INT16)offset))&&0x00ff;
//	ADDR  = ((Base_ROM_ADD + (INT16)offset)>>8)&& 0x00ff; 	
//	AreaSelect |= 0x20;         //ALE置1,锁存该地址
//	AreaSelect &= 0x5f;         //ALE清零,WR='0',写选通
	
//	*addr=datas;
//	AreaSelect |= 0xd0;         //WR='1'
/*
	while((eeprom_ReadByte(blocknum,offset))!=datas && i<10)
	{
		i++;
		delay(10);
    }
	if(i<10) return 1;
	else  return 0;
*/
	return 1;
}

bool eepromWrite(UINT8 blocknum, UINT16 offset, UINT16 datanum, UINT8 * datas)
{
	UINT16 i=0,j;
	UINT8 xdata * datapoint=datas;
	UINT8 writebuf[128];
	UINT8 xdata * addr=(UINT8 xdata *)(Base_ROM_ADD+offset);
	while(datanum>EEPROMPAGE)
	{
		Write_29EE020(blocknum, datapoint, addr);
		i++;
		datanum-=EEPROMPAGE;
		datapoint+=EEPROMPAGE;
		addr+=EEPROMPAGE;
	}
	for(j=0;j<datanum;j++)
		writebuf[j]=*datapoint++;
	Write_29EE020(blocknum, writebuf, addr);
	return 1;
}

void eeprom_Unlock()
{    
	 AreaSelect =0x61;	/* WR='0', RD='1',ALE='1',片选为1 */	 
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0xAA;
	 AreaSelect = 0x60;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x2AAA) = 0x55;
	 AreaSelect = 0x61;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0x80;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0xAA;
 	 AreaSelect = 0x60;
	 *(UINT8 xdata *)(Base_ROM_ADD + 0x2AAA) = 0x55;
	 AreaSelect =0x61;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0x20;
	 delay(10);
}

void eeprom_Lock()
{
	AreaSelect =0x61;	/* WR='0', RD='1',ALE='1',片选为1 */	 
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0xAA;
	 AreaSelect = 0x60;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x2AAA) = 0x55;
	 AreaSelect = 0x61;
     *(UINT8 xdata *)(Base_ROM_ADD + 0x1555) = 0xA0;
	 delay(10);
}

/*延时子程序
void delay(UINT16 ms)
{
	UINT16 base=2500;
	while(ms--)
	{
		base=2500;
		while(base--);
	}
}
*/
//测试代码
void main(void)
{

	UINT8 test[12];
	int tmp,i;
	char buf[]={0x25,0x3a,0x42,0xbd,0xcd,0xec,0x45,0xff,0x74,0x3a,0x2c,0x56};
	SYSCLK_Init ();
	eeprom_Init();
/*
	for(i=1;i<15;i++)
	{
		a=eeprom_WriteByte(i,100,i);
		delay(10);
		eeprom_WriteByte(i,i*100,i);
		delay(10);
	}
*/

	

	tmp=Check_SST_29EE020();
	eepromWrite(0,0,12,buf);

	for(i=0;i<12;i++)
		test[i]=eeprom_ReadByte(0,i);


	
}

⌨️ 快捷键说明

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