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

📄 i2c.c

📁 一个流量控制仪器的源码
💻 C
字号:
/*******************************************************************
P89C668 单片机硬件I2C 软件包I2C.c 主方式

668 的硬件I2C 接口定义在P1.6,P1.7 上,分别为P1.6=SCL;P1.7=SDA; (开漏输出)
相应寄存器	地址寄存器S1ADR --用于存放自身从地址(从方式时才有用)。
		数据寄存器S1DAT --接收/发送数据用。
		控制寄存器S1CON --用于硬件I2C 的设置使能、启动、结束,
				应答控制,中断标志等。
		状态寄存器S1STA --指示I2C 总线的操作状态码,高5 位有效
				若I2C 中断志置位,可查询此寄存器判断
				总线情况。
				
!此软件包是以查询方式完成各种总线操作的,在使用前应对总线进行检查,并
使用看门狗,以防等待总线而造成死机。

!系统工作主频不要高于12MHz

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

#include <REG668.H> 	/*P89C668 的硬件I2C 定义与552 的一样*/

#define uchar unsigned char



/*******************************************************************
			检查总线是否正常
功能:   进行I2C 总线的初始化前的检查
        如果返回0,表示总线有误。
        如果返回1,表示总线正常。
*******************************************************************/
bit I2C_CheckBus()
{
        SCL=0;
        SDA=1;
        if(SDA==0)
                return(0);      /*SCL、SDA 短路,或SDA被锁为低*/
        
        SCL=1;
        if(SCL==0)
                return(0);      /*SCL 被锁为低*/

        return(1);              /*总线正常*/
}



/*******************************************************************
			申请总线
功能: 进行I2C 总线的初始化--包括时钟速率,I2C 使能,发送起始信号等
*******************************************************************/
void I2C_GetBus()
{
        I2C_CheckBus();
	S1CON=0xc5; 	/*设置时钟为100K MCU 主频为12M ENS1 和AA 置位*/
                        /* 0xc5 = 1100 0101 */
	STA=1; 		/*申请成为主机起动总线*/
	while(SI==0); 	/*等待起始位的发送*/
}

/*******************************************************************
			结束总线
功能: 用于结束总线。
*******************************************************************/
void I2C_Stop()
{
	S1CON=0XD5;            /*结束总线*/
}

/*******************************************************************
			发送数据函数
功能: 用于向总线发送数据。
*******************************************************************/
void I2C_Send(uchar c)
{
	S1DAT=c;
	S1CON=0XC5; 	/*清除SI 位等等*/
	while(SI==0); 	/*等待数据的发送*/
}



/*******************************************************************
			向无子地址器件发送字节数据函数
函数原型: bit I2C_SendByte(uchar sla,ucahr c);
功能: 	从启动总线到发送地址、数据,结束总线的全过程,从器件地址sla,
	待发送的数据c ,如果返回1 表示操作成功,否则操作有误。
********************************************************************/
bit I2C_SendByte(uchar sla,uchar c)
{
	I2C_GetBus();          /*启动总线*/

	I2C_Send(sla);         /*发送器件地址,若无应答则返回*/
	if(S1STA!=0X18)
	{
		S1CON=0XD5;
		return(0);
	}

	I2C_Send(c);           /*发送数据,若无应答则返回*/
	if(S1STA!=0X28)
	{
		S1CON=0XD5;
		return(0);
	}

	S1CON=0XD5;            /*结束总线*/

	return(1);
}


/*******************************************************************
			向有子地址器件发送多字节数据函数
函数原型: bit I2C_SendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 	从启动总线到发送地址、子地址、数据、结束总线的全过程。从器件
	地址sla、子地址suba、发送内容是s、指向的内容发送no个字节。
	如果返回1,表示操作成功,否则操作有误。
********************************************************************/
bit I2C_SendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
	uchar i;
	
	
	I2C_GetBus();          /*启动总线*/
	
	I2C_Send(sla);         /*发送器件地址,若无应答则返回*/
	if(S1STA!=0X18)
	{
		S1CON=0XD5;
		return(0);
	}
	
	I2C_Send(suba);        /*发送器件子地址,若无应答则返回*/
	if(S1STA!=0X28)
	{
		S1CON=0XD5;
		return(0);
	}
	
	for(i=0;i<no;i++)
	{
		I2C_Send(*s);  /*发送数据,若无应答则返回*/
		if(S1STA!=0X28)
		{
			S1CON=0XD5;
			return(0);
		}
		s++;
	} 
	
	S1CON=0XD5; /*结束总线*/
	
	return(1);
}


/*******************************************************************
			向无子地址器件读字节数据函数
函数原型: bit I2C_RcvByte(uchar sla,ucahr *c);
功能: 	从启动总线到发送地址,读数据,结束总线的全过程,从器件地
	址sla、返回值在c。
	如果返回1,表示操作成功,否则操作有误。
********************************************************************/
bit I2C_RcvByte(uchar sla,uchar *c)
{
	I2C_GetBus(); 		/*启动总线*/

	I2C_Send(sla+1); 	/*发送器件地址,若无应答则返回*/
	if(S1STA!=0X40)
	{
		S1CON=0XD5;
		return(0);
	}
	
	S1CON=0XC1; 		/*接收一字节数据即发送非应答位*/
	while(SI==0); 		/*等待接收数据*/
	
	if(S1STA!=0X58)
	{
		S1CON=0XD5;
		return(0);
	}
	
	*c=S1DAT; 		/*读取数据*/
	S1CON=0XD5; 		/*结束总线*/
	
	return(1);
}


/*******************************************************************
			向有子地址器件读取多字节数据函数
函数原型: bit I2C_SendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 	从启动总线到发送地址、子地址、读数据、结束总线的全过程,从器件
	地址sla,子地址suba,读出的内容放入s指向的存储区读no个字节。
	如果返回1,表示操作成功,否则操作有误。
********************************************************************/
bit I2C_RcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
	uchar i;
	
	
	I2C_GetBus(); 		/*启动总线*/

	I2C_Send(sla); 		/*发送器件地址,若无应答则返回*/
	if(S1STA!=0X18)
	{
		S1CON=0XD5;
		return(0);
	}
	
	I2C_Send(suba); 	/*发送器件子地址,若无应答则返回*/
	if(S1STA!=0X28)
	{
		S1CON=0XD5;
		return(0);
	}
	
	S1CON=0XE5; 		/*重新启动总线*/
	while(SI==0);
	
	I2C_Send(sla+1);       /*发送器件地址,若无应答则返回*/
	if(S1STA!=0X40)
	{
		S1CON=0XD5;
		return(0);
	}
	
	for(i=0;i<no-1;i++)
	{
		S1CON=0XC5; 	/*接收一字节数据并发送应答位*/
		while(SI==0); 	/*等待接收数据*/
		if(S1STA!=0X50)
		{
			S1CON=0XD5;
			return(0);
		}
		
		*s=S1DAT; 	/*读取数据*/
		s++;
	}
	
	S1CON=0XC1; 		/*接收最后一字节数据并发送非应答位*/
	while(SI==0);
	*s=S1DAT;
	
	S1CON=0XD5; /*结束总线*/
	
	return(1);
}



/*软件包大小  字节*/

⌨️ 快捷键说明

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