我们之前学习串口通信的时候,了解到串口是用三根线进行通信,而我们今天要说的I2C通信也是用了3根线。但I2C与串口有很大区别。I2C虽然只有两条线,但只有一条线可以传递数据。我们称之为SDA,另一条是用来同步时钟的时钟线,我们称之为SCL。
串口的两根线就像是双向车道,可以同时发送和接受数据,因此我们称之为全双工通信。而I2C的数据线SDA虽然也允许双向通信,但同一时刻却只能一端发送,无法同时运行。因此我们称I2C为半双工通信。
为了避免双向的数据冲突,I2C采取了主从模式,一台设备为主机,另一台为从机,只有主机先发送指令,从机才能根据其指令回复相应信息。这种一问一答的主从模式使I2C可以支持多设备通信,这种支持多设备的通信我们称为总线协议。在每个总线上,从机都有对应的设备地址。当作为主机的单片机要操纵对应的从机时,就要在发送数据的最开始加上对应设备的地址,对应设备便能够接受到其数据。
像串口通信一类的异步通信模式,双方约定了一个通信的比特率,双方以各自的时钟为基准进行通信。而I2C通过同步通信模式,主机向从机发送一个固定频率的脉冲信号,来作为I2C总线上所有设备的统一时钟源。
下面我们来描述一次完整的I2C通信。
首先,I2C的数据线和时钟线往往都有上拉电阻进行上拉,在开始通信时,主机发送启动信号,在时钟线依旧是高电平时,将数据线提前下拉,这时,所有从机就已经准备接受命令了。之后,主机会在时钟线上发送一定频率的脉冲信号,主机和从机依靠时钟线上的脉冲信号同步进行数据读写。当时钟线处于低电平时,主机设置数据线的电平,时钟线处于高电平时,从机读取数据线的电平。从机读取到的电平就是主机在高电平时设置的电平。然后,我们便可以根据数据手册,先发送从机的地址,发送完一字节数据后,从机需要回复一个ACK信号,确认自己已经收到数据,就是把信号线拉低一下,之后就是由AHT20展示的时间了。就是之前的过程反过来,当时钟线处于低电平时,从机设置数据线的电平,时钟线处于高电平时,主机读取数据线的电平。一字节后,主机来一次ACK信号,再由AHT20继续发送,如此反复,直到发完所有数据。最后,主机会在时钟线为高电平时将数据线拉高,如此,一次通信便完成了。不难发现,只有在通信开始和结束的时候,才能在时钟线为高电平时设置数据线。