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

📄 i2c.c

📁 LPC2102的keil vendor code
💻 C
📖 第 1 页 / 共 2 页
字号:

	I2CCmd = I2C_WRITE_READ;
    I2CEngine();
	
	/* De-Initialize I2C1 controller */
	I2C1_DeInit(); 
} // I2C1_Master_Demo

/*****************************************************************************
** Function name:	I2C1_Init
** Description:		Initialize I2C1 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 I2C1_Init( DWORD I2cMode ) 
{
	BYTE i;
	PINSEL1 |= 0x00000014;		// Set P0.17 as SCL1 and P0.18 as SDA1

    IODIR = 0x00060000;			// Set P0.17 and P0.18 ports to output, high
    IOSET = 0x00060000;

    /*--- Clear flags ---*/
    I21CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;    

    /*--- Reset registers ---*/
    I21SCLL   = I2SCLL_SCLL;
    I21SCLH   = I2SCLH_SCLH;

    if(I2cMode == I2CSLAVE)
    {
		I21ADR = I2CSL_ADDRS << 1;
    }    

    /* Install interrupt handler */	
    if(install_irq( I2C1_INT, (void *)I2C1_MasterHandler ) == FALSE)
    {
		return( FALSE );
    }

	/* Enable I2C controller for Master or Slave functions */
	if(I2cMode == I2CMASTER)
	{
		I21CONSET = I2CONSET_I2EN;
	}
	else
	{
		I21CONSET = I2CONSET_I2EN | I2CONSET_AA;
	}

    for(i=0; i<BUFSIZE; i++)	/* clear buffer */
    {
		I2C1MasterBuffer[i] = 0;
    }
    
    return( TRUE );
} // I2C1_Init

/*****************************************************************************
** Function name:	I2C1_DeInit
** Description:		De-Initialize I2C1 controller
** Parameters:		None
** Returned value:	true or false, return false when the interrupt number is 
**					not found
*****************************************************************************/
DWORD I2C1_DeInit(void) 
{
	PINSEL1 &= ~0x00000014;		// Set P0.17 as SCL1 and P0.18 as SDA1

    IODIR &= ~0x00060000;		// Set P0.17 and P0.18 ports to input

    /* Install interrupt handler */	
    if(uninstall_irq(I2C1_INT) == FALSE)
    {
		return( FALSE );
    }
 
 	VICIntEnClr = 1 << I2C1_INT;
	   
    return (TRUE);
} // I2C1_DeInit

/*****************************************************************************
** Function name:	I2C1_MasterHandler
** Description:		I2C1 interrupt handler, deal with MASTER mode only.
** Parameter:		None
** Returned value:	None
*****************************************************************************/
void I2C1_MasterHandler (void) __irq 
{
	BYTE StatValue;

	/* Reads the I2C status to branch to one of the I2C state routines */
	StatValue = I21STAT;
  
	IENABLE;

	I21CONCLR = I2CONCLR_AAC | I2CONCLR_STAC;	// Clear STA and AA flags

	/* Handles I2C state routines */ 
	switch(StatValue)
	{
		case 0x08:	/* A Start condition is issued. */
			I21DAT = I2C1MasterBuffer[0];
			I21CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
			I2C1MasterState = I2C_STARTED;
			break;

		case 0x10:	/* A repeated start is issued */
			if(I2CCmd == I2C_WRITE_READ)
			{
			    I21DAT = I2C1MasterBuffer[1+WrIndex];
				WrIndex++;
			}
			else if(I2CCmd == I2C_READ_WRITE)
			{
			    I21DAT = I2C1MasterBuffer[1+RdIndex];
				RdIndex++;
			}

			I21CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
			I2C1MasterState = I2C_RESTARTED;
			break;
	
		case 0x18:	/* Regardless, it's a ACK */
			if(I2C1MasterState == I2C_STARTED)
			{
			    I21DAT = I2C1MasterBuffer[1+WrIndex];
			    WrIndex++;
			    I2C1MasterState = DATA_ACK;
			}

			if(I2CCmd == I2C_READ_WRITE)
			{
			    I21DAT = I2C1MasterBuffer[1+RdIndex];
				RdIndex++;
			    I2C1MasterState = DATA_ACK;
			}

			I21CONCLR = I2CONCLR_SIC;
			break;
	
		case 0x28:	/* Data byte has been transmitted, regardless ACK or NACK */
		case 0x30:
			if(WrIndex < I2C1WriteLength)
			{   
			    I21DAT = I2C1MasterBuffer[1+WrIndex]; /* This should be the last one */
			    if(WrIndex < I2C1WriteLength)
			    {   
					I2C1MasterState = DATA_ACK;
			    }
			    else
			    {
					I2C1MasterState = DATA_NACK;
					if(I2C1ReadLength > 0)
					{
					    I21CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
				    	I2C1MasterState = I2C_REPEATED_START;
					}
			    }

			    WrIndex++;
			}
			else
			{
			    if(I2C1ReadLength > 0)
			    {
					I21CONSET = I2CONSET_STA;	/* Set Repeated-start flag */
					I2C1MasterState = I2C_REPEATED_START;
			    }
			    else
			    {
					I2C1MasterState = DATA_NACK;
			    }
			}

			I21CONCLR = I2CONCLR_SIC;
			break;

		case 0x40:	/* Master Receive, SLA_R has been sent */
			RdIndex++;
			I21CONSET = I2CONSET_AA;
			I21CONCLR = I2CONCLR_SIC;
			break;
	
		case 0x50:	/* Data byte has been received, regardless following ACK or NACK */
			I2C1MasterBuffer[1+RdIndex] = I21DAT;

			RdIndex++;

			if(RdIndex < I2C1ReadLength)
			{
				I21CONSET = I2CONSET_AA;	/* assert ACK after data is received */
			    I2C1MasterState = DATA_ACK;
			}
			else
			{
			    RdIndex = 0;
				I21CONCLR = I2CONCLR_AAC;
			    I2C1MasterState = DATA_ACK;
			}

			I21CONCLR = I2CONCLR_SIC;
			break;

		case 0x58:
			I2C1MasterState = DATA_NACK;
			I21CONCLR = I2CONCLR_SIC;
			break;

		case 0x20:	/* Regardless, it's a NACK */
		case 0x48:
			I21CONSET = I2CONSET_AA;
			I21CONCLR = I2CONCLR_SIC;
			I2C1MasterState = DATA_NACK;
			break;
	
		case 0x38:	/* Arbitration lost, in this example, we don't
					   deal with multiple master situation */
		default:
			I21CONSET = I2CONSET_AA;
			I21CONCLR = I2CONCLR_SIC;	
			break;
    }

    IDISABLE;
    VICVectAddr = 0;		/* Acknowledge Interrupt */
} // I2C1_MasterHandler

/*****************************************************************************
** 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 returnValue = FALSE;
 
    /*--- Issue a start condition ---*/
    I21CONSET = I2CONSET_STA;	/* Set Start flag */
    
    /*--- Wait until START transmitted ---*/
    while(1)
    {
		if(I2C1MasterState == I2C_STARTED)
		{
		    returnValue = TRUE;
		    break;	
		}

		if(timeout >= MAX_TIMEOUT)
		{
		    returnValue = FALSE;
		    break;
		}

		timeout++;
    }

    return(returnValue);
} // I2CStart

/*****************************************************************************
** 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 )
{
    I21CONSET = I2CONSET_STO;  /* Set Stop flag */ 
    I21CONCLR = I2CONCLR_SIC;  /* Clear SI flag */ 
            
    /*--- Wait for STOP detected ---*/
    while(I21CONSET & I2CONSET_STO);

    return TRUE;
} // I2CStop

/*****************************************************************************
** 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.
** Parameters:		None
** Returned value:	true or false, return false only if the	start condition
**					can never be generated and timed out.
*****************************************************************************/
DWORD I2CEngine( void ) 
{
    I2C1MasterState = I2C_IDLE;
    RdIndex = 0;
    WrIndex = 0;

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

    while(1)
    {
		if(I2C1MasterState == DATA_NACK)
		{
		    I2CStop();
		    break;
		}
    }    

    return (TRUE);      
} // I2CEngine
#endif

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

⌨️ 快捷键说明

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