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

📄 i2c._c

📁 sunplus spca514 cdmp3 源码
💻 _C
字号:
/***********************************************************************/




#include <iom163.h>

#include "..\io.h"
#define TRUE   1
#define FALSE  0

#define I2C_MAX_WAIT	110	/* in microseconds */

	#define HOLDING_TIME	10

/*
 * These local functions wait for the other end the set the bit to a
 * certain level.
 */

void I2C_delay(void)
{
 unsigned char i;
 for(i=0;i<20;i++)
 {
 }
}
void I2C_delay1(viod)
{
 unsigned char i;
 for(i=0;i<200;i++)
 {
 };
}
/*static unsigned char wait_sda_lo(void)
{
	int i = I2C_MAX_WAIT/5;
    sda_set_input();
    while(i && is_sda_hi()) {
		i--;
		I2C_delay();		
	}
	sda_set_output();
	return i?TRUE:FALSE;
}*/

static unsigned char wait_sda_hi(void)
{
	unsigned char i = I2C_MAX_WAIT;
    sda_set_input();
    while(i)
	{
	  if(is_sda_hi())
	  { 
	    sda_set_output();
		 return TRUE;
	   }
		i--;
		I2C_delay1();		
	}
	sda_set_output();
	return FALSE;
}

static unsigned char wait_scl_hi(void)
{
	unsigned char i = I2C_MAX_WAIT;

    scl_set_input();
    while(i)
	{
	    if(is_scl_hi())
		{ 
		  scl_set_output();
		  return TRUE;
		}
		i--;
		I2C_delay1();		
	}
	scl_set_output();
	return FALSE;
}

/*
 * This function is called before an I2C transfer is started.  A start
 * condition is signified with a high-to-low transition of SDA while SCL
 * is high.
 */


 unsigned char i2c_start(void)
{

	scl_set_output();
	scl_hi();
					// SEC LEE0216
    I2C_delay();//HOLDING_TIME*3);
    sda_set_output();
    sda_hi();
	I2C_delay();//HOLDING_TIME*3);
	scl_hi();					// SEC LEE0216
    if (!wait_scl_hi())
		return FALSE;

    sda_lo();			/* this triggers the start */
    I2C_delay();//HOLDING_TIME*3);
    scl_lo();
    I2C_delay();//HOLDING_TIME*3);
	return TRUE;
}

/*
 * The function is used to tell the device the the transmission is over.
 * The stop condition is signified by a low-to-high transition of SDA
 * while SCL is high.
 */
 unsigned char i2c_stop(void)
{
    //scl_lo();
    //I2C_delay();//HOLDING_TIME*3);
    sda_lo();
    I2C_delay();//HOLDING_TIME*3);
    scl_hi();
    I2C_delay();//HOLDING_TIME*3);
	if (!wait_scl_hi())
		return FALSE;

    sda_hi();			/* this triggers the stop */
	if (!wait_sda_hi())
		return FALSE;
	scl_lo();
	
    I2C_delay();//HOLDING_TIME*3);

	return TRUE;
}

/*
 * This function sends one byte on the I2C bus. The bits in the byte are
 * sent in the order of the high bit first and the lowest bit last.
 */

 unsigned char i2c_putc(unsigned char d)
{
    unsigned char mask;
    unsigned ack;


    for (mask = 0x80; mask; mask >>= 1)
    {
		if (d & mask)
		    sda_hi();
		 else
		    sda_lo();

		I2C_delay();//HOLDING_TIME);		// SEC LEE0216 
		scl_hi();
	    I2C_delay();//HOLDING_TIME);
		scl_lo();
		//Idelay_us(5);//HOLDING_TIME);
    }

    //sda_hi();			/* ack handshake after every byte */
    sda_set_input();
	I2C_delay();//HOLDING_TIME);

    scl_hi();
    I2C_delay();//HOLDING_TIME);

    if (!is_sda_hi())		/* sda low means an ack */
		ack = TRUE;
    else
		ack = FALSE;

    scl_lo();
    I2C_delay();//HOLDING_TIME);		// SEC LEE0216
    sda_set_output();
    return ack;
}

/*
 * This function is used to get data from another I2C device. The |rdack|
 * parameter is used to tell the device if we want to read more bytes. If
 * |rdack| is true then we want to receive the byte at the next address,
 * otherwise we don't want anymore bytes.
 */

unsigned char i2c_getc(unsigned rdack)
{
    register unsigned char d;
    register unsigned char i;

    //sda_hi();			/* don't drive the data line */
    sda_set_input();
    d=0;
    for (i = 0; i < 8; i++) {
	d <<= 1;

	scl_hi();		/* drive clock high to get data */
	I2C_delay();//HOLDING_TIME);
	
	if (!wait_scl_hi())
		return 0xFF; /* i2c error */

	if (is_sda_hi())
	    d |= 1;		/* bit is a one */

	scl_lo();		/* drive clock back down */
	I2C_delay();//HOLDING_TIME);
    }

    sda_set_output();
    if (rdack)
	sda_lo();		/* send an ack */

    scl_hi();

	if (!wait_scl_hi())
		return 0xFF; /* i2c error */
    scl_lo();

    if (rdack)
	sda_hi();		/* release if set */

    return d;
}


 unsigned char i2c_select_device( unsigned char addr, unsigned char subaddr )
{
	if (i2c_start())
	{

		if (i2c_putc(addr))
		{
		    if (i2c_putc(subaddr))
			{
		      return TRUE;
			}
		}
	};
	return FALSE;
}

/*
 * This function writes address, subaddr, and data on the I2C bus. 
 * The bits in the byte are
 * sent in the order of the high bit first and the lowest bit last.
 */

unsigned char i2c_write(unsigned char addr, 
				   unsigned char subaddr, 
				   unsigned char dat)
{
	unsigned char res;

	if (res = i2c_select_device( addr, subaddr ))
	{ 
		res = i2c_putc(dat);
	};

	/* <<< ZRN SH0125: Modified to return FALSE if an error occured */
	i2c_stop();

	return res;
}
/*
unsigned char i2c_write_string( unsigned char addr, unsigned char subaddr, int count, unsigned char *data )
{
//	int retry = 10;					// SEC LEE0216
//	unsigned char retry = 10;		// SEC LEE0216

	while (count&&ret){
		if (i2c_write(addr, subaddr, *data)){
			subaddr++;
			data++;
			count--;
			retry = 10;
			usleep(10000L);
		}
		else 
			retry--;
		usleep(10000L); // sgjm wait 1ms(us_delay(1000L)-->wait 10ms(usleep(10000L) 
	}
	return retry?TRUE:FALSE;
}
*/
/*
unsigned char i2c_read_string( unsigned char addr, unsigned char subaddr, unsigned char count, unsigned char *data )
{
	
    unsigned char res;	
	if (res = i2c_select_device( addr, subaddr ))
	{ 
		if (!i2c_start())		// another start for read 
		{	

			return 0;
		}
		i2c_putc((unsigned char)(addr|1));		//set up for a read 
		while (--count)
			*data++ = i2c_getc(1);
		*data = i2c_getc(0);
	}
	i2c_stop();


	return res;
}

*/


/*
BOOL i2c_read_string( unsigned char addr, unsigned char subaddr, int count, unsigned char *data )
{
	BYTE i ;

	// set up for reads starting at address 0
	if ( i2c_select_device( addr, subaddr ) ) {
		// send a second start
		i2c_start() ;
		if ( i2c_putc( addr | 1 ) ) {
			for ( i=0 ; i<count ; i++ ) {

				data[i] = ( i2c_getc() ) ;
				if ( i != (count-1) )
					i2c_ack() ;
				else {
					i2c_clock() ;
					i2c_stop() ;
				}
			}
			return ( TRUE ) ;
		}
		else {
			i2c_stop() ;
			return ( FALSE ) ;
		}
	}
	else
		i2c_stop() ;
		return ( FALSE ) ;

}*/

#define PT2314_ADD 0x88


unsigned char pt2314_write(unsigned char data)
{

    register unsigned char res;
	
	//res=i2c_select_device(PT2314_ADD,data);
	
	if (res=i2c_start())
	{
      if (res=i2c_putc(PT2314_ADD))
	  {
	
   		res=i2c_putc(data);
	  
	  }
	 }
	i2c_stop();
	return res;

}

/*
unsigned char pca_read(unsigned char addr,unsigned char *data)
{
	if (!i2c_start())
	{
		return FALSE;
	}
	if (!i2c_putc(addr)){
#ifdef TTY
		printf("Error writing pca_read address\n");
#endif
		return FALSE;
	}
	I2C_delay();
	*data = i2c_getc(0);

	i2c_stop();
	return TRUE;
}

*/

⌨️ 快捷键说明

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