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

📄 i2c.c

📁 contain many examples code for I2c,UART,string ,digital convert, read/write to EEprom in microchip P
💻 C
字号:
#include	<pic.h>
#include	"c:\test\delay.c"
#include 	"c:\test\i2c.h"

#define sim_on
/*
 * 	Send stop condition
 * 	  - data low-high while clock high
 */

void
i2c_Stop(void)
{
	/* assume SCL is high on entry */

	SCL_DIR = I2C_OUTPUT;

	SDA = 0;			/* ensure the data is low first */
	SDA_DIR = I2C_OUTPUT;

	DelayUs(I2C_TM_DATA_SU);
	SCL_DIR = I2C_INPUT;		/* float clock high */
	DelayUs(I2C_TM_STOP_SU);
	SDA = 1;			/* the low->high data transistion */
	DelayUs(I2C_TM_BUS_FREE);	/* bus free time before next start */

	return;
}

/*
 * 	Send (re)start condition
 * 	  - ensure data is high then issue a start condition
 * 	  - see also i2c_Start() macro
 */

void
i2c_Restart(void)
{

	
	SDA_DIR = I2C_OUTPUT;
	SCL_DIR = I2C_OUTPUT;
	
	SCL = 1;			/* ensure clock is low */
	SDA = 1;			/* ensure data is high */
	asm("nop");
	SDA = 0;		/* the high->low transition */
	asm("nop");
	SCL=0;
	return;
}

/*
 * 	Send a byte to the slave
 * 	  - returns true on error
 */

unsigned char
i2c_SendByte(unsigned char byte)
{
	signed char i;
	
	for(i=7; i>=0; i--)
	{
	
		SCL_DIR = I2C_OUTPUT;		/* drive clock low */
		SCL=1;
		SDA_DIR = I2C_OUTPUT;
		SDA = ((byte>>i) & 0x01);	/* bit to send */
		SCL=0;
		
		//DelayUs(I2C_TM_DATA_SU);
		//asm("nop");	
		
		
	}

	return 1;

}

/*
 * 	send an address and data direction to the slave
 * 	  - 7-bit address (lsb ignored)
 * 	  - direction (FALSE = write ) 
 */

unsigned char
i2c_SendAddress(unsigned char address, unsigned char rw)
{
	return i2c_SendByte(address | (rw?1:0));
}

/*
 * 	Check for an acknowledge
 * 	  - returns ack or ~ack, or ERROR if a bus error
 */

signed char
i2c_ReadAcknowledge(void)
{
	unsigned char ack;

	//SCL_DIR = I2C_OUTPUT;
	SDA_DIR = I2C_INPUT;			/* disable data line - listen for ack */

	//DelayUs(I2C_TM_SCL_TO_DATA);		/* SCL low to data out valid */
	asm("nop");
	
	SCL=1;
	asm("nop");
	SCL=0;
	
	ack = SDA;				/* read the acknowledge */
	if(ack!=0)  
		{
		#ifndef  sim_on
		putst("  yes ! got ack \n");
		#endif
		asm("nop");		
		}
	else  
		{
		#ifndef  sim_on
		putst("  sorry ! can got ack  :~   \n");
		#endif
		asm("nop");	

		}
	

}

/*
 * 	Read a byte from the slave
 * 	  - returns the byte, or I2C_ERROR if a bus error
 */
unsigned char byte = 0;
int
i2c_ReadByte(void)
{
	unsigned char i;
	for(i=0; i<8; i++)
	{
		SCL_DIR = I2C_OUTPUT;
		//DelayUs(I2C_TM_SCL_LOW);	/* min clock low  period */
		asm("nop");
		SDA_DIR = I2C_INPUT;		/* release data line */
	

		asm("nop");
	
		byte = byte << 1;		/* read the next bit */
		byte |= SDA;
	}
	
	return (int)byte;
}

/*
 * 	Send an (~)acknowledge to the slave
 * 	  - status of I2C_LAST implies this is the last byte to be sent
 */

void
i2c_SendAcknowledge(unsigned char status)
{
	SCL_DIR = I2C_OUTPUT;
	
	SDA = status?0:1;			/* drive line low -> more to come */
	SDA_DIR = I2C_OUTPUT;
	
	DelayUs(I2C_TM_DATA_SU);
	
	SCL_DIR = I2C_INPUT;			/* float clock high */
	DelayUs(I2C_TM_SCL_HIGH);
	
	return;
}

/*
 * 	Send a byte to the slave and acknowledges the transfer
 * 	  - returns I2C_ERROR, ack or ~ack
 */

signed char
i2c_PutByte(unsigned char data)
{
	if(i2c_SendByte(data))
		return I2C_ERROR;
	return i2c_ReadAcknowledge();	/* returns ack, ~ack */
}

/*
 * 	Get a byte from the slave and acknowledges the transfer
 * 	  - returns true on I2C_ERROR or byte
 */

int
i2c_GetByte(unsigned char more)
{
	uchar byte;

	if((byte = i2c_ReadByte()) == I2C_ERROR)	
		return I2C_ERROR;

	i2c_SendAcknowledge(more);
	
	return byte;
}

/*
 * 	Send an array of bytes to the slave and acknowledges the transfer
 * 	  - returns number of bytes not successfully transmitted
 */

int
i2c_PutString(const unsigned char *str, unsigned char length)
{
	signed char error;

	while(length)
	{
		if((error = i2c_PutByte(*str)) == I2C_ERROR)
			return -(int)length;		/* bus error */
		else
			if(error)
				return (int)length;	/* non acknowledge */
		str++;
		length--;
	}
	
	return FALSE;					/* everything OK */
}

/*
 * 	Reads number bytes from the slave, stores them at str and acknowledges the transfer
 * 	  - returns number of bytes not successfully read in
 */

unsigned char
i2c_GetString(unsigned char *str, unsigned char number)
{
	int byte;

	while(number)
	{
		if((byte = i2c_GetByte(number-1)) == I2C_ERROR)
			return number;			/* bus error */
		else
			*str = (unsigned char)byte;
		str++;
		number--;
	}
	
	return FALSE;					/* everything OK */
}

/*
 * 	Opens communication with a device at address. mode
 * 	indicates I2C_READ or I2C_WRITE.
 * 	  - returns TRUE if address is not acknowledged
 */

unsigned char
i2c_Open(unsigned char address, unsigned char mode)
{
	i2c_Start();
	i2c_SendAddress(address, mode);
	if(i2c_ReadAcknowledge())
		return TRUE;
	
	return FALSE;
}
#if 0
	
/*
 * 	wait for the clock line to be released by slow slaves
 * 	  - returns TRUE if SCL was not released after the
 * 	    time out period.
 * 	  - returns FALSE if and when SCL released
 */

unsigned char
i2c_WaitForSCL(void)
{
	/* SCL_DIR should be input here */

	if(!SCL)
	{
		DelayUs(I2C_TM_SCL_TMO);
		/* if the clock is still low -> bus error */
		if(!SCL)
			return TRUE;
	}
	return FALSE;
}
#endif

⌨️ 快捷键说明

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