1、I2C通信特征
1.1、物理接口:SCL + SDA
(1)SCL(serial clock):时钟线,传输CLK信号,一般是I2C主设备向从设备提供时钟的通道。
(2)SDA(serial data): 数据线,通信数据都通过SDA线传输
1.2、通信特征:串行、同步、非差分、低速率
串行:只有一根数据线,每次传输一个bit位;
同步:主设备和从设备的工作时钟频率是一样的,主设备通过SCL时钟线给从设备提供时钟频率;
非差分:因为I2C通信速率不高,而且通信双方距离很近,一般是板级通信,所以使用电平信号通信;
低速率:I2C一般是用在同一个板子上的2个IC之间的通信,而且用来传输的数据量不大,所以本身通信速率很低。一般几百KHz,不同的I2C芯片的通信速率可能不同,具体在编程的时候要看自己所使用的设备允许的I2C通信最高速率,不能超过这个速率;
1.3、通信模式:主设备+从设备
(1)I2C通信时,通信设备之间的地位是平等的,分为主设备和从设备,其中主设备一个、从设备多个。主设备要主导整个通信过程,从设备根据I2C协议被动的响应主设备;
(2)在I2C通信中,没有规定谁做主设备、谁做从设备,是通信双方自己协商的。一个设备在同一时间只能做主设备或者从设备,但是有的设备可以通过软件配置来决定在此次通信时做主设备还是从设备。
1.4、可以多个设备挂在一条总线上
(1)I2C总线上可以挂载一个主设备和多个从设备,实现一对一(一个主设备 + 一个从设备)或者一对多(一个主设备 + 多个从设备)的通信;
(2)主设备负责调度总线,决定某个时间和其中一个从设备通信。在同一时间,只有主设备和其中一个从设备通信,其余的从设备处于等待状态,等待主设备与其通信;
(3)每个从设备在I2C总线上都有唯一的地址,主设备就是通过地址来区分不同的从设备,从而决定和哪一个从设备通信。
1.5、I2C总线的状态
空闲态:当SCL与SDA同时为高电平时,为空闲态;
忙态:主设备和从设备正在通信;
起始状态:当主设备在I2C总线上发出起始信号,开始一次通信;
停止状态:当主设备在I2C总线上发出停止信号,停止本次通信;
1.6、I2C总线协议
(1)主设备发送一个起始信号;
(2)主设备接着发送8bit数据,其中7位是从设备的地址,一位表示此次主设备是要读数据海思写数据;
(3)和主设备发送的地址匹配的从设备发出一个ack响应信号;
(4)主/从设备将数据发送到SDA总线上,每次传输都是8bit数据;
(5)主/从设备从SDA线上接收数据,并发送一个ACK响应信号;
(6)还可以接着n个发送和接收的过程;
(7)主设备发送停止信号,停止本次通信;
1.7、I2C从设备地址
(1)I2C通信的每次有效数据都是8bit,从设备地址是7bit,但是I2C主设备发送从设备地址时还是发送的8bit;
(2)在主设备发送从设备地址时,8bit数据中高7位是从设备地址,最低一位(LSB)是表示读写位;
(3)举例:KXTE9芯片的I2C地址固定为0b0001111(0x0f),最低位是1表示主设备读从设备,最低位是0则表示主设备写从设备。主设备读从设备时SAD是0b00011111,主设备写从设备SAD应该是0b00011110。
1.8、从设备地址知识补充
(1)一般从设备的地址都是固定的,在数据手册里可以查到,这也就是意味着在同一条I2C总线上,不能有两个及以上的同款从设备,不然就无法通过从地址来区分这两个设备。大多数的从设备地址都是固定的,因为没有必要同时接两个,比如重力传感器,你接一个就可以测出重力加速度,何必接两个。但是也有些设备需要同时接多个,比如一块EEPROM芯片(I2C接口)的容量不够就可能接两个。对于这种情况,生成EEPROM的厂家是做了预留的,EEPROM芯片的从地址一部分是固定的,一部分是通过给EEPROM芯片的引脚接高低电平来决定的。
(2)假设EEPROM芯片的7位地址,其中高5位是固定的0b111111,低两位是根据两个引脚的高低电平来确定,接高电平代表1,接低电平代表0。一块芯片把两个引脚接高电平,则从设备地址是0b11111111;另一块芯片把两个引脚把低电平,则从设备地址是0b111100。
1.9、主要用途
I2C通常是用在板级通信的,距离很近,Soc和各种外设的通信就是I2C通信方式,比如触摸屏、各种sensor等,外设的数据手册里会说明通信方式;
2、I2C控制器的结构框图
(1)最左侧是I2C总线的时钟来源,来源是时钟系统的PCLK_PSYS,PCLK_PSYS经过分频后得到I2C总线的时钟频率,然后主设备会通过SCL线将时钟信号传给从设备;
(2)I2C总线的控制单元,里面包含两个重要的寄存器:I2CCON和I2CSTAT寄存器。控制单元会对PCLK_PSYS时钟信号进行两级分频,产生通信需要的时序信号,配置I2C设备的主从模式等,具体细节看两个寄存器的说明;
(3)Address Register和Comparator是当设备作为从设备时用到的,Address Register寄存器里保存的是自己作为从设备的地址,Comparator是比较器,比较此次从I2C设备收到的地址是否和自己的地址相等,如果相等则代表主设备要和自己通信,如果不相等,就不用对此次通信做任何处理。
(3)Shift Register和I2CDS:I2CDS寄存器是保存接收/发送的数据,Shift Register是移位寄存器,负责将I2CDS寄存器里的数据一位一位的发送SDA总线上,或者将总线上的数据一位一位的存到I2CDS总线上,这要看当时是发送模式还是接收模式。
3、I2C控制器的模式
(1)主设备发送模式;
(2)主设备接收模式;
(3)从设备发送模式;
(4)从设备接收模式;
备注:设备可以是上面四个模式中的任意一种,但是同一时间只能是其中的一种,要么是作为主设备要么是作为从设备。
4、I2C的时序分析
4.1、时序介绍
时序就是时间顺序,实际上在通信中时序就是通信线上按照时间顺序发生的电平变化,以及这些变化对通信的意义就叫时序,不对的通信的协议对时序的要求不同。
4.2、通信起始条件和结束条件
起始信号:在SCL为高电平的时候,SDA产生一个下降沿;
停止信号:在SCL为高电平的时候,SDA产生一个上升沿;
4.3、数据有效性
(1)SDA 线上的数据必须在时钟的高电平周期保持稳定,数据线的高或低电平状态只有在 SCL 线的时钟信号是低电平时才能改变。SCL为高电平时表示有效数据,SDA为高电平表示“1”,低电平表示“0”;SCL为低电平时表示无效数据,此时SDA会进行电平切换,为下次数据表示做准备。
(2)数据有效性:在I2C总线通信时,在总线上传输的数据并不都是有效数据。比如开始信号和停止信号,并不代表什么实际的含义,只是通信协议里规定的。正因为我们的有效数据应该在SCL为高电平时SDA保持稳定,所以才能区分出开始信号和停止信号。
4.4、响应ACK
主/从设备在发送完一次数据后,需要一个ACK响应信号。每个通信周期传输8个数据,在第九个通信周期,发送端将SDA总线拉高,然后释放总线的控制权。如果接收端在第九个周期将SDA拉低,就是发出了ACK信号,如果在第几个周期SDA一直是高电平则代表没有发出ACK信号。
4.5、空闲态
空闲态:在I2C总线上没有主、从设备进行通信,此时SCL和SDA一直保持高电平;
5、I2C总线的读/写数据操作
5.1、写模式
(1)主设备发送开始信号;
(2)主设备接着发送8bit数据,其中7bit是从设备的地址,1bit表示此次主设备是要读数据还是写数据;
(3)从设备发送ACK响应信号;
(4)主设备将要写的数据每次发送8bit到SDA线上,从设备接收到发送ACK响应信号;
(5)当主设备发送完数据后,发送一个停止信号;
5.2、读模式
(1)主设备发送开始信号;
(2)主设备接着发送8bit数据,其中7bit是从设备的地址,1bit表示此次主设备是要读数据还是写数据;
(3)从设备发送ACK响应信号;
(4)从设备将数据每次发送8bit到SDA线上,主设备接收到发送ACK响应信号;
(5)当主设备接收完数据后,发送一个停止信号;
6、I2C的通信流程
6.1、I2C通信的主设备发送流程
(1)通过操作I2CCON寄存器,将设备配置成主发送模式;
(2)将从设备的地址写到I2CDS寄存器中; data shift register
(3)往I2CSTAT寄存器写0xF0,让I2C控制器产生一个开始信号;
(4)移位寄存器将I2CDS里的数据发送到SDA总线上;
(5)在收到ACK信号后,中断被挂起,需要中断处理程序来处理;
(6)中断处理程序判断是否是要结束本次通信;
(7)如果不是结束本次通信,则将新的数据写到I2CDS寄存器中,然后清中断挂起标志,将数据发送到SDA总线上,等待ACK信号,进入下一次判断;
(8)如果是要结束本次通信,则往I2CSTAT寄存器中写0xD0,产生一个停止信号,清中断挂起标志,等停止信号发送完毕则结束本次通信;
6.2、I2C通信的主设备接收流程
(1)通过操作I2CCON寄存器,将设备配置成主接收模式;
(2)将从设备的地址写到I2CDS寄存器中;
(3)往I2CSTAT寄存器写0xB0,让I2C控制器产生一个开始信号;
(4)移位寄存器将I2CDS里的数据发送到SDA总线上;
(5)在收到ACK信号后,中断被挂起,需要中断处理程序来处理;
(6)中断处理程序判断是否是要结束本次通信;
(7)如果不是结束本次通信,则从I2CDS寄存器中读取数据,清中断挂起标志,移位器将SDA上的数据再存到I2CDS寄存器中,进入下一次循环判断;
(8)如果是要结束本次通信,则往I2CSTAT寄存器中写0x90,产生一个停止信号,清中断挂起标志,等停止信号发送完毕则结束本次通信;
6.3、I2C通信的从设备接收流程
(1)通过操作I2CCON寄存器,将设备配置成从接收模式;
(2)在SDA总线上检测到开始信号,I2CDS寄存器接收到数据;
(3)将I2CDS寄存器中接收到的数据和I2CADD寄存器中保存的地址进行比较;
(4)判断是否匹配;
(5)如果不匹配,则表示主设备不是和自己通信,不用再进行下面的步骤;
(6)I2C地址匹配则中断产生,告诉设备主设备要和自己通信,并发送一个ACK信号;
(7)从SDA总线上读取数据、处理数据,并发送一个ACK信号,然后清中断;
(8)判断是否要停止本次通信,也就是有没有检测到主设备发送停止信号;
(9)如果不停止通信,则再次从SDA总线上将数据读取到I2CDS寄存器中,然后产生中断,重复之前的步骤;
(10)如果是停止本次通信,则不再做响应即可;
6.4、I2C通信的从设备发送流程
(1)通过操作I2CCON寄存器,将设备配置成从发送模式;
(2)在SDA总线上检测到开始信号,I2CDS寄存器接收到数据;
(3)将I2CDS寄存器中接收到的数据和I2CADD寄存器中保存的地址进行比较;
(4)判断是否匹配;
(5)如果不匹配,则表示主设备不是和自己通信,不用再进行下面的步骤;
(6)I2C地址匹配则中断产生,告诉设备主设备要和自己通信,并发送一个ACK信号;
(7)写数据到I2CDS寄存器,然后清中断;
(8)判断是否要停止本次通信,也就是有没有检测到主设备发送停止信号;
(9)如果不停止通信,则将I2CDS寄存器中的数据发送到SDA总线上,然后产生中断,重复之前的步骤;
(10)如果是停止本次通信,则不再做响应即可;
7、I2CCON寄存器
(1)bit0-3:配置I2C时钟信号的二级分频系数;
(2)bit4:中断挂起标志;
(3)bit5:I2C总线的发送/接收使能;
(4)bit6:配置I2C时钟信号的一级分频系数;
(5)bit7:配置I2C总线是否要在每次通信周期的末尾发送ACK响应信号;
8、I2CSTAT寄存器
(1)bit0:判断上一次的通信周期是否收到ACK响应信号;
(2)bit1:I2C总线的地址清零标志;
(3)bit2:I2C总线从设备的地址标志位;
(4)bit3:I2C的总线总裁标志位;
(5)bit4:发送/接收使能位;
(6)bit5:如果是读,0代表总线空闲,1代表总线忙;如果是写,写0则I2C控制器发出一个停止信号,写1则I2C控制器发出一个开始信号;
(7)bit6-7:配置设备的模式;
9、分析KXTF9-2050芯片的I2C通信协议
参考博客:《通过KXTF9-2050芯片分析I2C协议》。