I2C通讯协议

介绍:Philips公司研发的I2C总线是由俩根通讯线:SCL(控制线),SDA(数据线),且同步、半双工、带数据应答的通用数据总线。


时序说明:

默认状态:SCL、SDA都处于高阻态,防止短路

空闲状态:SCL、SDA都处于高电平时称总线处于空闲状态。

一、起始条件:SCL高电平期间,SDA由高电平切换位低电平。

                           

代码:

​/**
   *   @brief  I2C开始
   *   @param  无
   *   @retval  无
**/
void I2C_Start()
{ 	
    I2C_SDA=1; //先将SDA置高
	I2C_SCL=1; //SCL置高
	I2C_SDA=0; //在SCL置高期间将SDA拉低
    I2C_SCL=0; //最后将SCL拉低
}

​

二、终止条件:SCL高电平期间,SDA由低电平切换为高电平。

                          

代码:

/**
   *   @brief  I2C停止
   *   @param   无
   *   @retval  无
**/

void I2C_Stop()
{
	I2C_SDA=0; //先SDA拉低
	I2C_SCL=1; //将SCL拉高
	I2C_SDA=1; //最后拉高SDA,使其处于空闲状态
}

 三、发送一个字节:在SCL低电平期间,主机将数据依次放在SDA上(高位在前),然后拉高SCL,从机在SCL高电平期间读取数据位(SCL高电平期间不允许SDA上的数据位发生改变),循环8次,即可发送一个字节。

 代码:

/**
   *   @brief  I2C发送一个字节
   *   @param   Byte 一个字节
   *   @retval    无
**/

void I2C_SendByte(unsigned char Byte)
{
	unsigned char i;
    I2C_SCL=0;
	for(i=0;i<8;i++)
	{
		I2C_SDA=Byte&(0X80>>i); //在SCL地电平期间依次将数据放入SDA上(高位在前)
		I2C_SCL=1;        //将SCL拉高,让从机读取数据
		I2C_SCL=0;        //再将SCL拉低便于发送下一位数据
	}
	
}

四、接受一个字节:在SCL低电平期间,从机将数据依次放在SDA上(高位在前),然后拉高SCL,主机在SCL高电平期间读取数据位(SCL高电平期间不允许SDA上的数据位发生改变),循环8次,即可发送一个字节。(主机在接受前需要释放SDA)

代码:

/**
   *   @brief  I2C接受一个字节
   *   @param  Byte 一个字节  
   *   @retval  无
**/

unsigned char I2C_ReceiveByte()
{
	  unsigned char i,Byte=0X00; //初始化

	  I2C_SCL=0;   //先将SCL拉低

	    I2C_SDA=1;   //释放SDA

		for(i=0;i<8;i++)
	{
		I2C_SCL=1;   //拉高SCL,让主机读取数据
	
		if(I2C_SDA)   //如果读取的数据非0
		{
			Byte|=(0X80>>i);  //将数据转换到Byte上(按位转换)
		}
		I2C_SCL=0;    //拉低SCL,便于读取第下一位数据
	}	
		return Byte;   //返回所接受的值
}

 五、发送应答:将一个字节接受完之后,再下一个时钟时,主机发送一位数据,0表示应答、1表示非应答。

  

 代码:

/**
   *   @brief  I2C发送应答
   *   @param   AckByte 应答位  0为应答  1为不应答
   *   @retval   无
**/

void I2C_SendAck(unsigned char AckByte)
{
	I2C_SDA=AckByte; //发送应答位
	I2C_SCL=1;
	I2C_SCL=0;
}

六、接受应答:将一个字节发送完之后,再下一个时钟时,主机接受一位数据,判断从机是否应答,0表示应答、1表示非应答。(主机接受前需要释放SDA)

代码:

/**
   *   @brief  I2C接受应答
   *   @param   无
   *   @retval  接受到的应答位 0为应答  1为不应答
**/

unsigned char I2C_ReceiveAck()
{
	unsigned char AckByte;
	I2C_SDA=1;     //释放SDA
	I2C_SCL=1;
	AckByte=I2C_SDA;  //读取应答位
	I2C_SCL=0;
	return AckByte;   //返回应答位 

七、写数据帧

八、读数据帧

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值