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

📄 i2c_if.c

📁 I2C Serial Data Interface Module for Silabs C8051F133
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************  FUNCTION MODULE:           i2c_if.c**  I2C Serial Data Interface Module for Silabs C8051F133************************************************************************  DESCRIPTION:**  Serial I2C/SMBus bus access.**	This module is believed to be able to talk to any I2C compliant device.*	It has been tested with:*		- X64645 EEPROM (obsolete in 2003)*		- M24C64 EEPROM*		- MAX518 DAC*		- MAX5821 DAC*		- DS1629 Real Time Clock*		- MAX1609 parallel I/O extender**	Note: this module includes two versions:*	1) a version using hardware transceiver and*	2) a version using bit-banging.**	Define appropriate compilation option I2C_HARDWARE or I2C_BIT_BANGED***********************************************************************/#define  I2C_HARDWARE//#define I2C_BIT_BANGED/***  REVISION LOG (don't use TABs for rev log):**  Date     Name              Version  Reason*  -------  ----------------  -------  -------------------------------*  08-31-05 E.Burzic/D.Juges  0.0.1    Initial design from Silabs and Internet*  09-30-05 E.Burzic/D.Juges  0.2.1    bit-banged or hardware options*********************************************************************//*--------------------------------------------------------------------**  INCLUDE FILES*--------------------------------------------------------------------*/#include "f120.h"#include "comdefs.h"#include "i2c_if.h"/*---------------------------------------------------------------------** COMMON CONSTANTS*----------------------------------------------------------------------*/#define ESMB0		2		// SMB interrupt enable bit in sfr EIE1/*---------------------------------------------------------------------** common public variables (used by either version)*---------------------------------------------------------------------*/unsigned char xdata _i2c_error;unsigned char xdata smb_status;/*---------------------------------------------------------------------** COMMON FUNCTION: I2CCheckError()  (used by either version)**	Returns 0 if no error during previous I2C function, a non-zero*	error code otherwise.*---------------------------------------------------------------------*/unsigned char I2CCheckError( void ){	return( _i2c_error );} /* end I2CCheckError() *//*---------------------------------------------------------------------** FUNCTION: I2CClearError()*----------------------------------------------------------------------*//*void I2CClearError( void ){	_i2c_error = 0;} /* end I2CClearError() */#ifdef I2C_HARDWARE/*---------------------------------------------------------------------**	CONSTANTS*---------------------------------------------------------------------*/#define I2C_INIT    0x40	// enable SMB transceiver#define AA_BIT      0x04#define STO_BIT     0x10#define STA_BIT     0x20/*--------------------------------------------------------------------**   SMBus states for Master Tx or Rx:**   MT = Master Transmitter (Tx)*   MR = Master Receiver (Rx)*   ADD = Address transmitted*   DB = Data Byte transmitted/received*----------------------------------------------------------------------*/#define  SMB_BUS_ERROR  0x00        // (all modes) BUS ERROR#define  SMB_START      0x08        // (MT & MR) START transmitted#define  SMB_RP_START   0x10        // (MT & MR) repeated START#define  SMB_MTADDACK   0x18        // (MT) Slave address + W transmitted;                                    //  ACK received#define  SMB_MTADDNACK  0x20        // (MT) Slave address + W transmitted;                                    //  NACK received#define  SMB_MTDBACK    0x28        // (MT) data byte transmitted; ACK rec'vd#define  SMB_MTDBNACK   0x30        // (MT) data byte transmitted; NACK rec'vd#define  SMB_MTARBLOST  0x38        // (MT) arbitration lost#define  SMB_MRADDACK   0x40        // (MR) Slave address + R transmitted;                                    //  ACK received#define  SMB_MRADDNACK  0x48        // (MR) Slave address + R transmitted;                                    //  NACK received#define  SMB_MRDBACK    0x50        // (MR) data byte rec'vd; ACK transmitted#define  SMB_MRDBNACK   0x58        // (MR) data byte rec'vd; NACK transmitted#define BUF_LEN				14unsigned char xdata buffer[BUF_LEN];	// ***TESTunsigned char data smb_buf_ndx;			// ***TEST/* ----- local function prototypes ----- */void clearbuffer( void );/*=====================================================================**   GENERIC I2C FUNCTIONS*=====================================================================*//*---------------------------------------------------------------------**  I2CSendAddr()**   addr is an address between 0 and 255*   rd is either WRITE or READ**   - initiates START condition*   - send device select address, with appropriate R/W bit as provided in rd*   - wait for acknowledge from device*   - if timeout before acknlowledge is received, set error flag*---------------------------------------------------------------------*/void I2CSendAddr( unsigned char addr, unsigned char rd ){	int xdata i=0;	EA = FALSE;                     // Disable global interrupt.	if( ! rd ){		clearbuffer();		SMB0CN = I2C_INIT;               /* SIO1 enable, with bit frequency set.         */	}	_i2c_error  = 0;                /* Clear error flag.                            */	smb_status = 0;	SMB0CN = I2C_INIT | STA_BIT;     /* SIO1 send START.                             */	do{		i++;	}while( (! SI) && i>0 );        /* Hold here until Serial Interrupt FLag or     *///	while( SI == 0 );                                    /* counter rollover.                            */	if( SMB0STA != SMB_START && SMB0STA != SMB_MTDBACK &&		SMB0STA != SMB_RP_START ){		smb_status= SMB0STA;		_i2c_error = 0x01;				// START not transmitted?		I2CSendStop();		EA = TRUE;		return;	}	if( rd )                        /* I2C address fixup.                           */		addr++;	SMB0DAT = addr;                  /* Load address into Data Register  (which      */	SMB0CN = I2C_INIT;               /* intitiates transfer), SMB enabled            */	i = 0;	do{		i++;	}while( (! SI) && (i) );        // Hold here until Serial Interrupt FLag or                                    // counter rollover.	if( SMB0STA == SMB_MTADDNACK ) 	// SLA + (W || R) has been transmitted,	 											// NOT ACK has been received		_i2c_error |= 0x02;         // set error #2	if( SMB0STA == SMB_MRADDNACK )		_i2c_error |= 0x04;	EA = TRUE;                      // Enable global interrupt.} /* end I2CSendAddress() *//*---------------------------------------------------------------------**  I2CSendByte()**   Send Byte and wait for acknowledge*   Set error flag if timeout before acknowledge received.*---------------------------------------------------------------------*/void I2CSendByte( unsigned char byte_data ){	int xdata i=0;	EA = FALSE;	SMB0DAT = byte_data;	SMB0CN = I2C_INIT;          // Start Tx	do{		i++;	}while( (! SI) && i>0 );   // wait for Tx done or timeout	if( SMB0STA != SMB_MTDBACK ) // No ACK received after sending data?		_i2c_error |= 0x08;	EA = TRUE;} /* end I2CSendByte() *//*---------------------------------------------------------------------**  I2CGetByte()**   Receive Byte and acknowledge*---------------------------------------------------------------------*/unsigned char I2CGetByte( void ){	int xdata i = 0;	EA = FALSE;                     // Disable global interrupt	SMB0CN = I2C_INIT | AA_BIT;  /* SIO1 Enable, with ACK.   */	do{		i++;	}while( (! SI) && i>0 );	if( !i )                        /* SI never turned on?      */		_i2c_error |= 0x10;         /*  Yes, set error #4.      */	EA = TRUE;                      /* Enable global interrupt. */	return( SMB0DAT );} /* end I2CGetByte() *//*---------------------------------------------------------------------** FUNCTION: I2CGetLastByte()**   Receive byte and NAK*----------------------------------------------------------------------*/unsigned char I2CGetLastByte( void ){	int xdata i = 0;	EA = FALSE;	SMB0CN = I2C_INIT;           /* SIO1 Enable, no ACK.     */	do{		i++;	}while( (! SI) && i>0 );	if( !i )                        /* SI never turned on?      */		_i2c_error &= 0x20;         /*  Yes, set error #4.      */	EA = TRUE;                      /* Enable global interrupt. */	return( SMB0DAT );} // end I2CGetLastByte()/*---------------------------------------------------------------------**  I2CSendStop()*---------------------------------------------------------------------*/void I2CSendStop( void ){	char xdata i = 0;	SMB0CN = I2C_INIT | STO_BIT; /* SIO1 Enable,  generate STOP. */	do{		i++;	}while( i>0 );	// wait a little	SMB0CN = 0;		// reset transceiver} /* end I2CSendStop() *//*---------------------------------------------------------------------** I2C_Init()*----------------------------------------------------------------------*/void I2C_Init( void ){	SMB0CN = I2C_INIT;			// enable SMBus transceiver	SMB0CR = -60;				// 100 kHz	EIE1 &= ~ESMB0;				// disable SMB interrupts	XBR0 |= 0x01;				// enable SMBus crossbar//	SMB0CN   = I2C_INIT;     /* SIO1 enable, with bit frequency set.     */} /* end I2C_Init() *//*-----------------------------------------------------------------------------------** FUNCTION: clearbuffer)*------------------------------------------------------------------------------------*/void clearbuffer( void ){	char i;	for(i=0;i<BUF_LEN;i++)		buffer[i] = 0;	smb_buf_ndx = 0;} /* end clearbuffer() */#endif // I2C_HARDWARE#ifdef I2C_BIT_BANGED/*---------------------------------------------------------------------** Ports** Note: make sure these bits are set as Open Collector (default) outputs*---------------------------------------------------------------------*/sbit SCL  =     P0_3;    // I2C Clocksbit SDA  =     P0_2;    // I2C Data/*---------------------------------------------------------------------** Error Codes (_i2c_error)*	0	No error*	1	no acknowledge from Slave*	2	no address ack*	4	no data ack*----------------------------------------------------------------------*//*---------------------------------------------------------------------** Private Functions Prototypes*----------------------------------------------------------------------*/void i2c_delay( void );                 // Wait for 5祍 (for 100kHz operation)void i2c_start( void );                 // Geneate I2C START conditionvoid i2c_stop( void );                  // Geneate I2C STOP conditionvoid i2c_ack( void );                   // Geneate I2C MASTER ACKvoid i2c_nack( void );                  // Geneate I2C MASTER NACKunsigned char i2c_write( unsigned char value ); 	// Write a character via I2Cunsigned char i2c_check( void );             // Check an ACK from SLAVEunsigned char i2c_read( void );              // Read a character via I2C// END Private Function Prototypes ======================================/* ===== code ===== *//*---------------------------------------------------------------------**  I2CSendAddr()**	addr is an even number between 0 and 254*	rd is either WRITE (0) or READ (1)**	- initiates START condition*	- send device select address, with appropriate R/W bit as provided in rd*	- wait for acknowledge from device*	- if timeout before acknlowledge is received, set error flag*---------------------------------------------------------------------*/void I2CSendAddr( unsigned char addr, unsigned char rd ){	_i2c_error = 0;	i2c_start();	if( i2c_write( addr | rd ) != 0 )		_i2c_error = 0x02;} /* end I2CSendAddr() *//*---------------------------------------------------------------------**  I2CSendByte()**	Send Byte and wait for acknowledge*	Set error flag if timeout before acknowledge received.*---------------------------------------------------------------------*/void I2CSendByte( unsigned char byte_data ){	if( i2c_write( byte_data ))

⌨️ 快捷键说明

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