主要通过两个层面来讲:物理层、协议层。
IIC是一个同步半双工串行总线协议。
一、物理层(通信模型)
1、最早是飞利浦公司开发的这个协议,最早应用到其产品上去。
2、两线制(两根信号线)
其中SCL为时钟线,SDA为数据线。
3、挂载在IIC总线上的设备有主从之分,可以同时挂载多个主机和多个从机。
主机:通信的发起方。所有的通信皆由主机先来发起。
从机:和主机进行通信。实现数据的交互。
4、IIC通信中,每一个设备(不论是主机还是从机)都有唯一的ID。
那么问题来了,在同一根信号线上有那么多的设备挂载,既有主机也有从机,假设主机1想和从机2进行通信,该怎么实现呢。主机1如何精准的找到我想通信的从机呢?这就和设备的唯一的ID有关,主机1可以去信号线上广播想要通信的从机ID,如果对应ID的从机收到了主机1发起的请求,则发送一个应答信号传送给主机1,表示本从机设备收到了主机的通信请求,然后选择是否应答该请求,如果应答则表示同意通信,如果返回给主机1的是一个非应答信号则表示不想与主机1通信。而其他从设备虽然也能接收到主机1的请求,但因为ID不一样,所以无法与主机1通信。
假如在同一个时刻,多个主机同时发起总线请求,也就是说同一时刻多个主机想要占据总线的使用权。此时将会有一个总线仲裁机制来决定到底是哪一个主机能使用信号线进行通信,也就是最终会是谁占据总线的使用权。
总线仲裁机制使用的是线与特性(总线空闲电平状态为高电平),也就是说谁能先拉低总线谁就能得到总线的控制权限,如果两者都能拉低总线,那就看谁的时间更长,总有一个时刻会有一个主机最终获得线权。那么其他主机就会主动的让出总线的控制权限。
2.空闲电平状态为高电平。
在时钟线和数据线上都接了一个上拉电阻。其作用就在于使得IIC总线的空闲电平信号为高电平。这两个上拉电阻的必须要的。
所以我们在初始化配置GPIO的时候最好给其配置成开漏输出。因为开漏输出是无法自己输出一个高电平的(开漏输出只有低电平状态和高阻态),但是因为IIC设备是一定会接上拉电阻的,所以开漏输出模式下,空闲电平状态将会由上拉电阻来拉高。然而因为我们后面要使用GPIO口模拟的方式来实现IIC协议,所以在这里配置推挽也问题不大,因为在软件模拟的时候,总线的输出高输出低是由我们自己软件控制的。
3.IIC通信是高位先发,是以字节形式发送的(一次发8位)。
4.具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式下可达 3.4Mbit/s,但目前大多 I2C 设备尚不支持高速模式。
二、协议层
1、起始信号
起始信号是表示通信开始的信号,其表现为:在SCL时钟线为高电平期间,数据线产生一个由高到低的下降沿电平切换。
2、停止信号
起始信号是表示通信结束的信号,其表现为:在SCL时钟线为高电平期间,数据线产生一个由低到高的下降沿电平切换。
3、数据有效性
因为我们通过数据线发送的信号有高有低,所以在电平信号进行高低切换的过程当中,需要一定的时间,那么这时可以让此时的数据切换这段时间使得数据无效。在IIC里面,只有当时钟线为高电平的期间,数据才有效。时钟线为低电平的期间,数据是无效的。如果在数据切换期间读取数据有效,那么很可能会将切换电平信号识别成开始信号或结束信号。
4、应答信号
(1)应答
应答信号:表示一个肯定的回应。其表现为:在时钟线SCL高电平期间,数据线SDA维持一个稳定的低电平。
(2)非应答
非应答信号:表示一个否定的回应。其表现为:在时钟线SCL高电平期间,数据线SDA维持一个稳定的高电平,当然,有的时候,数据的接收方确实没有收到来自数据的发送方的信号,导致数据的接收方就没有理会数据的发送方,此时也属于非应答信号。所以非应答信号其实有好几种可能的情况。
注意:应答信号或非应答信号是谁发的,又是谁接收的呢?
这里需要特别注意一点,应答信号(非应答信号)是数据的接收方发出去的,并且由数据的发送方来接收的。这里要弄清楚一个概念,数据的接收方不等同于从设备,数据的发送方也不等同于主设备,因为数据的接收方可能是主设备也可能是从设备,同理,数据的发送方也一样,可能是主设备也可能是从设备,因为在数据的通信过程中,可能由主机向从机发
送数据,也可能由从机向主机发送数据(半双工通信,但通信的发起者都是主机)。当由主机向从机发送数据的时候,主机就是数据的发送方,从机就是数据的接收方,而当从机向主机发送数据的时候,从机就是数据的发送方,主机则变成了数据的接收方。所以,这里要特别注意,应答信号(非应答信号)是由数据的接收方发出去,并且由数据的发送方来接收的。
由于某种原因从机不对主机寻址信号应答时(如从机正在进行实时性的处理工作而无法接收总线上的数据),它必须将数据线置于高电平,而由主机产生一个终止信号以结束总线的数据传送。
如果从机对主机进行了应答,但在数据传送一段时间后无法继续接收更多的数据时,从机可以通过对无法接收的第一个数据字节的“非应答”通知主机,主机则应发出终止信号以结束数据的继续传送。
当主机接收数据时,它收到最后一个数据字节后,必须向从机发出一个结束传送的信号。这个信号是由对从机的“非应答”来实现的。然后,从机释放SDA线,以允许主机产生终止信号。
5、IIC时序生成方式
IIC时序可以通过软件模拟(即通过GPIO口模拟)的方式产生。
还可以通过硬件生成(通过配置IIC控制器来产生)IIC时序。
三、EEPROM(AT24Cxx)
最好是自己查看手册24C02。
AT24C01/02/04/08/16...是一个1K/2K/4K/8K/16K位串行CMOS,内部含有128/256/512/1024/2048个8位字节,AT24C01有一个8字节页写缓冲器,AT24C02/04/08/16有一个16字节页写缓冲器。该器件通过I2C总线接口进行操作,它有一个专门的写保护功能。
AT24C02器件地址为7位,高4位固定为1010,低3位由 A0/A1/A2信号线的电平决定。因为传输地址或数据是以字节为单位传送的,当传送地址时,器件地址占7位,还有最后一位(最低位R/W)用来选择读写方向,它与地址无关。
但在我们这块开发板上的是AT24C04,高4位固定为1010,低3位由 A0/A1/A2信号线的其中A0被数据地址位占用了,而原本的A0接入的是NC状态。具体的器件地址还是要看芯片原理图的接法。当P0接0时则表示对数据地址空间的0~255Bytes进行操作,当P0接1时表示对数据地址空间的256~511Bytes进行操作。
在原理图中,A2、A1均接地,包括接入NC状态的A0也接了地所以此时的设备地址为0xA0,如果加上读写位的话,写地址:0xA0,读地址:0xA1。