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

📄 i2c_driver.c

📁 I2c code for LPC2148
💻 C
字号:
#define Chip0	(1)

#define DeviceAdd		(0xA0) //10100 000 device address
#define ChipAddress0    (0x00)
#define ChipAddress1	(0x04)     						 

#define PageSize 		(256)
#define NoOfPages 		(512)
#define MaxBytes 		(131072L)
#define AddressBits		(17)		
#define Read			(0x01)
#define Write			(0x00)

#define LastPage		BIT(17)

//EEPROM Word addressing requires 17 bits data word address.
UDWord EEPROMAddress;

UByte MemPage[PageSize];//page writting globol buffer
UByte LowMemAdd,HighMemAdd,SeventhBitAdd;//address buffers
UByte Data;//single byte write buffer;
UByte DevAdd;
UByte I2CBuff[20];

void I2C0_Handler(void)
{
  BYTE StatValue;

  /* this handler deals with master read and master write only */
  StatValue = I20STAT;
 // IENABLE;				/* handles nested interrupt */	
  switch ( StatValue )
  {
	case 0x08:		/* A Start condition is issued. */
						//I20DAT = I2CMasterBuffer[0];
						I20Dat = I2CBuff[0];//Device Address
						I20CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
						I2CDataPtr++;
						I2CMasterState = I2C_STARTED;
		break;
	
	case 0x10:		/* A repeated started is issued */
						I20Dat = I2CBuff[0];//Device address for repeated start
						//this condition is only for master in receive mode.
						I20CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
						I2CMasterState = I2C_RESTARTED;
		break;
	
	case 0x18:		/* 0x18 Regardless, it's a ACK */
						if(I2CMAsterState == I2C_STARTED)
						{
							I20DAT = I2CBuff[I2CDataPtr];
							I2CDataPtr++;
						}
//						  I2CMasterState = DATA_ACK;
						I20CONCLR = I2CONCLR_SIC;
			break;
	
	case 0x28:	/* Data byte has been transmitted, regardless ACK or NACK */
	case 0x30:
						if ( WrIndex != I2CWriteLength )
						{   
						  I20DAT = I2CMasterBuffer[1+WrIndex]; /* this should be the last one */
						  WrIndex++;
						  if ( WrIndex != I2CWriteLength )
						  {   
							I2CMasterState = DATA_ACK;
						  }
						  else
						  {
							I2CMasterState = DATA_NACK;
							if ( I2CReadLength != 0 )
							{
							  I20CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
							  I2CMasterState = I2C_REPEATED_START;
							}
						  }
						}
						else
						{
						  if ( I2CReadLength != 0 )
						  {
							I20CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
							I2CMasterState = I2C_REPEATED_START;
						  }
						  else
						  {
							I2CMasterState = DATA_NACK;
						  }
						}
						I20CONCLR = I2CONCLR_SIC;
		break;
	
	case 0x40:	/* Master Receive, SLA_R has been sent */
						I20CONCLR = I2CONCLR_SIC;
		break;
	
	case 0x50:	/* Data byte has been received, regardless following ACK or NACK */
	case 0x58:
						I2CMasterBuffer[3+RdIndex] = I20DAT;
						RdIndex++;
						if ( RdIndex != I2CReadLength )
						{   
						  I2CMasterState = DATA_ACK;
						}
						else
						{
						  RdIndex = 0;
						  I2CMasterState = DATA_NACK;
						}
						I20CONSET = I2CONSET_AA;	/* assert ACK after data is received */
						I20CONCLR = I2CONCLR_SIC;
		break;
	
	case I2STAT_SLA_W_NOACK:		/* regardless, it's a NACK */
	case I2STAT_SLA_R_NOACK:
						I20CONCLR = I2CONCLR_SIC;
						I2CMasterState = DATA_NACK;
		break;
	
	case I2STAT_ARB_LOST:		/* Arbitration lost, in this example, we don't
								deal with multiple master situation */
	default:
			I20CONCLR = I2CONCLR_SIC;	
		break;
  }
  //IDISABLE;
  VICVectAddr = 0;		/* Acknowledge Interrupt */	
}

UByte WriteByte(UByte Byte,UDWord Address)
{	
	UByte retVal=0;
	UDWord Timeout=0;
#ifdef Chip0
	DevAdd = (DeviceAdd | ChipAddress0 | Write);
#else
	DevAdd = (DeviceAdd | ChipAddress1 | Write);
#endif										 
	
	LowMemAdd = (Address & 0x000000FF);
	HighMemAdd = ((Address >> 8) & 0x000000FF);
	
	if(Address & LastPage)
	{
		DevAdd |= 0x02;
	}
	
	I2CDataPtr = 0;
	I2CDataLen = 4;
	I2CBuff[0] = DevAdd;
	I2CBuff[1] = HighMemAdd;
	I2CBuff[2] = LowMemAdd;
	I2CBuff[3] = Byte;
	I2CBuff[4] = 0x00;

	if ( I2CStart() != TRUE )
  	{
		I2CStop();
		return ( FALSE );
  	}

	while(1)
	{
		if(I2CMasterState == DATA_NACK)
		{
			I2CStop();
			retVal = 1;
			break;
		}
		if(Timeout >= 0x000FFFFF)
		{
			retVal = 0;
		}
		Timeout++;
	}
	return retVal;
}

void initI2C0(void)
{
	UDWord PinSel;

	PCONP |= PCI2C0;//Power on I2C0 bit7
	//PINSEL1 = (PINSEL1 & I2C0PIN_MASK) | I2C0PIN_SELECT;
	PinSel         = PINSEL1;
    PinSel        &= I2C0PIN_MASK;
    PinSel        |= I2C0PIN_SELECT;
    PINSEL1        = PinSel;

    I20CONCLR      = (I2CONCLR_I2ENC | I2CONCLR_STAC | I2CONCLR_SIC | I2CONCLR_AAC);//Clear flags    

    I20SCLH        = I2CSCLH;
    I20SCLL        = I2CSCLL;

	//write code for enabling IRQ Here
	// handler for IRQ is I2C0_Handler

	I20CONSET = I2CONSET_I2EN;
}

DWORD I2CStart( void )
{
  DWORD timeout = 0;
  DWORD retVal = 0;
 
  /*--- Issue a start condition ---*/
  I20CONSET = I2CONSET_STA;	/* Set Start flag */
    
  /*--- Wait until START transmitted ---*/
  while( 1 )
  {
	if ( I2CMasterState == I2C_STARTED )
	{
	  retVal = TRUE;
	  break;	
	}
	if ( timeout >= 0x00FFFFFF )
	{
	  retVal = 0;
	  break;
	}
	timeout++;
  }
  return( retVal );
}

DWORD I2CStop( void )
{
  DWORD timeout = 0;
  DWORD retVal = 0;

  I20CONSET = I2CONSET_STO;     /* Set Stop flag */ 
  I20CONCLR = I2CONCLR_SIC;  	/* Clear SI flag */ 
  
  retVal = 1;          
  /*--- Wait for STOP detected ---*/
  while( I20CONSET & I2CONSET_STO )
  {
	if ( timeout >= 0x00FFFFFF )
	{
	  retVal = 0;
	  break;
	}
	timeout++;  	
  }

  return retVal;
}

⌨️ 快捷键说明

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