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

📄 i2c.c

📁 工业i2c总线通讯协议,是用c编辑的,可以用于单片机控制的i2c通讯
💻 C
字号:
	#include <reg51.h>
	#include <intrins.h>
	#define uchar unsigned char
	#define uint unsigned int
	//常变量定义区,端口位定义
	sbit SDA=P3^4;
	sbit SCL=P3^5;
	//状态标志
	bit ack;
	/***************************************************************
	启动总线函数
	函数原型:void Start_I2C();
	功能:启动I2C总线,即发送I2C起始条件
	***************************************************************/
	void Start_I2C()
	{
		SDA=1;
		_nop_();
		SCL=1;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		SDA=0;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		SCL=0;
		_nop_();
		_nop_();
	}
	/***************************************************************
	结束总线函数
	函数原型:void Stop_I2c();
	功能:结束I2C总线,即发送I2C结束条件
	****************************************************************/
	void Stop_I2C()
	{
		SDA=0;
		_nop_();
		SCL=1;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		SDA=1;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
    }

	/****************************************************************
	字节数据传送函数
	函数原型:void SendByte(uchar c)
	功能:将数据c发送出去,可以时地址,也可以时数据,发完后等待应答,并对
	此状态位进行操作(不应答或非应答都使ack=0,表示应答失败)。发送数据正常,ack=1;ack=0
	表示被控器无应答或损坏
	*******************************************************************/
	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;		//8位发送完后释放数据线,准备接收应答位
		_nop_();
		_nop_();
		SCL=1;
		_nop_();
		_nop_();
		_nop_();
		if(SDA==1)		//应答时接收器必须把SDA线拉低
			ack=0;
		else ack=1;		//判断是否接收到应答信号
		SCL=0;
		_nop_();
		_nop_();
	}
	/*************************************************************************
	字节数据接受函数
	函数原型:uchar RcvByte();
	功能:用来接收从器件传来的数据,并判断总线错误(不发应答信号)
    *************************************************************************/
	uchar RcvByte()
	{
		uchar retc;
		uchar BitCnt;
		retc=0;
		for(BitCnt=0;BitCnt<8;BitCnt++)
		{
			SDA=1;		//置数据线为输入方式
			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)
			SDA=1;
		else
			SDA=0;
		_nop_();
		_nop_();
		_nop_();
		SCL=1;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		SCL=0;
		_nop_();
		_nop_();
	}

	/****************************************************************
	向无子地址器件发送字节数据函数
	函数原型:bit ISendByte(uchar sla,uchar c);
	功能:从启动总线到发送地址,数据,直至结束总线的全过程;从器件地址sla,c为发送内容。
	如果返回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,
	读取数据返回值c.如果返回是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);
   功能:从启动总线到发送地址,子地址,数据直到结束总线的全过程;从器件地址sla,子地址suba,到读出内容放到s指向的存储区,
   读no个字节。如果返回是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();
		SendByte(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 + -