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

📄 i2c.c

📁 模拟I2C总线的C51通用程序: 实现8051系列单片机与I2C总线器件的通信
💻 C
字号:
//模拟I2C总线的C51通用程序:

#include "reg51.h"
#include "intrins.h"

sbit SCL= P1^6; 				//定义SCL线所在口,可以根据自己的需要来定义
sbit SDA= P1^7; 				//定义SDA线所在口,可以根据自己的需要来定义
unsigned char error;	   	

/*--------------------------------------------------------------------------------
调用方式:void Start_I2C (void)
函数说明:启动总线函数,发送I2C总线起始条件
---------------------------------------------------------------------------------*/
void Start_I2C(void)
{
	EA=0;
	SDA=1; 						//发送I2C总线起始条件的数据信号
	SCL=1; 						//发送I2C总线起始条件的时钟信号
	_nop_();					//数据线保持高,延时
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SDA=0; 						//发送起始信号
	_nop_();					//延时
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SCL=0; 						//时钟线从高到低一次跳变,I2C通信开始
}						   	

/*--------------------------------------------------------------------------------
调用方式:void Stop_I2C (void)
函数说明:结束总线函数,发送I2C总线停止条件
---------------------------------------------------------------------------------*/
void Stop_I2C (void)
{
	SCL=0;						//发送I2C总线停止条件的时钟信号
	SDA=0; 						//发送I2C总线停止条件的数据信号
	_nop_();					//数据线保持低,延时
	_nop_();	
	_nop_();
	_nop_();
	_nop_();
	SCL=1; 						//时钟线从低到高一次跳变,I2C通信停止
	_nop_();					//延时
	_nop_();	
	_nop_();
	_nop_();
	_nop_();
	SDA=1;						///发送I2C总线停止的数据信号
	_nop_();					//延时
	_nop_();	
	_nop_();
	_nop_();
	_nop_();
	EA=1;
}

/*--------------------------------------------------------------------------------
调用方式: void Ack_I2C (void) 
函数说明:主控制器等待从器件接收方的应答
---------------------------------------------------------------------------------*/
void Ack_I2C(void)
{
	unsigned char errtime=255;		//因故障接收方无ACK,超时值为255。
	SDA=1;
	SCL=1;
	error=0x10; 
	while(SDA)
		{
    	errtime--;
		if(!errtime)
			{			
			Stop_I2C ();
			error=0x11; 			//出错后给全局变量赋值
			return;
			}
		}
	SCL=0;
}

/*--------------------------------------------------------------------------------
调用方式:void SendAck(void)
函数说明:主器件为接收方,从器件为发送方时,从器件等待主器件的应答信号。
---------------------------------------------------------------------------------*/
void SendAck(void)
{
	SDA=0; 						//数据线保持低,时钟线发生一次从高低的跳变 发送一个应答信号
	_nop_();					//延时
	_nop_();	
	_nop_();
	_nop_();
	_nop_();
	SCL=1;
	_nop_();					//延时
	_nop_();	
	_nop_();
	_nop_();
	_nop_();
	SCL=0;
}

/*--------------------------------------------------------------------------------
调用方式:void SendNotAck(void)
函数说明:主器件为接收方,从器件为发送方时,非应答信号。
--------------------------------------------------------------------------------*/
void SendNotAck(void)
{
	SDA=1;						//数据线保持高,时钟线发生一次从高低的跳变 没有应答
	_nop_();					//延时
	_nop_();	
	_nop_();
	_nop_();
	_nop_();
	SCL=1; 
	_nop_();					//延时
	_nop_();	
	_nop_();
	_nop_();
	_nop_();
	SCL=0;
}

/*--------------------------------------------------------------------------------
调用方式:void Send_I2C (uchar ch) 2003/05/13
函数说明:I2C总线字节发送函数
---------------------------------------------------------------------------------*/
void Send_I2C (Byte ch)
{
	unsigned char i;
	for (i=0;i<=8;i++)
		{
		SCL=0;				 	//时钟保持低可以发送数据
		_nop_();
		SDA=(ch&0x80);
    	ch<<=1; 
    	_nop_();				//延时
		_nop_();	
		_nop_();
		_nop_();
		_nop_();
		SCL=1; 
		_nop_();				//延时
		_nop_();	
		_nop_();
		_nop_();
		_nop_();
		}
	SCL=0;
}

/*--------------------------------------------------------------------------------
调用方式:unsigned char Receive_I2C (void) 
函数说明:接收I2C总线从器件传来的数据
---------------------------------------------------------------------------------*/
unsigned char  Receive_I2C(void)
{
	unsigned char i,data=0;
	SDA=1;
	for (i=0;i<=8;i++)
		{
		data<<=1;
		SCL=0;
		_nop_();				//延时
		_nop_();	
		_nop_();
		_nop_();
		_nop_();
		SCL=1;					//时钟做一次从低到高的跳变 可以接收数据
		_nop_();				//延时
		_nop_();	
		_nop_();
		_nop_();
		_nop_();
		data|=SDA;
		}
	SCL=0;
	return data;
}

⌨️ 快捷键说明

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