接口/总线/驱动
1. 什么是I2C?
I2C全拼Inter Integrated Circuit,简称IIC或I2C,是由Philips公司开发的两线时串行总线,用于SOC与外设的连接通讯,它只需要两根线就能实现I2C的通讯,采用主从模式,主的一方可以读写数据,而从的一方只能等待被读写。从的一方没有主动权。
I2C是双向通讯的,由两根线完成,分别是:SDA(串行数据线)、SCL(串行时钟线),接口输出模式为开漏输出,其总线接口已经集成到SOC内部,我们只需要通过原理图找到它的接口,在用外设的杜邦线或者其它方法连接到此接口上就可以实现I2C的通讯。
SDA与SCL都外接了上拉电阻,所以当SDA空闲时刻输出的永远是高电平,它对外设也有一定要求,要求外设的输出模式也是开漏输出,因为这跟它本身的电路实现有关,若两个电路接口模式不一则是无法完成正常通讯的。
其中I2C里的上拉电阻也不是随便用的,因为电阻值越高意味着信号拉高周期越长,那么通讯周期时间就越高,速率就下来了。
I2C为每个设备提供了一个地址,可以通过这个地址找到不同的设备,来表明不同的设备,只有从设备收到是自己的地址时才响应。
因为连接在I2C上的可能有很多个设备,从设备需要设置自己的地址,主设备不用,因为主设备是不会被从设备读写的,主设备是负责读写其它设备的。
通讯时会有一个起始数据,这个数据是9个bit位,前7位是从设备地址,最后一位是方向(0/1(读或写))
这也就表明从设备的地址不能超过7个bit
2. I2C组成原理
架构图:
SMBA线用于SMBUS 的警告信号,I2C 通讯没有使用,可以忽略
I2C内部是有自己的控制单元的,用于处理I2C的通讯,可以说是一个小芯片,它不属于CPU,它只是被集成SOC里(看架构,有的架构是没有的)
3. I2C的特性
仅需两根线
接口集成在PCB内部
因为是开漏输出,电流消耗较小(高电流由上拉电阻完成,通常情况下器件不需要输出高电平所以这块功耗较小)
世界级标准,大多数开发板都支持
一对多,一根线接多跟外设,通过地址区分,节省排版空间
4. I2C的通讯模式
双向传输总线:
模式 | 速率(kbit/s) |
---|---|
标准模式(Standard-mode) | 100 |
快速模式(Fast-mode) | 400 |
快速模式+(Fast-mode Plus) | 1M |
高速模式(High-speed mode) | 3.4M |
单向传输总线:
模式 | 速率(kbit/s) |
---|---|
超快速模式(Ultra Fast-mode) | 5M |
这些模式是根据速率来决定的,也就是说我们将I2C通讯速率设置成与上面对应的速率那么就是处于这个模式当中,其中说是这么快其实是有延迟的,因为要流过上拉电阻,这个取决于上拉电阻的阻值,因为信号在经过上拉电阻时会有一个周期变化,这个周期变化区别于阻值。
设置方法:
我们需要根据当前的PCLK时钟频率来计算的,这和设置PWM占空比类似,都需要经过计算然后设置I2C里的CCR时钟控制寄存器的值,因为如果频率不同是无法正常工作的。
如:时钟频率是66MHZ,预分频值是65MHZ,系数是1/2那么计算公式如下:
时钟频率=PCLK/((预分频值+1))/分频系数
PCLK我们得知是66,分频值我们设置的是65,分频系数是1/2也就是除于2
所以公式:66/(65+1)/2 =0.5
在将0.5转化为HZ的单位:0.5*1000=500KHZ,这里还有一个公式,就是算HZ转秒,赫兹的倒数就是它的秒这个公式:(1/500)=0.002ms,1毫秒=1000微秒,0.002毫秒等于2微秒,通过这样的算法公式就可以得知我们现在的频率是每2微秒工作一次
我们想让它每0.5毫秒工作一次,所以TCNTB的值=500毫秒/当前微秒频率2
500/2=250,所以TCNTB的值应该为250,当然你也可以这也算,2微秒一次,1毫秒=1000微秒,0.5毫秒就等于500微秒,500微秒/2微秒=250,就得出经过250次2微秒后就到达了500微秒,而500微秒就等于0.5毫秒
5. I2C的通讯过程
通讯步骤:
开始信号:SCL为高电平而SDA由高到低的跳变,表示产生一个起始条件
结束信号:SCL为高电平而SDA由低到高的跳变,表示产生一个 停止条件
应答信号:当发送完信号之后则拉低
总线在空闲状态时,SCL和SDA都保持着高电平
这三种信号里,起始信号是必须需要的,而结束信号和应答信号都可以视情况不要。
在起始条件产生后,总线处于忙状态,由本次数据传输的主从设备独占,其他I2C器件无法访问总线;而在停止条件产生后,本次数据传输的主从设备 将释放总线,总线再次处于空闲状态
传输过程:
每次传输时的数据/地址以9位bit进行传输,前8位是数据,最后一位是应答位
传输时高位在前,低位在后
主设备在SCL和SDA都处于高电平状态时,先将SDA拉到低电平,然后在将SCL也拉入低电平,这样SDA产生了一个下降沿的信号,从设备检测到之后便知道主设备发来了起始信号,那么从设备需要主动拉高SDA线告诉主设备我准备好了
这个电平变化不是说一个时间点的变化,比如上一秒是高电平下一秒是低电平这不算变化,时间点变化是要求在一个周期里某一时间段处于高电平,某一时间段处于低电平,整个周期里完成这样一个动作才属于上升沿或下降沿变化,这个周期取决于I2C的时钟频率
如下图的周期变化,假设一个周期是1.2毫秒,那么这个毫秒里的周期变化如下
T1到T2之间处于高电平,T3到T4之间处于低电平,然后整个周期就变成了下降沿的信号
然后主设备会在SCL线上产生时钟周期的脉冲信号,即发高电平,每产生一个脉冲信号都会从SDA线上发送一个数据出去,然后从设备检测到脉冲信号了就从SDA线上去读一个BIT位,在产生脉冲信号之后,SCL是处于低电平的,那么此时SDA电平会根据传输的数字信号进行翻转(为了防止数据不稳定,要求在SCl处于低电平时SDA才允许改变电平值,SCL发送一次脉冲信号后会要求拉低电平)
首先最开始发送的是地址信息,每次有效位为8位,当主设备发送8位之后就不会在发了,且发送完八位以后会主动让SDA线一直处于高电平(因为SDA线发送BIT可能是高或低电平,可能第8位是低电平所以需要拉高回来),然后就会一直等待从设备拉低,当从设备拉低以后那么主设备监听到之后就会认为此次通讯是正确的
然后接下来就可以发送数据位了,与地址信息一样,SCL产生脉冲之后SDA进行翻转,从设备进行读取,当发送完成之后就需要产生停止位,这个是由主设备完成的,会拉高SCL电平使其一直处于高电平,然后将SDA进行周期变化:上升沿,即在一定周期里拉低电平然后在拉高电平,然后此时SCL与SDA都处于高电平模式,则代表总线处于空闲状态可以被其它设备占用
从设备是需要实时监听SCL的电平变化,来完成对应的动作
以下是发送170(十六进制:0xAA; 二进制:1010 1010)到从设备的传输时序:
总结理解起始与结束信号就是:
起始条件:SCL线是高电平时,SDA线从高电平向低电平切换。
停止条件:SCL线是高电平时,SDA线从低电平向高电平切换。
这其中还有重复起始条件,即不用停止符号,只需要发送一个重复起始条件后续可以发送任意字节的数据,当全部发送完成之后在发送停止条件
即在不释放总线的情况下给从设备发送Sr信号,然后重复上一次的传输,这样做的好处在于不会出现在传输期间被别的设备抢占的情况,因为每次传输结束都会有一定的空闲时间,如果这个时间周期被别的设备占用会出现一些数据不完整的情况,因为每次传输只能传输一个字节的有效数据位,每次通讯都要产生起始和结束信号,所以会有一定的空闲时间
具体的通讯步骤可以参考I2C官方文档
6. I2C接口工作模式
I2C接口有四种工作模式
工作模式 | 介绍 |
---|---|
从发送器模式 | 从设备收到主设备发来的ADDR地址后,将内部的数据寄存器里的值通过数据控制模块,发送给SDA总线,这种模式一般应用于主设备读取从设备里的数据 |
从接收器模式 | 从设备收到主设备发来的ADDR地址后,通过数据控制模块将SDA总线的数据存于到数据寄存器中 |
主发送器模式 | 在发送ADDR地址后且得到从设备响应后将数据寄存器里的值发送到SDA总线上 |
主接收器模式 | 在发送ADDR地址后且得到从设备响应后将SDA总线上的数据写入到数据寄存器中 |
数据寄存器一般是DR寄存器(数据缓存寄存器),这块寄存器是等待内部程序将其读走的
其中因为是高位到地位发送的,所以内部会有一个位移寄存器的过程才能写入到DR寄存器
7. 硬件拉高拉低的过程
I2C的SDA与SCL都外接了上拉电阻,如果一直处于拉高状态那么只能输出高电平无法输出低电平,那么数字逻辑信号时钟是1,这样结果是不对的,所以需要有一个拉低的过程才能保证传输的bit位是有效且正确的。
I2C内部有一个逻辑控制器,负责控制这一块,当需要上拉时候会控制FET(场效应管,主要作用是控制半导体器件,控制电阻值),来拉低上拉电阻值使其电流固定在低电平值范围,产生低电平信号
拉低:
拉高:
S3C2400的物理层的拓扑结构(仅供参考):
8. 一对多
I2C给每个从设备设置地址,然后通过发送地址位来选择要操控哪个从设备。
在每个从设备连接后需要设置自己的地址,便于I2C主设备查找。
每个设备连接到I2C的SDA与SCL上,然后I2C主设备对这条线发送地址当从设备收到以后来确定是否是寻找自己
下图的连接就是将所有设备的SCL与SDA连接到I2C的主设备上,也就是说将I2C主设备的SDA与SCL引出来,然后从设备接到这根线上去,然后发送数据时接在这跟线上的所有设备都能监听到电平变化,就像socket的广播模式一样。
主设备是不需要设置自身地址的,因为不会有人找它,当然如果要与其它外设进行合作开发,可以设置一个自己的地址,并编写监听代码让自己做主或从
9. 开发流程
主机接收模式:
主机发送模式:
审核编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !