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

📄 i2c.c

📁 EEPROM芯片驱程
💻 C
字号:
//sla:器件地址,suda:子地址,*dat:接收或发送缓冲,count:接收或发送的字节数,bs:0接收或1发送,bytes:子地址 1为16bit 0为8bit

#include <reg764.h>
#include <intrins.h>


sbit SDA=P1^3;
sbit SCL=P1^2;

void Nop()  	     { _nop_();_nop_();_nop_();_nop_(); }			//空指令大于4.7us
void Start_I2c(void) { SDA=1; SCL=1; Nop(); SDA=0; Nop(); SCL=0; SDA=1; }	//起动总线
void Stop_I2c(void)  { SDA=0; Nop(); SCL=1; Nop(); SDA=1; }			//结束总线

/******************************************
sbit a0=ACC^0;
sbit a1=ACC^1;
sbit a2=ACC^2;
sbit a3=ACC^3;
sbit a4=ACC^4;
sbit a5=ACC^5;
sbit a6=ACC^6;
sbit a7=ACC^7;

bit  SendByte(unsigned char dat)
{
	ACC=dat;
	SDA=a7;SCL=1;SCL=0;
	SDA=a6;SCL=1;SCL=0;
	SDA=a5;SCL=1;SCL=0;
	SDA=a4;SCL=1;SCL=0;
	SDA=a3;SCL=1;SCL=0;
	SDA=a2;SCL=1;SCL=0;
	SDA=a1;SCL=1;SCL=0;
	SDA=a0;SCL=1;SCL=0;
	SDA=1;SCL=1;
	CY=SDA;
 	SCL=0;
 	return CY;
}
unsigned char RcvByte(bit i)
{
	SCL=1;a7=SDA;SCL=0;
	SCL=1;a6=SDA;SCL=0;
	SCL=1;a5=SDA;SCL=0;
	SCL=1;a4=SDA;SCL=0;
	SCL=1;a3=SDA;SCL=0;
	SCL=1;a2=SDA;SCL=0;
	SCL=1;a1=SDA;SCL=0;
	SCL=1;a0=SDA;SCL=0;
	SDA=i; SCL=1; SCL=0; SDA=1;
	return(ACC);
}

*********************************************************/

bit  SendByte(unsigned char c)	//字节发送
{
	unsigned char i;
	for(i=8;i;i--)
	{
		c<<=1;		//无论C51怎样实现这个操作,始终会使CY=c^7;
		SDA=CY;
		SCL=1; Nop();
		SCL=0; Nop();
	}
	SDA=1; Nop();
	SCL=1; Nop();
	CY=SDA;
 	SCL=0; Nop();
 	return CY;
}
unsigned char  RcvByte(bit a)	//字接接收
{
	register char dat, i=8;
	while(i--)
	{
		SCL=1; Nop();
		dat=(dat<<1)|SDA;
		SCL=0; Nop();
	}
	SDA=a; SCL=1; Nop(); SCL=0; SDA=1; Nop();	//应答
	return dat;
}
void delay_i2c(void)		// >100us
{
	unsigned char i=100;	//200us
	while(i--) ;
}

/***************************************************有器件地址,立即地址多字节读写 */
bit I2C_A(unsigned char sla,unsigned char data *dat,bit bs,unsigned char count)
{
	unsigned char i=255;
	while(i--)
	{
		if(i!=254) delay_i2c();
		Start_I2c();                		//启动总线
		if(SendByte(sla|(~bs))) continue;	//发送器件地址
		while(count--)
		{
			if(!bs) { *dat=RcvByte(count?0:1); }	//读取数据
			else	if(SendByte(*dat++)) return 0;	//发送数据
		}
		Stop_I2c();                 		//结束总线
		return 1;
	}
	return 0;
}

/***************************************************有器件地址,有子地址多字节读写 */
bit I2C_B(unsigned char sla,unsigned int suba,unsigned char data *dat,bit bs,bit bytes,unsigned char count)
{
	unsigned char i=255;
	while(i--)
	{
		if(i!=254) delay_i2c();
		Start_I2c();					//启动总线
 		if(bytes)
 		{
 			if(SendByte(sla))	continue;	//发送器件地址
 			if(SendByte(suba>>8))	continue;	//发送器件子地址	16bit
 		}
 		else	if(SendByte(((suba&0x77f)>>7|sla))) continue;	//发送器件地址
		if(SendByte(suba))	continue;			//发送器件子地址	16bit & 8bit
		if(!bs)
		{
			Start_I2c();
			if(bytes)
			{
				if(SendByte(sla+1))	continue;	//发送器件地址
			}
			else	if(SendByte(((suba&0x77f)>>7|(sla+1)))) continue;
		}
		while(count--)
		{
			if(!bs) { *dat++=RcvByte(count?0:1); }	//接收数据
			else	if(SendByte(*dat++)) return 0;	//发送数据
		}
		Stop_I2c();					//结束总线
		return 1;
	}
	return 0;
}
/*************************************************** END */

⌨️ 快捷键说明

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