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

📄 iic.c

📁 Linux 系统中
💻 C
字号:
#include "reg51.h"
#include "IIC.h"
#include <stdio.h>
#include <intrins.h>


/*---------------------------------
启动总线函数
函数原型:Start_I2C()
功能:启动I2C总线,即发送起始条件
---------------------------------*/
void Start_I2C()
{
	SDA = 1;	//发送起始条件数据信号
	_nop_();
	SCL = 1;
	_nop_();		//起始建立时间大于4.7us
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SDA = 0;	//发送起始信号
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SCL = 0;	//钳位
	_nop_();
	_nop_();
}

/*-------------------------------
结束总线函数
函数原型:Stop_I2C()
功能:结束I2C总线,即发送I2C结束条件
-------------------------------*/
void Stop_I2C()
{
	SDA = 0;	//发送结束条件的数据信号
	_nop_();		//发送结束条件的时钟信号
	SCL = 1;	//结束条件建立时间大于4us
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SDA = 1;	//发送I2C总线结束命令
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();	
}


/*------------------------------
字节数据传送函数
函数原型:SendByte(uchar c)
功能:将数据C发送出去,可以是地址,
也可以是数据,发送完成之后等待应答
并且对应答状态位进行操作,不应答和非
应答都使得ACK=0,发送数据正常则ACK=1
--------------------------------*/
void	SendByte(uchar c)
{
	uchar BitCnt;
	for(BitCnt = 0;BitCnt < 8;BitCnt++)			//一个字节
		{
			if((c << BitCnt)& 0x80) SDA = 1;	//判断发送位
			else	SDA = 0;
			_nop_();
			SCL = 1;	//时钟线为高,通知被控器开始接受数据
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			SCL = 0;
		}
	_nop_();
	_nop_();
	SDA = 1;	//释放数据线,准备接受应答位
	_nop_();
	_nop_();
	SCL = 1;
	_nop_();
	_nop_();
	_nop_();
	if(SDA == 1) ack =0;
	else ack = 1;		//判断是否收到应答信号
	SCL = 0;
	_nop_();
	_nop_();
}

/*-------------------------------------------
字节数据接收函数
函数原型:uchar RcvByte();
功能:用来接收从器件传来的数据,并且判断总线错误(不发送应答信号)
发送完成后使用应答信号
-------------------------------------------*/
uchar RcvByte();
{
	uchar retc;
	uchar BitCnt;
	retc = 0;
	SDA = 1;		//置数据线为输入方式
	for(BitCnt = 0;BitCnt < 8;BitCnt++)
	{
		_nop_();
		SCL = 0;	//置时钟线为低,准备接收
		_nop_();
		nop();
		nop();
		nop();
		nop();
		SCL = 1;	//置时钟线为高使得数据有效
		nop();
		nop();
		retc = retc << 1;	//左移补零
		if (SDA == 1)
		retc = retc + 1;	//当数据为真加一
		nop();
		nop();
	}
	SCL = 0;
	nop();
	nop();
	return(retc);
}

/*-----------------------------------------
应答子函数
原型:void Ack_I2c(bit a);
功能:主控器进行应答信号,(可以是应答或者非应答信号)
-----------------------------------------*/
void Ack_I2C (bit a)
{
	if( a == 0)SDA = 0;			//在此发出应答信号或者非应答信号
	else SDA = 1;
	nop();
	nop();
	nop();
	SCL = 1;
	nop();
	nop();
	nop();
	nop();
	nop();
	SCL = 0;
	nop();
	nop();
}

/*----------------------------------
向无子地址器件发送字节数据函数
函数原型:bit ISendByte( uchar sla,uchar c);
功能:从启动总线到发送地址,数据,结束总线的全过程,从器件地址
sla。如果返回1表示操作成功,否则表示有误
-----------------------------------*/
bit ISendByte (uchar sla,uchar c)
{
	Start_I2C();		//启动
	SendByte(sla);		//发送器件地址
	if(ack == 0)
	return(0);
	SendByte(c);		//发送数据
	if(ack == 0)
	return(0);
	Stop_I2C();			//结束
	return(1);	
}

/*------------------------------------
向有子地址器件发送多字节数据函数
函数原型:bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no);
功能:启动地址,发送地址,数据,结束全过程
从器件地址sla,子地址suba,发送内容是s指向的内容,发送
no个字节,如果返回1表示成功,否则表示有问题
---------------------------------*/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
	uchar i;
	Start_I2C();	//启动总线
	SendByte(sla);	//发送器件地址
	if(ack == 0)
	return(0);
	SendByte(suba);	//发送器件子地址
	if(ack == 0);
	return(0);
	for (i = 0;i < no; i++)
	{
		SendByte(*s);	//发送数据
		if(ack == 0)
		return(0);
		s++;
	}
	Stop_I2C();		//结束总线
	return(1);	
}

/*-----------------------------------
向无子地址器件读取字节数据函数
函数原型: bit IRcvByte(uchar sla,uchar *c)
功能:从启动总线到发送地址、读数据,结束总线全部过程,从器件地址sla
子地址suba,读出内容放在s指向的存储区,读no个字节
如果返回1表示操作成功,否则表示操作有误
---------------------------------*/
bit IRcvByte(uchar sla,uchar *c)
{
	Start_I2C();		//启动总线
	SendByte(sla+1);	//发送器件地址
	if(ack==0)
	return(0);
	*c = RcvByte();
	Ack_I2C(1);		//发送非就应答位
	Stop_I2C();		//结束总线
	return(1);
}

/*-----------------------------------
向有子地址器件读取多字节数据函数



----------------------------------*/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
	uchar i;
	Start_I2C();		//启动总线
	SendByte(sla);		//发送器件地址
	if(ack == 0)
	return(0);
	SendByte(suba);		//发送子地址
	if(ack == 0)
	return(0);
	Start_I2C();		//启动
	StartByte(sla+1);
	if(ack == 0)
	return(0);
	for(i = 0;i < no - 1;i++)
	{
		*s = RcvByte();		//接收数据
		Ack_I2C(0);			//发送应答位
		s++;
	}
	*s = RcvByte();
	Ack_I2C(1);			//发送就答位
	Stop_I2C();
	return(1);
} 
	

}

⌨️ 快捷键说明

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