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

📄 i2c.c

📁 LPCXpresso1768
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
 *   $Id:: i2c.c 5865 2010-12-08 21:42:21Z usb00423                         $
 *   Project: NXP LPC17xx I2C example
 *
 *   Description:
 *     This file contains I2C code example which include I2C initialization, 
 *     I2C interrupt handler, and APIs for I2C access.
 *
 ****************************************************************************
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * products. This software is supplied "AS IS" without any warranties.
 * NXP Semiconductors assumes no responsibility or liability for the
 * use of the software, conveys no license or title under any patent,
 * copyright, or mask work right to the product. NXP Semiconductors
 * reserves the right to make changes in the software without
 * notification. NXP Semiconductors also make no representation or
 * warranty that such application will be suitable for the specified
 * use without further testing or modification.
****************************************************************************/
#include "lpc17xx.h"
#include "type.h"
#include "i2c.h"

volatile uint32_t I2CMasterState[I2C_PORT_NUM] = {I2C_IDLE,I2C_IDLE,I2C_IDLE};
volatile uint32_t timeout[I2C_PORT_NUM] = {0, 0, 0};

volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
volatile uint32_t I2CCount[I2C_PORT_NUM] = {0, 0, 0};
volatile uint32_t I2CReadLength[I2C_PORT_NUM];
volatile uint32_t I2CWriteLength[I2C_PORT_NUM];

volatile uint32_t RdIndex0 = 0, RdIndex1 = 0, RdIndex2 = 0;
volatile uint32_t WrIndex0 = 0, WrIndex1 = 0, WrIndex2 = 0;

/* 
From device to device, the I2C communication protocol may vary, 
in the example below, the protocol uses repeated start to read data from or 
write to the device:
For master read: the sequence is: STA,Addr(W),offset,RE-STA,Addr(r),data...STO 
for master write: the sequence is: STA,Addr(W),offset,RE-STA,Addr(w),data...STO
Thus, in state 8, the address is always WRITE. in state 10, the address could 
be READ or WRITE depending on the I2C command.
*/   

/*****************************************************************************
** Function name:		I2C_IRQHandler
**
** Descriptions:		I2C interrupt handler, deal with master mode only.
**
** parameters:			None
** Returned value:		None
** 
*****************************************************************************/
void I2C0_IRQHandler(void) 
{
  uint8_t StatValue;

  timeout[0] = 0;
  /* this handler deals with master read and master write only */
  StatValue = LPC_I2C0->STAT;
  switch ( StatValue )
  {
	case 0x08:			/* A Start condition is issued. */
	WrIndex0 = 0;
	LPC_I2C0->DAT = I2CMasterBuffer[0][WrIndex0++];
	LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
	break;
	
	case 0x10:			/* A repeated started is issued */
	RdIndex0 = 0;
	/* Send SLA with R bit set, */
	LPC_I2C0->DAT = I2CMasterBuffer[0][WrIndex0++];
	LPC_I2C0->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
	break;
	
	case 0x18:			/* Regardless, it's a ACK */
	if ( I2CWriteLength[0] == 1 )
	{
	  LPC_I2C0->CONSET = I2CONSET_STO;      /* Set Stop flag */
	  I2CMasterState[0] = I2C_NO_DATA;
	}
	else
	{
	  LPC_I2C0->DAT = I2CMasterBuffer[0][WrIndex0++];
	}
	LPC_I2C0->CONCLR = I2CONCLR_SIC;
	break;

	case 0x28:	/* Data byte has been transmitted, regardless ACK or NACK */
	if ( WrIndex0 < I2CWriteLength[0] )
	{   
	  LPC_I2C0->DAT = I2CMasterBuffer[0][WrIndex0++]; /* this should be the last one */
	}
	else
	{
	  if ( I2CReadLength[0] != 0 )
	  {
		LPC_I2C0->CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
	  }
	  else
	  {
		LPC_I2C0->CONSET = I2CONSET_STO;      /* Set Stop flag */
		I2CMasterState[0] = I2C_OK;
	  }
	}
	LPC_I2C0->CONCLR = I2CONCLR_SIC;
	break;

	case 0x30:
	LPC_I2C0->CONSET = I2CONSET_STO;      /* Set Stop flag */
	I2CMasterState[0] = I2C_NACK_ON_DATA;
	LPC_I2C0->CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x40:	/* Master Receive, SLA_R has been sent */
	if ( (RdIndex0 + 1) < I2CReadLength[0] )
	{
	  /* Will go to State 0x50 */
	  LPC_I2C0->CONSET = I2CONSET_AA;	/* assert ACK after data is received */
	}
	else
	{
	  /* Will go to State 0x58 */
	  LPC_I2C0->CONCLR = I2CONCLR_AAC;	/* assert NACK after data is received */
	}
	LPC_I2C0->CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x50:	/* Data byte has been received, regardless following ACK or NACK */
	I2CSlaveBuffer[0][RdIndex0++] = LPC_I2C0->DAT;
	if ( (RdIndex0 + 1) < I2CReadLength[0] )
	{   
	  LPC_I2C0->CONSET = I2CONSET_AA;	/* assert ACK after data is received */
	}
	else
	{
	  LPC_I2C0->CONCLR = I2CONCLR_AAC;	/* assert NACK on last byte */
	}
	LPC_I2C0->CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x58:
	I2CSlaveBuffer[0][RdIndex0++] = LPC_I2C0->DAT;
	I2CMasterState[0] = I2C_OK;
	LPC_I2C0->CONSET = I2CONSET_STO;	/* Set Stop flag */ 
	LPC_I2C0->CONCLR = I2CONCLR_SIC;	/* Clear SI flag */
	break;

	case 0x20:		/* regardless, it's a NACK */
	case 0x48:
	LPC_I2C0->CONSET = I2CONSET_STO;      /* Set Stop flag */
	I2CMasterState[0] = I2C_NACK_ON_ADDRESS;
	LPC_I2C0->CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x38:		/* Arbitration lost, in this example, we don't
					deal with multiple master situation */
	default:
	I2CMasterState[0] = I2C_ARBITRATION_LOST;
	LPC_I2C0->CONCLR = I2CONCLR_SIC;	
	break;
  }
  return;
}

/*****************************************************************************
** Function name:		I2C_IRQHandler
**
** Descriptions:		I2C interrupt handler, deal with master mode only.
**
** parameters:			None
** Returned value:		None
** 
*****************************************************************************/
void I2C1_IRQHandler(void) 
{
  uint8_t StatValue;

  timeout[1] = 0;
  /* this handler deals with master read and master write only */
  StatValue = LPC_I2C1->STAT;
  switch ( StatValue )
  {
	case 0x08:			/* A Start condition is issued. */
	WrIndex1 = 0;
	LPC_I2C1->DAT = I2CMasterBuffer[1][WrIndex1++];
	LPC_I2C1->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
	break;
	
	case 0x10:			/* A repeated started is issued */
	RdIndex1 = 0;
	/* Send SLA with R bit set, */
	LPC_I2C1->DAT = I2CMasterBuffer[1][WrIndex1++];
	LPC_I2C1->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
	break;
	
	case 0x18:			/* Regardless, it's a ACK */
	if ( I2CWriteLength[1] == 1 )
	{
	  LPC_I2C1->CONSET = I2CONSET_STO;      /* Set Stop flag */
	  I2CMasterState[1] = I2C_NO_DATA;
	}
	else
	{
	  LPC_I2C1->DAT = I2CMasterBuffer[1][WrIndex1++];
	}
	LPC_I2C1->CONCLR = I2CONCLR_SIC;
	break;

	case 0x28:	/* Data byte has been transmitted, regardless ACK or NACK */
	if ( WrIndex1 < I2CWriteLength[1] )
	{   
	  LPC_I2C1->DAT = I2CMasterBuffer[1][WrIndex1++]; /* this should be the last one */
	}
	else
	{
	  if ( I2CReadLength[1] != 0 )
	  {
		LPC_I2C1->CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
	  }
	  else
	  {
		LPC_I2C1->CONSET = I2CONSET_STO;      /* Set Stop flag */
		I2CMasterState[1] = I2C_OK;
	  }
	}
	LPC_I2C1->CONCLR = I2CONCLR_SIC;
	break;

	case 0x30:
	LPC_I2C1->CONSET = I2CONSET_STO;      /* Set Stop flag */
	I2CMasterState[1] = I2C_NACK_ON_DATA;
	LPC_I2C1->CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x40:	/* Master Receive, SLA_R has been sent */
	if ( (RdIndex1 + 1) < I2CReadLength[1] )
	{
	  /* Will go to State 0x50 */
	  LPC_I2C1->CONSET = I2CONSET_AA;	/* assert ACK after data is received */
	}
	else
	{
	  /* Will go to State 0x58 */
	  LPC_I2C1->CONCLR = I2CONCLR_AAC;	/* assert NACK after data is received */
	}
	LPC_I2C1->CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x50:	/* Data byte has been received, regardless following ACK or NACK */
	I2CSlaveBuffer[1][RdIndex1++] = LPC_I2C1->DAT;
	if ( (RdIndex1 + 1) < I2CReadLength[1] )
	{   
	  LPC_I2C1->CONSET = I2CONSET_AA;	/* assert ACK after data is received */
	}
	else
	{
	  LPC_I2C1->CONCLR = I2CONCLR_AAC;	/* assert NACK on last byte */
	}
	LPC_I2C1->CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x58:
	I2CSlaveBuffer[1][RdIndex1++] = LPC_I2C1->DAT;
	I2CMasterState[1] = I2C_OK;
	LPC_I2C1->CONSET = I2CONSET_STO;	/* Set Stop flag */ 
	LPC_I2C1->CONCLR = I2CONCLR_SIC;	/* Clear SI flag */
	break;

	case 0x20:		/* regardless, it's a NACK */
	case 0x48:
	LPC_I2C1->CONSET = I2CONSET_STO;      /* Set Stop flag */
	I2CMasterState[1] = I2C_NACK_ON_ADDRESS;
	LPC_I2C1->CONCLR = I2CONCLR_SIC;
	break;
	
	case 0x38:		/* Arbitration lost, in this example, we don't
					deal with multiple master situation */
	default:
	I2CMasterState[1] = I2C_ARBITRATION_LOST;
	LPC_I2C1->CONCLR = I2CONCLR_SIC;	
	break;
  }
  return;
}

/*****************************************************************************
** Function name:		I2C_IRQHandler
**
** Descriptions:		I2C interrupt handler, deal with master mode only.
**
** parameters:			None
** Returned value:		None
** 
*****************************************************************************/
void I2C2_IRQHandler(void) 
{
  uint8_t StatValue;

  timeout[2] = 0;
  /* this handler deals with master read and master write only */
  StatValue = LPC_I2C2->STAT;
  switch ( StatValue )
  {
	case 0x08:			/* A Start condition is issued. */
	WrIndex2 = 0;
	LPC_I2C2->DAT = I2CMasterBuffer[2][WrIndex2++];
	LPC_I2C2->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
	break;
	
	case 0x10:			/* A repeated started is issued */
	RdIndex2 = 0;

⌨️ 快捷键说明

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