📄 i2c_if.c
字号:
_i2c_error |= 0x04;} /* end I2CSendByte() *//*---------------------------------------------------------------------** FUNCTION: I2CGetByte()** Get one byte and acknowledge*----------------------------------------------------------------------*/unsigned char I2CGetByte( void ){ unsigned char result; result = i2c_read(); i2c_ack(); i2c_stop(); return( result );} /* end I2CGetByte() *//*---------------------------------------------------------------------** FUNCTION: I2CGetLastByte()** Get one byte and do not acknowledge (this stops transfer from* the slave)*----------------------------------------------------------------------*/unsigned char I2CGetLastByte( void ){ unsigned char result; result = i2c_read(); i2c_nack(); i2c_stop(); return( result );} /* end I2CGetLastByte() *//*---------------------------------------------------------------------** I2CSendStop()*---------------------------------------------------------------------*/void I2CSendStop( void ){ i2c_stop();} /* end I2CSendStop() *//*---------------------------------------------------------------------** FUNCTION: I2C_Init()*----------------------------------------------------------------------*/void I2C_Init( void ){ XBR0 &= ~0x01; // disable SMBus from crossbar EIE1 &= ~ESMB0; // disable SMB interrupts (to be sure) ENSMB = 0; // disable SMBus transceiver} /* end I2C_Init() *//********************************************************************//* Function : i2c_delay() SUB *//*------------------------------------------------------------------*//* Description : This subroutine waits for about 5uS. *//* (Low-level I2C routine) *//*------------------------------------------------------------------*//* Author : Thorsten Godau NT8 *//* (Based upon U24C08 EEPROM programming with C51 by *//* Dimitry S. Obukhov dso@usa.net in 1996/97) *//*------------------------------------------------------------------*//* Input : none *//*------------------------------------------------------------------*//* Returnvalue : none *//*------------------------------------------------------------------*//* History : 11/99 V1.0 Basic routine *//* 11/03 Changed for MSC1210Y5 (D. Juges) *//* 09/05 Changed for Silabs C8051F133 (D. Juges) *//********************************************************************/void i2c_delay( void ){ uchar data i; EA = 0; // Disable all interrupts for a accurate timing for( i=0; i<20; i++ ) ; EA = 1; // Enable all interrupts return;} /* end i2c_delay() *//********************************************************************//* Function : i2c_start() SUB *//*------------------------------------------------------------------*//* Description : This subroutine generates a I2C START condition. *//* (Low-level I2C routine) *//*------------------------------------------------------------------*//* Author : Thorsten Godau NT8 *//* (Based upon U24C08 EEPROM programming with C51 by *//* Dimitry S. Obukhov dso@usa.net in 1996/97) *//*------------------------------------------------------------------*//* Input : none *//*------------------------------------------------------------------*//* Returnvalue : none *//*------------------------------------------------------------------*//* History : 11/99 V1.0 Basic routine *//* *//********************************************************************/void i2c_start( void ){ EA = 0; // Disable all interrupts for accurate timing // Force defined state of SCL and SDA SCL = 1; // Release SCL SDA = 1; // Release SDA i2c_delay(); // Force 5祍-delay // Generate START condition SDA = 0; i2c_delay(); // Force 5祍-delay SCL = 0; i2c_delay(); EA = 1; // Enable all interrupts // I2C Busy return;} /* end i2c_start() *//********************************************************************//* Function : i2c_stop() SUB *//*------------------------------------------------------------------*//* Description : This subroutine generates a I2C STOP condition. *//* (Low-level I2C routine) *//*------------------------------------------------------------------*//* Author : Thorsten Godau NT8 *//* (Based upon U24C08 EEPROM programming with C51 by *//* Dimitry S. Obukhov dso@usa.net in 1996/97) *//*------------------------------------------------------------------*//* Input : none *//*------------------------------------------------------------------*//* Returnvalue : none *//*------------------------------------------------------------------*//* History : 11/99 V1.0 Basic routine *//* *//********************************************************************/void i2c_stop( void ){ EA = 0; // Disable all interrupts for a accurate timing // Generate STOP condition SDA = 0; i2c_delay(); // Force 5祍-delay SCL = 1; // Release SCL i2c_delay(); // Force 5祍-delay SDA = 1; // Release SDA EA = 1; // Enable all interrupts // I2C Idle return;} /* i2c_stop() *//********************************************************************//* Function : i2c_ack() SUB *//*------------------------------------------------------------------*//* Description : This subroutine generates a I2C MASTER ACK. *//* MASTER clock synchronisation (needed to handle *//* SLAVE clock streching) is supported. *//* (Low-level I2C routine) *//*------------------------------------------------------------------*//* Author : Thorsten Godau NT8 *//* (Based upon U24C08 EEPROM programming with C51 by *//* Dimitry S. Obukhov dso@usa.net in 1996/97) *//*------------------------------------------------------------------*//* Input : none *//*------------------------------------------------------------------*//* Returnvalue : none *//*------------------------------------------------------------------*//* History : 11/99 V1.0 Basic routine *//* *//********************************************************************/void i2c_ack( void ){ EA = 0; // Disable all interrupts for a accurate timing // Generate ACK SDA = 0; SCL = 1; // Release SCL while( SCL == 0 ) ; // Synchronize clock i2c_delay(); // Force 5祍-delay SCL = 0; // Force a clock cycle EA = 1; // Enable all interrupts return;} /* end i2c_ack() *//********************************************************************//* Function : i2c_nack() SUB *//*------------------------------------------------------------------*//* Description : This subroutine generates a I2C MASTER NACK. *//* MASTER clock synchronisation (needed to handle *//* SLAVE clock streching) is supported. *//* (Low-level I2C routine) *//*------------------------------------------------------------------*//* Author : Thorsten Godau NT8 *//* (Based upon U24C08 EEPROM programming with C51 by *//* Dimitry S. Obukhov dso@usa.net in 1996/97) *//*------------------------------------------------------------------*//* Input : none *//*------------------------------------------------------------------*//* Returnvalue : none *//*------------------------------------------------------------------*//* History : 11/99 V1.0 Basic routine *//* *//********************************************************************/void i2c_nack( void ){ EA = 0; // Disable all interrupts for a accurate timing // Generate NACK SDA = 1; // Release SDA SCL = 1; // Release SCL while( SCL == 0 ) ; // Synchronize clock i2c_delay(); // Force 5祍-delay SCL = 0; // Force a clock cycle EA = 1; // Enable all interrupts return;} /* end i2c_nack() *//********************************************************************//* Function : i2c_check() SUB *//*------------------------------------------------------------------*//* Description : This subroutine checkes an I2C SLAVE ACK. *//* MASTER clock synchronisation (needed to handle *//* SLAVE clock streching) is supported. *//* (Low-level I2C routine) *//*------------------------------------------------------------------*//* Author : Thorsten Godau NT8 *//* (Based upon U24C08 EEPROM programming with C51 by *//* Dimitry S. Obukhov dso@usa.net in 1996/97) *//*------------------------------------------------------------------*//* Input : none *//*------------------------------------------------------------------*//* Returnvalue : unsigned char -> 0 : acknowledge from Slave *//* 1 : no acknowledge from Slave *//*------------------------------------------------------------------*//* History : 11/99 V1.0 Basic routine *//* *//********************************************************************/unsigned char i2c_check( void ){ EA = 0; // Disable all interrupts for accurate timing SDA = 1; // Release SDA SCL = 1; // Release SCL while( SCL == 0 ) ; // Synchronize clock i2c_delay(); // Force 5祍-delay if( SDA ){ // SDA is high SCL = 0; // Force a clock cycle _i2c_error |= 1; return( 1 ); // No acknowledge from Slave } SCL = 0; // Force a clock cycle i2c_delay(); // Force 5祍-delay EA = 1; // Enable all interrupts return( 0 ); // Acknowledge from Slave} /* end i2c_check() *//********************************************************************//* Function : i2c_write(value) SUB *//*------------------------------------------------------------------*//* Description : This subroutine writes a character to I2C. *//* MASTER clock synchronisation (needed to handle *//* SLAVE clock streching) is supported. *//* (Low-level I2C routine) *//*------------------------------------------------------------------*//* Author : Thorsten Godau NT8 *//* (Based upon U24C08 EEPROM programming with C51 by *//* Dimitry S. Obukhov dso@usa.net in 1996/97) *//*------------------------------------------------------------------*//* Input : unsigned char value -> data to I2C device *//*------------------------------------------------------------------*//* Returnvalue : unsigned char -> 0 : Acknowledge received *//* 1 : No acknowledge received *//*------------------------------------------------------------------*//* History : 11/99 V1.0 Basic routine *//* *//********************************************************************/unsigned char i2c_write( unsigned char value ){ unsigned char idata c; // Bitcounter EA = 0; // Disable all interrupts for a accurate timing for( c = 8; c > 0; c-- ){ if( value & 0x80 ) SDA = 1; else SDA = 0; SCL = 1; // Release SCL SCL = 1; // make it a little longer SCL = 1; while( SCL == 0 ) ; // Synchronize clock i2c_delay(); // Force 5祍-delay SCL = 0; // Force a clock cycle i2c_delay(); value <<= 1; // Prepare next bit for transmission } EA = 1; // Enable all interrupts // Generate a 9th clock cycle and check ACK from SLAVE // Return the result return( i2c_check() );} /* end i2c_write() *//********************************************************************//* Function : i2c_read() SUB *//*------------------------------------------------------------------*//* Description : This subroutine reads a character from I2C. *//* MASTER clock synchronisation (needed to handle *//* SLAVE clock streching) is supported. *//* (Low-level I2C routine) *//*------------------------------------------------------------------*//* Author : Thorsten Godau NT8 *//* (Based upon U24C08 EEPROM programming with C51 by *//* Dimitry S. Obukhov dso@usa.net in 1996/97) *//*------------------------------------------------------------------*//* Input : none *//*------------------------------------------------------------------*//* Returnvalue : unsigned char -> data from I2C device *//*------------------------------------------------------------------*//* History : 11/99 V1.0 Basic routine *//* *//********************************************************************/unsigned char i2c_read( void ){ unsigned char idata r = 0; // Return value with read I2C byte unsigned char idata c = 0; // Bit counter EA = 0; // Disable all interrupts for a accurate timing for( c = 8; c > 0; c-- ){ SDA = 1; // Release SDA SCL = 1; // Release SCL while( SCL == 0 ) ; // Synchronize clock i2c_delay(); // Force 5祍-delay r <<= 1; // Shift left the result if( SDA ) r |= 0x01; // Set actual SDA state to LSB SCL = 0; // Force a clock cycle i2c_delay(); // Force 5祍-delay } EA = 1; // Enable all interrupts // ACK or NACK from MASTER must be generated outside this routine return( r );} /* end i2c_read() */#endif // end i2c bit-banged
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -