IIC通信协议

来源:互联网 发布:东华软件java笔试题 编辑:程序博客网 时间:2024/05/29 13:04

IIC协议

(1)概述

I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。

经常IIC和SPI接口被认为指定是一种硬件设备,但其实这样的说法是不尽准确的,严格的说他们都是人们所定义的软硬结合体,分为物理层(四线结构)和协议层(主机,从机,时钟极性,时钟相位)。

IIC,SPI的区别不仅在与物理层,IIC比SPI有着一套更为复杂的协议层定义。下面来分别说明一下IIC的物理层和协议层。

(2)IIC的物理层

a.只要求两条总线线路,一条是串行数据线SDA,一条是串行时钟线SCL。(IIC是半双工,而不是全双工)。

b.每个连接到总线的器件都可以通过唯一的地址和其它器件通信,主机/从机角色和地址可配置,主机可以作为主机发送器和主机接收器。

c.IIC是真正的多主机总线,(而这个SPI在每次通信前都需要把主机定死,而IIC可以在通讯过程中,改变主机),如果两个或更多的主机同时请求总线,可以通过冲突检测和仲裁防止总线数据被破坏。

d.传输速率在标准模式下可以达到100kb/s,快速模式下可以达到400kb/s。

e.连接到总线的IC数量只是受到总线的最大负载电容400pf限制。

一个典型的IIC接口如下图(1)所示


图(1)

(3)IIC的协议层

IIC的协议层才是掌握IIC的关键。现在简单概括如下:

a.数据的有效性

在时钟的高电平周期内,SDA线上的数据必须保持稳定,数据线仅可以在时钟SCL为低电平时改变。

如图(2)所示:


      图(2)

b.起始和结束条件

起始条件:当SCL为高电平的时候,SDA线上由高到低的跳变被定义为起始条件,结束条件:当SCL为高电平的时候,SDA线上由低到高的跳变被定义为停止条件,要注意起始和终止信号都是由主机发出的,连接到I2C总线上的器件,若具有I2C总线的硬件接口,则很容易检测到起始和终止信号。总线在起始条件之后,视为忙状态,在停止条件之后被视为空闲状态,对起始条件和结束条件的描述如下图(3)所示。


图(3)

c.应答

每当主机向从机发送完一个字节的数据,主机总是需要等待从机给出一个应答信号,以确认从机是否成功接收到了数据,从机应答主机所需要的时钟仍是主机提供的,应答出现在每一次主机完成8个数据位传输后紧跟着的时钟周期,低电平0表示应答,1表示非应答,如图(4)所示。


图(4)

d.数据帧格式

I2C总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。
在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/T),用“0”表示主机发送数据(T),“1”表示主机接收数据(R)。{这里小编在驱动MPU6050模块的时候,就犯过这样的错误,它写的MPU6050从机地址是0x68,因为发送从机地址的时候,要加一位读写方向位,因为刚开始应该是向这个MPU6050里写从机里某个寄存器的地址,所以应该是7位地址   0x68(1101000)+二进制位0=11010000)也就是0xD0,表示要向该IIC设备里写东西,然后再紧接着写入IIC设备里的寄存器地址,而我直接写入了0x68,导致出错}每次数据传送总是由主机产生的终止信号结束。但是,若主机希望继续占用总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对另一从机进行寻址。
在总线的一次数据传输过程中,可以有以下几种组合方式:
[1] 
主机向从机发送数据,数据传送方向在整个传送过程中不变:

注:有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。
    A表示应答(低电平), A非表示非应答(高电平)。S表示起始信号,P表示终止信号。
[2]主机在第一个字节后,立即从从机读数据:

[3]在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次,但两次读/写方向位正好反相:


一般情况下,[3]是比较常见的,比如MPU6050模块,
发送起始信号
等待从机应答
写一个从机地址+0(表示写),
等待从机应答
发送一个字节的MPU6050加速度存储寄存器地址,
等待从机应答
再发送一次起始信号
等待从机应答
写一个从机地址+1(表示读)
等待从机应答
读取MPU6050传感器数据
主机非应答
e.IIC信号的模拟
主机可以采用不带I2C总线接口的单片机,如80C51、AT89C2051等单片机,利用软件实现I2C总线的数据传送,即软件与硬件结合的信号模拟。即使是含有IIC硬件的单片机(如stm32 103系列)也有一定的缺陷,所以一般也会模拟IIC的时序。现将具体时间截图如下:

具体的程序代码如下:

//产生起始信号
void I2C_Start(void)
{
    I2C_SDA_OUT();//配置一下引脚,引脚设置为输出

I2C_SDA_H;//把数据线拉高
I2C_SCL_H;//把时钟线拉高
delay_us(5);//延时5微秒,要求大于4.7微秒
I2C_SDA_L; //拉低,产生下降沿
delay_us(6);//这个过程大于4微秒
I2C_SCL_L;//最后一定要把这个时钟线拉低,因为只有时钟线拉低的时候才允许数据变化。
}
//产生停止信号
void I2C_Stop(void)
{
   I2C_SDA_OUT();


   I2C_SCL_L;
   I2C_SDA_L;
   I2C_SCL_H;
   delay_us(6);
   I2C_SDA_H;
   delay_us(6);
}
//主机产生应答信号ACK
void I2C_Ack(void)
{
   I2C_SCL_L;
   I2C_SDA_OUT();
   I2C_SDA_L;
   delay_us(2);
   I2C_SCL_H;
   delay_us(5);
   I2C_SCL_L;
}


//主机不产生应答信号NACK
void I2C_NAck(void)
{
   I2C_SCL_L;
   I2C_SDA_OUT();
   I2C_SDA_H;
   delay_us(2);
   I2C_SCL_H;
   delay_us(5);
   I2C_SCL_L;
}
//等待从机应答信号,我们只负责主机应答信号的产生,从机应答信号
//我们不控制。
//返回值:1 接收应答失败
//  0 接收应答成功
u8 I2C_Wait_Ack(void)
{
u8 tempTime=0;


I2C_SDA_IN(); //配置为上拉输入。


I2C_SDA_H; //主机释放数据总线,等待从机产生应答信号
delay_us(1);
I2C_SCL_H;
delay_us(1);
//等待从机对数据总线的操作。低电平代表应答
while(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA))
{
tempTime++;
//这个属于软件延时,不一定准确。
if(tempTime>250) //如果时间超时,没有应答就停止。
{
I2C_Stop();
return 1;  //没有响应的话返回1.
} 
}


I2C_SCL_L;
return 0; //如果有响应的话就返回0.
}

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 半边头神经痛怎么办 泰迪狗狗咳嗽怎么办 嘴唇粘乎乎的怎么办 脑袋疼人怎么办 月经期间头痛怎么办 说话不过脑子怎么办 更年期老出汗怎么办 更年期出汗严重怎么办 更年期爱出汗怎么办 潮热出汗怎么办 更年期多汗怎么办 失眠头晕怎么办 头昏失眠怎么办 每天头昏昏沉沉怎么办 儿童反应慢怎么办 孩子反应迟钝怎么办 小孩子反应迟钝怎么办 小孩子反应慢怎么办 怀孕后头重脚轻怎么办 脑袋里长个瘤怎么办 经常头不舒服怎么办 抑郁症脑子空白怎么办 脑袋空空的怎么办 脑袋不够用怎么办 老公意志消沉怎么办 感觉情感怎么办 情感冷漠怎么办 感冒眼睛流泪怎么办 脑子越来越迟钝怎么办 为什么老是头疼怎么办 高血压头昏怎么办 头嗡嗡响怎么办 脖子抽筋怎么办 巴西龟四肢无力怎么办 脑袋筋疼是怎么办 脑袋有根筋疼怎么办 脑袋疼肚子疼怎么办 脑袋涨怎么办 右头皮神经痛怎么办 经常右侧偏头痛怎么办 头跳痛怎么办快速缓解