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

📄 eeprom.c

📁 中颖单片机的基础驱动程序源代码eeprom
💻 C
字号:
#include	".\head\intrins.h"	
#include	".\head\CPU081.h"
#include	".\head\define.h"
#include	".\head\global.h"

/*-----------------------------------------------------------------------------------------
*
*		     		 I2C_eeprom driver for 24c01/02/04/08/16
*						------------------------------------
*
*capbility:
*  - support write serial bytes from MCU ram to eeprom
*  - support read serial bytes from eeprom to MCU ram
*  - support write/read serial bytes in one block
*
*24C02			1block * 32page rows * 4bytes  * 8 bit = 128bytes = 1kbits
*24C02			1block * 32page rows * 8bytes  * 8 bit = 256bytes = 2kbits	
*24C04			2block * 16page rows * 16bytes * 8 bit = 512bytes = 4kbits
*24C08			4block * 16page rows * 16bytes * 8 bit = 1024bytes = 8kbits
*24C16			8block * 16page rows * 16bytes * 8 bit = 2048bytes = 16kbits
*
*----------------------------------------------------------------------------------------*/

//communication config
#define	I2CFAILTIMES	30					 //*** communication retry times

//IO_Port config
#define		SDA_PINCR		P1CR			 //*** select SDA pin IO port
#define		SDA_PULL		P1PCR			 //***
#define		SDA_PIN			P1_1			 //*** 
#define		SDA				Bin(00000010);	 //***

#define		SCL_PINCR		P1CR			 //*** select SCL pin IO port
#define		SCL_PULL		P1PCR			 //*** 
#define		SCL_PIN			P1_0			 //*** 
#define		SCL				Bin(00000001);	 //***

//EEPROM Type config

#define EEPROM_24C01		0
#define EEPROM_24C02		1
#define EEPROM_24C04		2
#define EEPROM_24C08		3
#define EEPROM_24C16		4
#define	EEPROM_TYPE			EEPROM_24C02	 //*** select eeprom type
#if    (EEPROM_TYPE == EEPROM_24C01)
#define	 PAGE_OVER_ROLL Bin(00000011)		//every page contain 4bytes
#elif (EEPROM_TYPE == EEPROM_24C02)
#define	 PAGE_OVER_ROLL Bin(00000111)		//every page contain 8bytes
#elif (EEPROM_TYPE == EEPROM_24C04)
#define	 PAGE_OVER_ROLL Bin(00001111)		//every page contain 16bytes
#elif (EEPROM_TYPE == EEPROM_24C08)
#define	 PAGE_OVER_ROLL Bin(00001111)		//every page contain 16bytes
#elif (EEPROM_TYPE == EEPROM_24C16)
#define	 PAGE_OVER_ROLL Bin(00001111)		//every page contain 16bytes
#else        
#define	 PAGE_OVER_ROLL Bin(00000111)		//every page contain 8bytes
#endif	

/*------------------------------------------------------------------------------------------
;								IICDelay
;*** TBD: delay 4us
;notice: user may need to modify here
;-----------------------------------------------------------------------------------------*/
void	IICDelay(void)		
{			
		//delay 20*0.125=2us
					//+7	LCALL
		_nop_();	//+1	nop
		_nop_();	//+1	nop
		_nop_();	//+1	nop
		_nop_();	//+1	nop
		_nop_();	//+1	nop
					//+8	RET
}		
/*------------------------------------------------------------------------------------------
;								IICDelayStop
;*** TBD: delay about 10ms on 8M oscillator
;notice: user may need to modify here
;-----------------------------------------------------------------------------------------*/
void	IICDelayStop(void)		
{			
		Byte	i,j;
		for(j=4;j>0;j--)
		{
			RSTSTAT = 0x00;				//feed watchdog
			for(i=250;i>0;i--)
			{	
			}
		}
}		
/*------------------------------------------------------------------------------------------
;								IICInit
;-----------------------------------------------------------------------------------------*/
void	IICInit(void)
{
		SDA_PINCR	|= SDA;
		SDA_PULL	|= SDA;
		SDA_PIN = 1;
		SCL_PINCR	|= SCL;
		SCL_PULL	|= SCL;
		SCL_PIN = 1;				
}
/*------------------------------------------------------------------------------------------
;								IICStart
;-----------------------------------------------------------------------------------------*/
void	IICStart(void)
{
		SDA_PINCR |= SDA;			
		SDA_PIN=1;
		SCL_PINCR |= SCL;						
		SCL_PIN=1;	
		IICDelay();
		SDA_PIN=0;			//SDA H->L
		IICDelay();
		SCL_PIN=0;			//SCL H->L
}
/*------------------------------------------------------------------------------------------
;								IICStop
;-----------------------------------------------------------------------------------------*/
void	IICStop(void)
{
		SDA_PINCR |= SDA;		
		SDA_PIN=0;
		SCL_PINCR |= SCL;
		SCL_PIN=0;
		IICDelay();
		SCL_PIN=1;			//SCL L->H
		IICDelay();
		SDA_PIN=1;			//SDA L->H
		IICDelay();
		SDA_PINCR &= ~SDA;	//standby
		SCL_PINCR &= ~SCL;		
		SDA_PULL  |= SDA;
		SCL_PULL  |= SCL;
}
/*------------------------------------------------------------------------------------------
;								IICReadByte
;return one byte and tell the slave whether to read the apprend bytes by zI2CCounter
;-----------------------------------------------------------------------------------------*/
Byte	IICReadByte(Byte zI2CCounter)
{
		Byte	zI2CByteData;
		Byte	zI2CBit;

		SCL_PINCR |= SCL;						//SCL output
		SDA_PIN = 1;
		SDA_PINCR &= ~SDA;						//SDA input to read bit 1~8 from slave
		for( zI2CBit = 8;zI2CBit >0;zI2CBit--)		
		{
			SCL_PIN = 1;
			zI2CByteData *=2;
			if( SDA_PIN )
			{	
				zI2CByteData |= Bin(00000001);
			}
			SCL_PIN = 0;
		}
		SDA_PINCR |= SDA;						//SDA output to write apprend bit to slave	
		if(zI2CCounter == 0 )
		{
			SDA_PIN = 1;
		}
		else
		{
			SDA_PIN = 0;	
		}
		IICDelay();
		SCL_PIN = 1;
		IICDelay();
		SCL_PIN = 0;
		IICDelay();
		return zI2CByteData;
}
/*------------------------------------------------------------------------------------------
;								IICWriteByte
;write one byte,return 1 if success,return 0 if failure
;-----------------------------------------------------------------------------------------*/
bit	IICWriteByte(Byte zI2CByteData)
{
		Byte zI2CBit;
		bit  zI2CAck=0;
		SDA_PINCR |= SDA;						//SDA output to write bit 1~8 to slave			
		for( zI2CBit =8;zI2CBit>0;zI2CBit-- )
		{
			zI2CByteData *=2;
			if(CY)		
			{	
				SDA_PIN =1;		//send Bit1	
			}	
			else
			{
				SDA_PIN =0;		//send Bit0
			}			
			IICDelay();
			SCL_PIN=1;
			IICDelay();
			SCL_PIN=0;
		}													
		SDA_PIN=1;				//SDA input to read ACK from slave	
		SDA_PINCR &= ~SDA;			
		IICDelay();
		SCL_PIN=1;
		zI2CAck =  ~SDA_PIN;	
		IICDelay();
		SCL_PIN =0;		
		return zI2CAck;	
}	
/*------------------------------------------------------------------------------------------
;								IICCheckBusBusy
;return 1 if idle,return 0 if busy
;-----------------------------------------------------------------------------------------*/
bit IICCheckBusBusy(void)
{
	SDA_PINCR &= ~SDA;
	SCL_PINCR &= ~SCL;
	SDA_PIN=1;
	SCL_PIN=1;	
	if(SDA_PIN && SCL_PIN)
	{
		return 1;
	}
	return 0;
}
/*------------------------------------------------------------------------------------------
;								EEPROMWrite
;return 1 if communication success,return 0 if failure
;-----------------------------------------------------------------------------------------*/
bit	EEPROMWrite(Byte *zI2Cptr,Word zI2CByteAddr,Byte zI2CCounter)
{
	bit	 zI2CError=0;
	Byte zI2CDevAddrH = (((zI2CByteAddr>>8)*2)&0x0f) | Bin(10100000);
	Byte zI2CDevAddrL = zI2CByteAddr & 0xff;
	Byte zI2CRepeat  = I2CFAILTIMES;	

	while(zI2CCounter!=0)
	{
		if(_testbit_(zI2CError))							//comunication error and retry
		{
			IICStop();
			IICDelayStop();	
			zI2CRepeat--;			
			if( zI2CRepeat==0 )
			{
				return 0;
			}
		}
		if( ! IICCheckBusBusy())							//1.check bus stable
		{
			zI2CError = 1;			//mark error flag
			continue;
		}					
		IICInit();		
		IICStart();											//2.start
		if(! IICWriteByte(zI2CDevAddrH)	)					//3.command to write 	
		{
			zI2CError = 1;			//mark error flag
			continue;	
		}		
		if(! IICWriteByte(zI2CDevAddrL))					//4.write address
		{
			zI2CError = 1;			//mark error flag
			continue;		
		}									
		do													//5.write serial bytes
		{
			if( ! IICWriteByte(*zI2Cptr) )
			{
				zI2CError = 1;		//mark error flag
				break;		
			}			
			zI2CCounter--;			//prepare to write next byte						
			zI2Cptr++;
			zI2CDevAddrL ++;
			if(zI2CCounter == 0)
			{
				IICStop();			//finished all bytes written
				IICDelayStop();			
				return 1;	
			}
			if(!(zI2CDevAddrL&PAGE_OVER_ROLL))	
			{
				IICStop();			//switch to next page and continue to write rest bytes
				IICDelayStop();	
				break;
			}
		}while(zI2CCounter>0);		
	}
}
/*------------------------------------------------------------------------------------------
;								EEPROMRead
;return 1 if communication success,return 0 if failure
;-----------------------------------------------------------------------------------------*/
bit	EEPROMRead(Byte *zI2Cptr,Word zI2CByteAddr,Byte zI2CCounter)
{
	bit	 zI2CError=0;
	Byte zI2CDevAddrH = (((zI2CByteAddr>>8)*2)&0x0f) | Bin(10100000);
	Byte zI2CDevAddrL = zI2CByteAddr & 0xff;
	Byte zI2CRepeat  = I2CFAILTIMES;	
	while(zI2CCounter!=0)
	{
		if(_testbit_(zI2CError))							//comunication error and retry
		{
			IICStop();
			IICDelayStop();	
			zI2CRepeat--;			
			if( zI2CRepeat==0 )
			{
				return 0;
			}
		}
		if( ! IICCheckBusBusy())							//1.check bus stable
		{
			zI2CError = 1;			//mark error flag
			continue;
		}	
		IICInit();					
		IICStart();											//2.start
		if(! IICWriteByte(zI2CDevAddrH)	)					//3.command to write 	
		{
			zI2CError = 1;			//mark error flag
			continue;	
		}		
		if(! IICWriteByte(zI2CDevAddrL))					//4.write address
		{
			zI2CError = 1;			//mark error flag
			continue;		
		}		
		IICInit();							
		IICStart();											//5.command to read
		if(! IICWriteByte(zI2CDevAddrH | Bin(00000001)))
		{
			zI2CError = 1;			//mark error flag
			continue;	
		}		
		do													//6.read serial bytes					
		{
			zI2CCounter--;									
			*zI2Cptr = IICReadByte(zI2CCounter);			
			zI2Cptr++;
			zI2CDevAddrL ++;		
		}while(zI2CCounter>0);		
		IICStop();
		IICDelayStop();			
		return 1;
	}
}


⌨️ 快捷键说明

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