IIC通讯通用代码

IIC通讯通用代码

在实际项目中往往要用到IIC与不同的设备通讯,做一个通用型的IIC驱动代码很有必要,面得每次还得去自己测时序,实在是太麻烦了。而网上其他的IIC通讯代码要么只是适配51,要么用不了,我要弄的是适配所有平台,不需要再去检查IIC的时序。

#define SDA					RB0
#define SCL					RB1
#define SDA_SET	  			SDA=1;
#define SCL_SET	  			SCL=1;
#define SDA_RESET 			SDA=0;
#define SCL_RESET 			SCL=0;
#define SDA_IN_STATUS   	TRISB|=0x01; //SDA线输入状态
#define SDA_OUT_STATUS   	TRISB&=0xfe; //SDA线输出状态

void Single_WriteI2C(_u8 REG_Address,_u8 REG_data); //向设备写一个字节数据
_u8 Single_ReadI2C(_u8 REG_Address);       //向设备读一个字节数据

void Delay5us()  //自定义延迟函数
{
	_u8 i;
	for(i=0;i<5;i++)
}


//**************************************
//I2C起始信号
//**************************************
void I2C_Start()
{
    SDA_SET;                    //拉高数据线
    SCL_SET;                    //拉高时钟线
    Delay5us();                 //延时
    SDA_RESET;                    //产生下降沿
    Delay5us();                 //延时
    SCL_RESET;                    //拉低时钟线
}

//**************************************
//I2C停止信号
//**************************************
void I2C_Stop()
{
    SDA_RESET;                    //拉低数据线
    SCL_SET;                    //拉高时钟线
    Delay5us();                 //延时
    SDA_SET;                    //产生上升沿
    Delay5us();                 //延时
	Delay5us();
}


//**************************************
//I2C发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK(_u8 ack)
{                 
	if(ack)    //写应答信号
	{
		SDA_SET;
	}
	else
	{
		SDA_RESET;
	}	
    SCL_SET;                    //拉高时钟线
    Delay5us();                 //延时
    SCL_RESET;                   //拉低时钟线
    Delay5us();                 //延时
}


//**************************************
//I2C接收应答信号
//**************************************
_u8 I2C_RecvACK()
{
    SDA_IN_STATUS;             //SDA线改成输入模式
    SCL_SET;                    //拉高时钟线
    Delay5us();                 //延时
	if(SDA_READ)
	{
		Anwer_f=1;
	}
	else
	{
		Anwer_f=0;
	}
	
    SCL_RESET; 					//拉低时钟线
    SDA_OUT_STATUS;            //SDA线改成输出模式
    Delay5us();                 //延时
    return Anwer_f;
}

//**************************************
//向I2C总线发送一个字节数据
//**************************************
void I2C_SendByte(_u8 dat)
{
    _u8 i;
    for (i=0; i<8; i++)        
    {
	    if(dat&0x80)
		{
			SDA_SET; 
		}
		else
		{
			SDA_RESET; 
		}
        dat <<= 1;             //送数据口
        SCL_SET;                //拉高时钟线
        Delay5us();             //延时
        SCL_RESET;                //拉低时钟线
        Delay5us();             //延时
    }
    I2C_RecvACK();
}
//**************************************
//从I2C总线接收一个字节数据
//**************************************
uchar I2C_RecvByte()
{
    uchar i;
    uchar dat_RESET;
    SDA_IN_STATUS;             //SDA线改成输入 
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        SCL_SET;                //拉高时钟线
        Delay5us();             //延时
		if(SDA)
		{
			dat |=1;
		}
		              
        SCL_RESET;         //拉低时钟线
        Delay5us();        //延时
    }
	SDA_OUT_STATUS; 	  //SDA线改成输出
    return dat;
}


//**************************************
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(_u8 REG_Address,_u8 REG_data)
{
    I2C_Start();                  //起始信号
    I2C_SendByte(SlaveAddress);   //发送设备地址+写信号
    I2C_SendByte(REG_Address);    //内部寄存器地址,
    I2C_SendByte(REG_data);       //内部寄存器数据,
    I2C_Stop();                   //发送停止信号
}

//**************************************
//从I2C设备读取一个字节数据
//**************************************
_u8 Single_ReadI2C(_u8 REG_Address)
{
	_u8 REG_data;
	I2C_Start();                   //起始信号
	I2C_SendByte(SlaveAddress);    //发送设备地址+写信号
	I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始	
	I2C_Start();                   //起始信号
	I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号
	REG_data=I2C_RecvByte();       //读出寄存器数据
	I2C_SendACK(1);                //接收应答信号
	I2C_Stop();                    //停止信号
	return REG_data;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值