嵌入式之IIC协议及其相关
IIC
协议
协议:
协议简单来说就是主机与从机双方约定一组动作,只要一方做了特定的动作,另一方就可以知道你要干什么,然后就可以给出特定的回复动作,多次重复就可以实现通信。
以下是我总结的IIC
读写的步骤,仅供参考:IIC
读数据:
发送起始信号
发送从机地址 - 发送(写入)
发送寄存器地址
起始信号
发送从机地址 - 接收(读取)
接收数据
发送停止信号
IIC
写数据:
发送起始信号
发送从机地址 - 发送(写入)
发送寄存器地址
发送数据
发送停止信号
软件模拟IIC
实现与硬件IIC
由于在IIC
总线的通信过程中,时钟信号由主设备产生,从设备根据时钟信号进行数据传输(即同步通信)。故可通过代码方便地模拟该协议,也即所谓的模拟IIC
协议。
不过,对于异步通信来说,软件就没办法进行模拟了,比如常见的串口通信。
在软件模拟 IIC
时 GPIO
一般为开漏模式,支持线与功能;不过由于开漏模式无法输出真正的高电平,所以需要外部上拉(IIC
的电平只是通信使用,所以负载强度不大;一般总线上认为,低于0.3Vdd
为低电平,高于0.7Vdd
为高电平)
推挽输出不能实现线与功能,因为如果两个输出引脚,一个输出高电平P-MOS
管导通,一个输出低电平N-MOS
管导通,则P-MOS
管上方的高电平会经过P-MOS -> N-MOS -> GND
,整个通路上没有外接电阻,因此电阻很小相当于高电平直接接到低电平造成了短路。
模拟 I2C
是用两条 GPIO
管脚的软件模拟的,将一个 GPIO
设置为数据线 SDA
,另外一个设置为时钟线 SCL
。
硬件 I2C
则是通过一个 I2C
控制器实现的,该控制器被建立在微控制器芯片或单独的 I2C
芯片中,通过集成的硬件内部逻辑和电路来控制时序和数据格式,实现 I2C
总线通信。
软件与硬件的IIC
各有优缺点,可根据实际情况选用。
注:在使用软件模拟IIC
时,其实IIC
的IO
口既可以配置为推挽输出也可以配置为开漏输出,不同之处在于当IO
口配置为推挽输出时,发送和接收数据时需要切换IO
口的输入输出模式,发送数据时需要将IO
口切换为输出模式,接收数据时需要将IO
口切换为输入模式。如果配置开漏输出则不需要切换IO
口的输入输出模式。我们知道推挽输出不具有线与的功能,但是由于我们使用软件IIC
时通常不会有多个设备连接到一个总线上的情况,所以只有一个从设备的话,也就不会有线与的情况发生了,可以使用推挽输出。但是我们需要根据发送数据和接收数据来切换IO
口的工作模式。
模拟IIC
代码实现
注:有时候器件规格书上标明的设备地址不一定非得按照该地址进行寻址!
具体来说就是,假如:现有一传感器,使用
IIC
通信;其规格书标明设备地址可选(0x18、0x19)
,假如根据硬件连接,我们选用的地址为0x18
;这并不意味着我们寻址是直接使用#define SLAVE_ADDR 0x18
就行,很可能需要进行一番运算,即:#define SLAVE_ADDR (0x18 << 1)
。如果IIC
使用7位地址,那么<< 1
的作用就很明了了:将最低位让出,用做读写位。所以如果使用
IIC
时,根据规格书上的地址寻不到从设备且检查并无其他问题,那么就可以考虑一下该情况!
1 | /** |
硬件IIC通信示例
1 | void My_IIC_Init(void) |
注意
- 根据传输的数据位来拉
SCL
与SDA
线电平:若为逻辑1,则拉高SCL
与SDA
线电平,若为逻辑0就拉低 SCL
与SDA
需默认拉高,以释放总线状态,此时为准备好数据传输状态IIC
起始信号:SCL
高电平,SDA
下降沿(注:起始后需把SCL
也拉低,使主机占用总线准备发送数据);IIC
结束信号:SCL
高电平,SDA
上升沿;- 主机发送:每次发送1位,循环8次即可发送一个字节;在发送数据时应注意:
SCL
高电平时,此时SDA
上数据有效,不可被更改;SCL
低电平时,SDA
上数据可被更改,也只有这时数据可被更改 - 从机接收:在接收前,应先拉高
SDA
,避免主机抢占SDA
,导致数据出错;为存储接收到的数据,需拉高SCL
,使主机在SCL
高电平期间读取SDA
,每读取一位就存入提前申请好的变量中;读完后即可得到一个字节的数据。然后拉低SCL
,使从机可写入SDA
,这样即可实现从机发送。 - 应答信号:主机把应答位数据放到
SDA
线(即:如需应答则拉低SDA
,如无需应答则拉高SDA
);然后先拉高SCL
,以读取应答位;再拉低SCL
,开始下一个时序模块;
补充
推挽输出
推挽(Push-Pull
)通常用于需要强驱动能力的场景。
推挽输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出既提高电路的负载能力,又提高开关速度。
下面是一个典型的推挽输出电路:上面的三极管是NPN
型三极管,下面的三极管是PNP
型三极管,分别有以下两种情况,请留意控制端、输入端和输出端。
输出低电平:从负载拉电流
当Vin
电压为V-
时,下面的三极管有电流流出,Q4
导通,Q3
截止,于是电流从上往下流过。经过下面的P
型三极管提供电流给负载(Rload
),这就叫「挽」。
输出高电平:向负载灌电流
当Vin
电压为V+
时,上面的N型三极管控制端有电流输入,Q3
导通,Q4
截止,于是电流从上往下通过,提供电流给负载。经过上面的N型三极管提供电流给负载(Rload
),这就叫「推」。
开漏输出(开集输出)
开漏输出指的是场效应管(可以类比晶体管来理解,对于晶体管来说,也就变成了开集电极输出)的漏极开路输出,只能输出低电平和高阻态(只有接上拉电阻才能输出高电平)。
以下图为例,当内部输出为1时,经过非门变为0,也就是场效应管的栅极电压为0,此时场效应管截止(相当于开路),那么单片机IO
的输出是什么呢?是没办法确定的,注意并没有上拉电路。如果有上拉电阻呢,当然就是VCC
,也就是逻辑1。当内部输出0时,栅极电压为1,此时场效应管导通,单片机IO
与地连接,输出为0。
开漏结构(OD
)对比推挽结构:开漏结构只有一个三极管或者MOS
管,推挽结构则有两个。
之所以叫开漏,是因为MOS
管分为三极:源极、栅极、漏极。漏极开路输出,所以叫开漏输出;
如果是三极管:基极、集电极、发射极,集电极开路输出,就叫开集输出(OC
)。
浮空输入
顾名思义,浮空就是浮在空中,既不上拉也不下拉;
通俗讲就是让管脚什么都不接,浮空着,呈高阻态。
浮空最大的特点就是电压的不确定性,它可能是0V
,也可能是VCC
,还可能是介于两者之间的某个值(最有可能)完全由外部输入决定,引脚悬空的情况下,该端口的电平是不确定的。
用途:
- 浮空可用来做
ADC
输入,这样可以减少上下拉电阻对结果的影响。 - 用于外部按键输入。
高阻态
高阻状态是三态门电路的一种状态,三态为高电平、低电平、高阻态。
当处于高阻态时,无论该门的输入如何变化,都不会对其输出有影响。
高阻态近似为开路状态,控制信号无法控制引脚的电平,引脚测量电压可能为任意的电压值。
上拉 & 下拉
上拉就是将引脚通过一个电阻连接到VCC
上;
上拉电阻的功能主要是为集电极开路输出型电路和开漏输出提供输出电流通道,将不确定的信号通过一个电阻钳位在高电平(可以结合上面的开漏输出来理解),电阻同时起限流作用。
所谓的强上拉、弱上拉,只是上拉电阻的阻值不同。
下拉就是将引脚通过一个电阻连接到GND
上,将不确定的信号通过一个电阻钳位在低电平。
三极管 & 场效应管
三个极:
三极管是半导体基本元器件之一,具有电流放大作用;
共有三个极:发射极(Emitter
)、基极(Base
)和集电极(Collector
);中间部分是基区,两侧部分是发射区和集电区,排列方式有PNP
和NPN
两种。
场效应管有三个极:源极(S - Source
),栅极(G - Gate
),漏极(D - Drain
),对应于晶体管的发射极(E
),基极(B
),以及集电极(C
),排列方式也有P
沟道和N
沟道两种。
MOS
管的源极和漏极是可以对调的,他们都是在P
型backgate
中形成的N
型区。在多数情况下,这个两个区是一样的,即使两端对调也不会影响器件的性能,这样的器件被认为是对称的。
N-MOS
的特性,Vgs
大于一定的值就会导通,适合用于源极接地时的情况(低端驱动)。P-MOS
的特性,Vgs
小于一定的值就会导通,适合用于源极接 VCC
时的情况(高端驱动)。
三极管与场效应管的基本工作原理:
- 三极管:三极管是一种电流控制元件,其工作原理是通过控制输入电流来改变输出电流。三极管有
NPN
型和PNP
型两种类型,电流方向不同。 - 场效应管:场效应管是一种电压控制元件,通过控制输入电压来改变输出电流。场效应管分为结型场效应管和金属氧化物场效应管(
MOS
管),其中MOS
管是最常见的类型。
三极管与场效应管的主要区别:
- 控制方式:三极管是电流控制元件,需要输入电流才能产生输出电流;而场效应管是电压控制元件,输入端电流极小,适用于低功耗应用。
- 输入阻抗:三极管的输入阻抗较小,而场效应管的输入阻抗较大,适用于高输入电阻的场合。
- 噪声性能:场效应管的噪声系数较低,适用于低噪声放大器的前置级。
- 温度特性:三极管是负温度系数器件,而场效应管是正温度系数器件,场效应管在高温下功耗增加,可能导致更高的温度。
- 开关频率:场效应管的开关频率高于三极管,适用于高速开关应用。
应用场景:
- 三极管:适用于低频放大、开关电路和功率放大等应用。
- 场效应管:适用于高频放大、低噪声放大、开关电路和低功耗电路等。
线与
线与:所有GPIO
输出高就是高,只要有一个输出低,整条线上面的都是低,这就是“与”的意思。