📄 i2c_driver.c
字号:
#define Chip0 (1)
#define DeviceAdd (0xA0) //10100 000 device address
#define ChipAddress0 (0x00)
#define ChipAddress1 (0x04)
#define PageSize (256)
#define NoOfPages (512)
#define MaxBytes (131072L)
#define AddressBits (17)
#define Read (0x01)
#define Write (0x00)
#define LastPage BIT(17)
//EEPROM Word addressing requires 17 bits data word address.
UDWord EEPROMAddress;
UByte MemPage[PageSize];//page writting globol buffer
UByte LowMemAdd,HighMemAdd,SeventhBitAdd;//address buffers
UByte Data;//single byte write buffer;
UByte DevAdd;
UByte I2CBuff[20];
void I2C0_Handler(void)
{
BYTE StatValue;
/* this handler deals with master read and master write only */
StatValue = I20STAT;
// IENABLE; /* handles nested interrupt */
switch ( StatValue )
{
case 0x08: /* A Start condition is issued. */
//I20DAT = I2CMasterBuffer[0];
I20Dat = I2CBuff[0];//Device Address
I20CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
I2CDataPtr++;
I2CMasterState = I2C_STARTED;
break;
case 0x10: /* A repeated started is issued */
I20Dat = I2CBuff[0];//Device address for repeated start
//this condition is only for master in receive mode.
I20CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
I2CMasterState = I2C_RESTARTED;
break;
case 0x18: /* 0x18 Regardless, it's a ACK */
if(I2CMAsterState == I2C_STARTED)
{
I20DAT = I2CBuff[I2CDataPtr];
I2CDataPtr++;
}
// I2CMasterState = DATA_ACK;
I20CONCLR = I2CONCLR_SIC;
break;
case 0x28: /* Data byte has been transmitted, regardless ACK or NACK */
case 0x30:
if ( WrIndex != I2CWriteLength )
{
I20DAT = I2CMasterBuffer[1+WrIndex]; /* this should be the last one */
WrIndex++;
if ( WrIndex != I2CWriteLength )
{
I2CMasterState = DATA_ACK;
}
else
{
I2CMasterState = DATA_NACK;
if ( I2CReadLength != 0 )
{
I20CONSET = I2CONSET_STA; /* Set Repeated-start flag */
I2CMasterState = I2C_REPEATED_START;
}
}
}
else
{
if ( I2CReadLength != 0 )
{
I20CONSET = I2CONSET_STA; /* Set Repeated-start flag */
I2CMasterState = I2C_REPEATED_START;
}
else
{
I2CMasterState = DATA_NACK;
}
}
I20CONCLR = I2CONCLR_SIC;
break;
case 0x40: /* Master Receive, SLA_R has been sent */
I20CONCLR = I2CONCLR_SIC;
break;
case 0x50: /* Data byte has been received, regardless following ACK or NACK */
case 0x58:
I2CMasterBuffer[3+RdIndex] = I20DAT;
RdIndex++;
if ( RdIndex != I2CReadLength )
{
I2CMasterState = DATA_ACK;
}
else
{
RdIndex = 0;
I2CMasterState = DATA_NACK;
}
I20CONSET = I2CONSET_AA; /* assert ACK after data is received */
I20CONCLR = I2CONCLR_SIC;
break;
case I2STAT_SLA_W_NOACK: /* regardless, it's a NACK */
case I2STAT_SLA_R_NOACK:
I20CONCLR = I2CONCLR_SIC;
I2CMasterState = DATA_NACK;
break;
case I2STAT_ARB_LOST: /* Arbitration lost, in this example, we don't
deal with multiple master situation */
default:
I20CONCLR = I2CONCLR_SIC;
break;
}
//IDISABLE;
VICVectAddr = 0; /* Acknowledge Interrupt */
}
UByte WriteByte(UByte Byte,UDWord Address)
{
UByte retVal=0;
UDWord Timeout=0;
#ifdef Chip0
DevAdd = (DeviceAdd | ChipAddress0 | Write);
#else
DevAdd = (DeviceAdd | ChipAddress1 | Write);
#endif
LowMemAdd = (Address & 0x000000FF);
HighMemAdd = ((Address >> 8) & 0x000000FF);
if(Address & LastPage)
{
DevAdd |= 0x02;
}
I2CDataPtr = 0;
I2CDataLen = 4;
I2CBuff[0] = DevAdd;
I2CBuff[1] = HighMemAdd;
I2CBuff[2] = LowMemAdd;
I2CBuff[3] = Byte;
I2CBuff[4] = 0x00;
if ( I2CStart() != TRUE )
{
I2CStop();
return ( FALSE );
}
while(1)
{
if(I2CMasterState == DATA_NACK)
{
I2CStop();
retVal = 1;
break;
}
if(Timeout >= 0x000FFFFF)
{
retVal = 0;
}
Timeout++;
}
return retVal;
}
void initI2C0(void)
{
UDWord PinSel;
PCONP |= PCI2C0;//Power on I2C0 bit7
//PINSEL1 = (PINSEL1 & I2C0PIN_MASK) | I2C0PIN_SELECT;
PinSel = PINSEL1;
PinSel &= I2C0PIN_MASK;
PinSel |= I2C0PIN_SELECT;
PINSEL1 = PinSel;
I20CONCLR = (I2CONCLR_I2ENC | I2CONCLR_STAC | I2CONCLR_SIC | I2CONCLR_AAC);//Clear flags
I20SCLH = I2CSCLH;
I20SCLL = I2CSCLL;
//write code for enabling IRQ Here
// handler for IRQ is I2C0_Handler
I20CONSET = I2CONSET_I2EN;
}
DWORD I2CStart( void )
{
DWORD timeout = 0;
DWORD retVal = 0;
/*--- Issue a start condition ---*/
I20CONSET = I2CONSET_STA; /* Set Start flag */
/*--- Wait until START transmitted ---*/
while( 1 )
{
if ( I2CMasterState == I2C_STARTED )
{
retVal = TRUE;
break;
}
if ( timeout >= 0x00FFFFFF )
{
retVal = 0;
break;
}
timeout++;
}
return( retVal );
}
DWORD I2CStop( void )
{
DWORD timeout = 0;
DWORD retVal = 0;
I20CONSET = I2CONSET_STO; /* Set Stop flag */
I20CONCLR = I2CONCLR_SIC; /* Clear SI flag */
retVal = 1;
/*--- Wait for STOP detected ---*/
while( I20CONSET & I2CONSET_STO )
{
if ( timeout >= 0x00FFFFFF )
{
retVal = 0;
break;
}
timeout++;
}
return retVal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -