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

📄 i2c.c

📁 基于NXP LPC2368 iic的程序!大家可以
💻 C
字号:
/*****************************************************************************
 *   i2c.c:  I2C C file for NXP LPC23xx/24xx Family Microprocessors
 *
 *   Copyright(C) 2006, NXP Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2006.07.19  ver 1.00    Prelimnary version, first Release
 *
*****************************************************************************/
#include "LPC23xx.h"                        /* LPC23xx/24xx definitions */
#include "type.h"
#include "irq.h"
#include "i2c.h"
#include "stdio.h"
#include "uart.h"

#define BUFFER_SIZE	0x40

extern char RUN_INFOR[BUFFER_SIZE];

volatile DWORD I2CMasterState = I2C_IDLE;
volatile DWORD I2CSlaveState = I2C_IDLE;

volatile DWORD I2CCmd;
volatile DWORD I2CMode;

volatile BYTE I2CMasterBuffer[BUFSIZE];
volatile BYTE I2CSlaveBuffer[BUFSIZE];
volatile DWORD I2CCount = 0;
volatile DWORD I2CReadLength;
volatile DWORD I2CWriteLength;

volatile DWORD RdIndex = 0;
volatile DWORD WrIndex = 0;

volatile char Status[0x20];
volatile char StatusIndex=0;

/* 
From device to device, the I2C communication protocol may vary, 
*/   

/*****************************************************************************
** Function name:		I2C0MasterHandler
**
** Descriptions:		I2C0 interrupt handler, deal with master mode
**				only.
**
** parameters:			None
** Returned value:		None
** 
*****************************************************************************/
void I2C2MasterHandler(void) __irq 
{
  BYTE StatValue;

  /* this handler deals with master read and master write only */
  StatValue = I22STAT;
  IENABLE;				/* handles nested interrupt */
  
  Status[ StatusIndex++ ] = StatValue;	
  switch ( StatValue )
  {
    case 0x08:			/* A Start condition is issued. */
	I22DAT = I2CMasterBuffer[0];
	I22CONSET = I2CONSET_AA;
	I22CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
	I2CMasterState = I2C_STARTED;
	break;
	
	case 0x10:			/* A repeated started is issued */
	if ( I2CCmd == AT24C16_READ )
	{
	  I22DAT = I2CMasterBuffer[2];
	}
	I22CONSET = I2CONSET_AA;
	I22CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
	I2CMasterState = I2C_RESTARTED;
	break;
	
	case 0x18:			/* Regardless, it's a ACK */
	if ( I2CMasterState == I2C_STARTED )
	{
	  I22DAT = I2CMasterBuffer[1+WrIndex];
	  WrIndex++;
	  I2CMasterState = DATA_ACK;
	}

	I22CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x28:	/* Data byte has been transmitted, regardless ACK or NACK */
	case 0x30:
	if ( WrIndex != I2CWriteLength )
	{   
	  I22DAT = I2CMasterBuffer[1+WrIndex];
	  WrIndex++;
	  if ( WrIndex != I2CWriteLength )
	  {   
		I2CMasterState = DATA_ACK;
	  }
	  else
	  {			
		if ( I2CReadLength != 0 )
		{
		  I22CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
		  I2CMasterState = I2C_REPEATED_START;
		}
		else
		{
			I2CMasterState = DATA_NACK;
			I22CONCLR = I2CONCLR_AAC;
		}
	  }
	}
	else
	{
	  if ( I2CReadLength != 0 )
	  {
		I22CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
		I2CMasterState = I2C_REPEATED_START;
	  }
	  else
	  {
		I2CMasterState = DATA_NACK;
		I22CONCLR = I2CONCLR_AAC;
	  }
	}
	I22CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x40:	/* Master Receive, SLA_R has been sent */
	I22CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x50:	/* Data byte has been received, regardless following ACK or NACK */
	case 0x58:
	I2CMasterBuffer[3+RdIndex] = I22DAT;
	RdIndex++;
	if ( RdIndex != I2CReadLength )
	{   
	  I2CMasterState = DATA_ACK;
	}
	else
	{
	  RdIndex = 0;
	  I2CMasterState = DATA_NACK;
	  I22CONCLR = I2CONCLR_AAC;	 
	}
	I22CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x20:		/* regardless, it's a NACK */
	case 0x48:
	I22CONCLR = I2CONCLR_SIC;
	I2CMasterState = DATA_NACK;
	break;
	
	case 0x38:		/* Arbitration lost, in this example, we don't
					deal with multiple master situation */
	default:
	I22CONCLR = I2CONCLR_SIC;	
	break;
  }
  IDISABLE;
  VICVectAddr = 0;		/* Acknowledge Interrupt */
}

/*****************************************************************************
** Function name:		I2CStart
**
** Descriptions:		Create I2C start condition, a timeout
**				value is set if the I2C never gets started,
**				and timed out. It's a fatal error. 
**
** parameters:			None
** Returned value:		true or false, return false if timed out
** 
*****************************************************************************/
DWORD I2CStart( void )
{
  DWORD timeout = 0;
  DWORD retVal = FALSE;
 
  /*--- Issue a start condition ---*/
  I22CONSET = I2CONSET_STA;	/* Set Start flag */
    
  /*--- Wait until START transmitted ---*/
  while( 1 )
  {
	if ( I2CMasterState == I2C_STARTED )
	{
	  retVal = TRUE;
	  break;	
	}
	if ( timeout >= MAX_TIMEOUT )
	{
	  retVal = FALSE;
	  break;
	}
	timeout++;
  }
  return( retVal );
}

/*****************************************************************************
** Function name:		I2CStop
**
** Descriptions:		Set the I2C stop condition, if the routine
**				never exit, it's a fatal bus error.
**
** parameters:			None
** Returned value:		true or never return
** 
*****************************************************************************/
DWORD I2CStop( void )
{
  I22CONSET = I2CONSET_STO | I2CONSET_AA;      /* Set Stop flag */ 
  I22CONCLR = I2CONCLR_SIC;  /* Clear SI flag */ 
            
  /*--- Wait for STOP detected ---*/
  while( I22CONSET & I2CONSET_STO );
  return TRUE;
}

/*****************************************************************************
** Function name:		I2CInit
**
** Descriptions:		Initialize I2C controller
**
** parameters:			I2c mode is either MASTER or SLAVE
** Returned value:		true or false, return false if the I2C
**				interrupt handler was not installed correctly
** 
*****************************************************************************/
DWORD I2CInit( DWORD I2cMode ) 
{
  PCONP |= (1 << 19);
  PINSEL0 |= 0x00A00000;	//选择引脚 I2C2  
							
  /*--- Clear flags ---*/
  I22CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;    

  /*--- Reset registers ---*/
  I22SCLL   = I2SCLL_SCLL;
  I22SCLH   = I2SCLH_SCLH;
  if ( I2cMode == I2CSLAVE )
  {
	//I22ADR = SLAVE_ADDR;
  }    

  /* Install interrupt handler */	
  if ( install_irq( I2C2_INT, (void *)I2C2MasterHandler, HIGHEST_PRIORITY ) == FALSE )
  {
	return( FALSE );
  }
  I22CONSET = I2CONSET_I2EN;
  return( TRUE );
}

/*****************************************************************************
** Function name:		I2CEngine
**
** Descriptions:		The routine to complete a I2C transaction
**				from start to stop. All the intermitten
**				steps are handled in the interrupt handler.
**				Before this routine is called, the read
**				length, write length, I2C master buffer,
**				and I2C command fields need to be filled.
**				see i2cmst.c for more details. 
**
** parameters:			None
** Returned value:		true or false, return false only if the
**				start condition can never be generated and
**				timed out. 
** 
*****************************************************************************/
DWORD I2CEngine( void ) 
{
  char i;

  I2CMasterState = I2C_IDLE;
  RdIndex = 0;
  WrIndex = 0;
  StatusIndex=0;
  for( i=0; i<0x20; i++)
  {
  	Status[ i ] = 0;
  }

  if ( I2CStart() != TRUE )
  {
	sprintf( RUN_INFOR, "I2CStart Failed.\r\n" );
    UARTSend( 0, (BYTE *)RUN_INFOR, BUFFER_SIZE ); 
    I2CStop();
	return ( FALSE );
  }

  while ( 1 )
  {
	if ( I2CMasterState == DATA_NACK )
	{
	  I2CStop();
	  break;
	}
  }
  for( i=0; i<StatusIndex; i++)
  {
  	sprintf( RUN_INFOR, "Status[%d]=%XH.\r\n" , i , Status[ i ] );
  	UARTSend( 0, (BYTE *)RUN_INFOR, BUFFER_SIZE );
  }    
  return ( TRUE );      
}

/******************************************************************************
**                            End Of File
******************************************************************************/

⌨️ 快捷键说明

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