📄 lpc_i2c.c
字号:
{
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 + -