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

📄 driver_software_i2c.c

📁 增强型51单片机程序模板
💻 C
字号:
/**************************************************************************
文 件 名:IO_I2C.c													
创 建 人:														
创建日期:2008.07.12												
组成部分:void I2C_Start(void)
		  void I2C_Stop(void)
		  bit I2C_SendData(uint8 send_data)
		  uint8 I2C_ReceiveData(void)
		  void I2C_ACK(bit ack)
		  bit I2C_SendString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
		  bit I2C_ReceiveString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
		  bit Write_Byte(uint8 addr,uint8 subaddr,uint8 info)
		  uint8 Read_Byte(uint8 addr,uint8 subaddr)
描    述:此文件用于对I2C总线的控制工作								
修 改 人:															
修改日期:															
修改内容:															
**************************************************************************/
#include "user.h"
#include "intrins.h"


#ifdef I2C
/**************************************************************************
函 数 名: void I2C_Start(void) 								    
功能描述: 用于完成I2C总线的启动工作								
全局变量: 无													
局部变量: 无													
参数说明: 无													
输    入: 无													
输    出: 无													
创 建 人: city		    	    								
创建日期: 2008.6.1												
修 改 人:        												
日    期:		  												
函数说明: 														
**************************************************************************/
void I2C_Start(void)
{
	SDA=1;						//数据线置高电平
	_nop_();
	SCL=1;						//时钟线置高电平
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();										
	SDA=0;						//时钟线置低电平,配合先前的高电平以产生下降沿启动总线
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();					
	SCL=0;
	_nop_();
	_nop_();	
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();					
}
	
/**************************************************************************
函 数 名: void I2C_Stop(void)								        
功能描述: 用于完成I2C总线的停止工作									
全局变量: 无														
局部变量: 无														
参数说明: 无														
输    入: 无														
输    出: 无														
创 建 人: city		    	    									
创建日期: 2008.5.16													
修 改 人:        													
日    期:		  													
函数说明: 															
**************************************************************************/
void I2C_Stop(void)
{
	_nop_();
	SDA=0;						//数据线置低电平
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();					
	SCL=1;
	_nop_();					//时钟线置高电平
	_nop_();
	_nop_();
	_nop_();
	_nop_();					
	_nop_();					 
	_nop_();
	_nop_();
	_nop_();
	_nop_();					
	SDA=1;						//数据线置高电平,配合先前的低电平以产生上升降停止总线
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();					
	_nop_();
}

/**************************************************************************
函 数 名: bit I2C_SendData(uint8 send_data)					    
功能描述: 发送一个字节数据或地址出去								
全局变量: 无														
局部变量: count  ack													
参数说明: count为发送字节位数标志循环8位发送一个字节				
输    入: send_data待发送的数据										
输    出: ack为应答标志												
创 建 人: city		    	    									
创建日期: 2008.5.16													
修 改 人: city     													
日    期: 2008.6.14													
函数说明: 															
**************************************************************************/
bit I2C_SendData(uint8 send_data)
{
	uint8 count;
	bit ack;
	for(count=8;count!=0;count--)
		{
		if((send_data&0x80)==0x80)					//判断当前位为1则发送高电平状态
		{
			SDA=1;									//反之发送低电平
		}										
		else SDA=0;
		_nop_();
		_nop_();	
		_nop_();
		_nop_();
		_nop_();
		SCL=1;				
		_nop_();									//保持时钟高电平周期大于4us,此处为10us
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		SCL=0;
		send_data=send_data<<1;						//数据移位高位在前
		}
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SDA=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();					
	SCL=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();					
	if(SDA==1)ack=0;			  				    //判断应答为0表示被控器件无应答或损坏
	else ack=1;										//判断应答为1表示发送数据正常
	SCL=0;
	_nop_();
	_nop_();
	_nop_();
	_nop_();					
	return (ack);									//返回应答状态标志
}

/**************************************************************************
函 数 名: uint8 I2C_ReceiveData(void)						        
功能描述: 接收一个字节数据											
全局变量: 无														
局部变量: count;receivedata											
参数说明:count为循环接收数据位次数;receivedtat为收到的数据保存参数	
输    入: 无														
输    出: receivedata												
创 建 人: city		    	    									
创建日期: 2008.5.16													
修 改 人: city     													
日    期: 2008.6.14													
函数说明: 函数不含应答功能										
**************************************************************************/
uint8 I2C_ReceiveData(void)
{
	uint8 count,receivedata;
	SDA=1;							 				//置数据线为输入方式
	for(count=8;count!=0;count--)
	{
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		SCL=0;						 				//时钟线置低,准备接收数据位		
		_nop_();					 				//时钟低电平周期大于4.7us,此处为10us
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();			
		SCL=1;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		receivedata=receivedata<<1;					//循环移位
		if(SDA==1)						 			//判断收到的电平为高则对应数据位高置1
			{
				receivedata=receivedata+1;
			}
		_nop_();
		_nop_();
		_nop_();
		_nop_();
	}
	SCL=0;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	return receivedata;
}

/**************************************************************************
函 数 名: void I2C_ACK(bit ack)								        
功能描述: 当主器件收好一个字节数据后给出应答或非应答				
全局变量: 无														
局部变量: 无														
参数说明:无														
输    入: ack														
输    出: 无														
创 建 人: city		    	    									
创建日期: 2008.5.16													
修 改 人: city     													
日    期: 2008.6.15 												
函数说明: 															
**************************************************************************/
void I2C_ACK(bit ack)
{
	if(ack==0)SDA=0;						    //在此发出应答或非应答信号
	else SDA=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SCL=1;			
	_nop_();									//时钟低电平周期大于4us
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SCL=0;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
}


/**************************************************************************
函 数 名: bit I2C_SendString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
功能描述: 完成一个指定器件的指定地址字符串的发送					
全局变量: 无													
局部变量: ack,i													
参数说明:ack为应答标志,i用于保存len长度用于进行循环				
输    入: addr器件地址,subaddr子器件地址,*s为待发送数据地址		
		  len为发送数据长度												
输    出: 返回应答标志												
创 建 人: city		    	    									
创建日期: 2008.5.16													
修 改 人:        													
日    期:		  													
函数说明: 															
*************************************************************************/
bit I2C_SendString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
{
	bit ack;
	uint8 i;
	I2C_Start();								//启动I2C总线			
	ack=I2C_SendData(addr);						//发送硬件地址(针对不同的元件硬件地址有所不同)	
	if(ack==0)return(0);						//判断应答,为0表明没有收到应答则退出
	ack=I2C_SendData(subaddr);					//发送器件子地址(若为存储器则为对应写入数据的地址)
	if(ack==0)return(0);						//判断应答,为0表明没有收到应答则退出
	for(i=len;i!=0;i--)							//根据待发送数据长度循环发送指定数组中的数据
		{
			ack=I2C_SendData(*s);					//发送对就地址中数据
			s++;									//移动数据指针
			if(ack==0)return(0);					//判断应答,为0表明没有收到应答则退出
		}
	I2C_Stop();									//停止I2C总线
	return(1);									//返回状态标志1确定发送成功
}

/**************************************************************************
函 数 名: I2C总线接收字符串							
功能描述: 							
全局变量: 无														
局部变量: 无														
参数说明:无														
输    入: 无														
输    出: 无														
创 建 人: city		    	    									
创建日期: 2008.5.16													
修 改 人:        													
日    期:		  													
函数说明: 															
**************************************************************************/
bit I2C_ReceiveString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
{
	bit ack;
	uint8 i;
	I2C_Start();								//启动I2C总线
	I2C_SendData(addr);							//发送硬件地址(针对不同的元件硬件地址有所不同)
	if(ack==0)return(0);						//判断应答,为0表明没有收到应答则退出
	I2C_SendData(subaddr);						//发送器件子地址(若为存储器则为对应写入数据的地址)
	if(ack==0)return(0);						//判断应答,为0表明没有收到应答则退出

	I2C_Start();								//启动I2C总线
	I2C_SendData(addr+1);						//发送读指定硬件数据指令
	if(ack==0)return(0);

	for(i=len;i!=0;i--)							//读取指定长度数据
	{										
		*s=I2C_ReceiveData();					//读取数据到指定数组地址中
		I2C_ACK(0);								//返回应答
		s++;									//指向下一个保存的数据数组空间
	}
	*s=I2C_ReceiveData();
	I2C_ACK(1);									//返回应答标志
	I2C_Stop();									//停止I2C总线
	return(1);									//返回状态
}

/**************************************************************************
函 数 名: 
功能描述: 							
全局变量: 														
局部变量: 														
参数说明:														
输    入: 														
输    出: 														
创 建 人: 		    	    									
创建日期: 												
修 改 人:        													
日    期:		  													
函数说明: 															
**************************************************************************/
bit Write_Byte(uint8 addr,uint8 subaddr,uint8 info)
{
	bit ack;
	I2C_Start();								//启动I2C总线
	ack=I2C_SendData(addr);						//发送硬件地址(针对不同的元件硬件地址有所不同)
	if(ack==0)return(0);						//判断应答,为0表明没有收到应答则退出
	ack=I2C_SendData(subaddr);					//发送器件子地址(若为存储器则为对应写入数据的地址
	if(ack==0)return(0);						//判断应答,为0表明没有收到应答则退出
	ack=I2C_SendData(info);						//向已经确定的地址写入一个字节的数据
	I2C_Stop();									//停止I2C总线
	return(1);
}

/**************************************************************************
函 数 名: 
功能描述: 							
全局变量: 														
局部变量: 														
参数说明:														
输    入: 														
输    出: 														
创 建 人: 		    	    									
创建日期: 												
修 改 人:        													
日    期:		  													
函数说明: 															
**************************************************************************/
uint8 Read_Byte(uint8 addr,uint8 subaddr)
{
	bit ack;								   
	uint8 info;
	I2C_Start();								//启动I2C总线
	I2C_SendData(addr);							//发送硬件地址(针对不同的元件硬件地址有所不同)
	if(ack==0)return(0);						//判断应答,为0表明没有收到应答则退出
	I2C_SendData(subaddr);						//发送器件子地址(若为存储器则为对应写入数据的地址
	if(ack==0)return(0);						//判断应答,为0表明没有收到应答则退出
	I2C_Start();								//启动I2C总线
	I2C_SendData(addr+1);						//发送读指定硬件数据指令
	if(ack==0)return(0);						//判断应答,为0表明没有收到应答则退出
	info=I2C_ReceiveData();						//接收一个字节数据保存到info局部变量中
	I2C_ACK(1);									//返回应答标志
	I2C_Stop();									//停止I2C总线
	return(info);								//返回接收到的数据
}

#endif

⌨️ 快捷键说明

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