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

📄 lpc_i2c.c

📁 给大家提供一个在inram/exram中调试的示例,在周公的lpc2200上调试过.
💻 C
📖 第 1 页 / 共 2 页
字号:
	{
		I2CMsg.buf = pMsg;
		I2CMsg.nrBytes= numMsg;
		I2CMsg.address = NULL;
		I2CMsg.transMode= transMode;
		I2CMsg.dataCount = 0;

		VIC_EnableInt(INT_I2C);		// Open interrupt

		__I2C_ClearFlag(I2C_MSG_START | I2C_MSG_SI | I2C_MSG_STOP);
		I2C_EnableI2C();
		__I2C_SetFlag(I2C_MSG_AA);

		while(I2CState != I2C_OK);
		if (I2CState == I2C_OK)
			return 0;
		else
			return 1;
	}
	
	return 0;
}


/*************************************************************************
 * Function Name: I2C_HandleMasterState
 * Parameters: void 
 * Return: void
 * Description: Master mode state handler for I2C bus.
 *
 *************************************************************************/
void I2C_HandleMasterState(void)
{
	unsigned long I2Cstatus = I2C_I2STAT & 0xF8;
	unsigned long ReadData ; // for debug

	switch (I2Cstatus)
	{
		case 0x08 : // start condition transmitted
		case 0x10 : // restart condition transmitted
			if (I2CMsg.transMode == WRITETHENREAD)
			{
				if (I2CMsg.dataCount < I2CMsg.nrWriteBytes)
					__I2C_SendData( I2CMsg.address | WRITE );
				else
					__I2C_SendData( I2CMsg.address | READ );
			}
			else
			{
				__I2C_SendData( I2CMsg.address | I2CMsg.transMode );
			}
			__I2C_ClearFlag(I2C_MSG_SI);	// clear SI bit, STO bit clear automatically
			break;
			
		case 0x18 : // SLA+W transmitted and ACK received
			if ( I2CMsg.nrBytes == 0 )
			{
				__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
				__I2C_SetFlag(I2C_MSG_STOP);
	    			I2CState = I2C_NO_DATA;
			}
			else
			{
    				// Send next data byte
				__I2C_SendData(I2CMsg.buf[I2CMsg.dataCount++]);	
				__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START); // clear SI, STA bit, STO bit clear automatically
			}
			break;
			
		case 0x20 : // SLA+W transmitted, but no ACK received
			__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
			__I2C_SetFlag(I2C_MSG_STOP);
			I2CState = I2C_NACK_ON_ADDRESS;
			break;
			
		case 0x28 : //Data byte transmitted and ACK received

			if (I2CMsg.transMode == WRITE)
			{
				if (I2CMsg.dataCount < I2CMsg.nrBytes)
				{
					__I2C_SendData(I2CMsg.buf[I2CMsg.dataCount++]);	
					__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
				}
				else
				{
					__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
					__I2C_SetFlag(I2C_MSG_STOP);	// data transmit finished, stop transmit
					I2CState = I2C_OK;
				}
			}
			else if (I2CMsg.transMode == WRITETHENREAD)
			{
				if (I2CMsg.dataCount < I2CMsg.nrWriteBytes)
				{
					__I2C_SendData(I2CMsg.buf[I2CMsg.dataCount++]);	
					__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
				}
				else		// send start condition
				{
					__I2C_ClearFlag(I2C_MSG_SI);
					__I2C_SetFlag(I2C_MSG_START);
				}
				
			}
			break;
			
		case 0x30 : // no ACK for data byte
			__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
			__I2C_SetFlag(I2C_MSG_STOP);
			I2CState = I2C_NACK_ON_DATA;
			break;
			
		case 0x38 : // arbitration lost in Slave Address or Data bytes
			//__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);	// Or stop and release bus???
			__I2C_ClearFlag(I2C_MSG_SI);				// Send start again
			__I2C_SetFlag(I2C_MSG_START);
			I2CState = I2C_ARBITRATION_LOST;
			break;
			
		// MASTER RECEIVER FUNCTIONS
		case 0x40 : // ACK for slave address + R
			if (I2CMsg.nrBytes>1)
			{
				__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
				__I2C_SetFlag(I2C_MSG_AA);	// send acknowledge byte
			}
			else
			{
				__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START | I2C_MSG_AA); // return NACK
			}
			break;
			
		case 0x48 : // no ACK for slave address + R
			__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
			__I2C_SetFlag(I2C_MSG_STOP);
			I2CState = I2C_NACK_ON_ADDRESS;
			break;
			
		case 0x50 : // ACK for data byte
			ReadData =  __I2C_ReceiveData();	// for debug
			I2CMsg.buf[I2CMsg.dataCount++] = ReadData & 0xFF;

			if (I2CMsg.dataCount + 1 < I2CMsg.nrBytes)
			{
				__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
				__I2C_SetFlag(I2C_MSG_AA);	// send acknowledge byte
			}
			else
			{
				__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START | I2C_MSG_AA); // return NACK
			}
			break;
			
		case 0x58 : // no ACK for data byte
			ReadData =  __I2C_ReceiveData();	// for debug
			I2CMsg.buf[I2CMsg.dataCount++] = ReadData & 0xFF;
			
			__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
			__I2C_SetFlag(I2C_MSG_STOP);
			I2CState = I2C_OK;
			break;
			
		default : // undefined error
//			__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START | I2C_MSG_AA);
//			__I2C_SetFlag(I2C_MSG_STOP);
//			I2CState = I2C_ERROR;
			break;
	} // switch - I2C_I2STAT & 0xF8

	return ;
}

/*************************************************************************
 * Function Name: I2C_HandleSlaveState
 * Parameters: void 
 * Return: void
 * Description: Slave mode state handler for I2C bus.
 *
 *************************************************************************/
void I2C_HandleSlaveState(void)
{
	unsigned long I2Cstatus = I2C_I2STAT & 0xF8;

	switch (I2Cstatus)
	{
		case 0x60: // own SLA+W received, Ack returned
		case 0x68: // Addressed as slave
		case 0x70: // General call received, Ack returned
		case 0x78:
			I2CMsg.dataCount = 0;
			if (I2CMsg.nrBytes > 1)	// return ACK on first byte
			{
				__I2C_ClearFlag(I2C_MSG_SI);
				__I2C_SetFlag(I2C_MSG_AA);
			}
			else		// return NACK on first byte
			{
				__I2C_ClearFlag(I2C_MSG_AA | I2C_MSG_SI);
			}
			I2CState = I2C_BUSY; // Data will be received
			break;
			
		case 0x80:
		case 0x90: // Data received, ACK returned
			I2CMsg.buf[I2CMsg.dataCount++] = __I2C_ReceiveData();// read data
			if (I2CMsg.dataCount == I2CMsg.nrBytes)
			{
				__I2C_ClearFlag(I2C_MSG_AA | I2C_MSG_SI);	// return NACK on next byte
			}
			else
			{
				__I2C_ClearFlag(I2C_MSG_SI);
				__I2C_SetFlag(I2C_MSG_AA);	// return ACK on next byte
			}
			break;
			
		case 0x88:
		case 0x98: // received, NACK returned
			__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
			__I2C_SetFlag(I2C_MSG_AA);	// clr SI and STA, set AA
			I2CState = I2C_SLAVE_ERROR;
			break;
			
		case 0xA0: // STOP or REP.START received, addressed as slave
			__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
			__I2C_SetFlag(I2C_MSG_AA);	// clr SI and STA, set AA
			I2CState = I2C_OK;
			break;

		// SLAVE TRANSMIT FUNCTIONS
		case 0xA8: // Addressed as slave transmitter
		case 0xB0: // Arb. lost as MST, addressed as slave transmitter
			I2CMsg.dataCount = 0;
			__I2C_SendData(I2CMsg.buf[I2CMsg.dataCount++]);	// Transmit next data, restart
			if (I2CMsg.dataCount >= I2CMsg.nrBytes)
			{
				__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_AA);
			}
			else
			{
				__I2C_ClearFlag(I2C_MSG_SI);
				__I2C_SetFlag(I2C_MSG_AA);
			}
			I2CState = I2C_BUSY;
			break;
			
		case 0xB8: // Data transmitted, ACK received
			__I2C_SendData(I2CMsg.buf[I2CMsg.dataCount++]);  // Transmit next data
			if (I2CMsg.dataCount >= I2CMsg.nrBytes)
			{
				__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_AA);
			}
			else
			{
				__I2C_ClearFlag(I2C_MSG_SI);
				__I2C_SetFlag(I2C_MSG_AA);
			}
			break;
			
		case 0xC0: // Data transmitted, NOT ACK received
			__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
			__I2C_SetFlag(I2C_MSG_AA);			
			I2CState = I2C_SLAVE_ERROR;
			break;
			
		case 0xC8:	// Last data byte in I2CDAT has been transmitted (AA=0); ACK has been received. 
			__I2C_ClearFlag(I2C_MSG_SI | I2C_MSG_START);
			__I2C_SetFlag(I2C_MSG_AA);	
			I2CState = I2C_OK;
			break;
			
		default:
			break;
	}
}

/*************************************************************************
 * Function Name: I2C_Interrupt
 * Parameters: void 
 * Return: void
 * Description: Interrupt handler for I2C.
 *************************************************************************/
__irq void I2C_ISR(void)
{
	if (I2CMode == I2C_MASTER)
		I2C_HandleMasterState();	// Master Mode
	else
		I2C_HandleSlaveState();		// Slave Mode

	VICVectAddr = 0;
}

⌨️ 快捷键说明

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