IIC
目录
IIC
BH1750型号的光照传感器
IIC通信协议
iic物理层
IIC软件层协议
-- 那么一主多从,怎么选中与指定的从机通信呢?
从机设备地址 -- 从手册中查看
IIC 写操作
IIC 读操作
硬件IIC和模拟 IIC 使用
模拟 IIC 使用
!!!注意:模拟iic的代码最好手敲一遍熟悉一下。
-- 这节课新增一个传感器,就是光照传感器
-- 之前单片机上的光敏传感器只能测出几千几千的数据,测不出真正的光照数据
BH1750型号的光照传感器
-- BH1750
-- 学习一个模块,还是按照之前的学习方法,要先找到这个模块的官方手册
-- 找到手册之后先看引脚定义,咱们这个模块一共5个引脚
-- 可以看到有SCL和SDA引脚,这就是IIC通信的引脚
- 以后见到SCL和SDA,就是IIC通信
-- 然后要了解它的通信方式
-- IIC是一种通信方式,为什么有时候会叫做IIC协议?
- 因为像SPI和IIC通信方式自带的有自身的协议。
-- 什么叫协议?
-
协议一般指的是通信过程中数据传输的格式或者是数据传输的方式
-
比如kqm6600,通信协议是规定他传输数据的格式。(一次8字节)
iic也是一种通信时自带协议的通信
-- 补充:spi是全双工通信,优点:快。iic是半双工通信,优点:占用引脚资源少,但是没有SPI的速度快。
-- iic是串行通信,什么叫串行通信(一位一位发),要发送一字节,就要发送8次.
IIC通信协议
IIC其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线(总线是连接各个部件的信息传输线,使各个部件共享的传输介质),使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。
-- 我们之前也学过总线,有SPI总线,单总线
- 总线:在通信方式上能够连接多个设备
-- iic的应用十分广泛,例如:
-
1、飞行器当中的陀螺仪:
-
2、EEPROM-存储器
-
3、触摸屏(触摸芯片)
-
各种传感器等
iic物理层
-- 两根通信线:SCL(时钟线) 、 SDA(数据线)
-- 电平标准:一般TTL电平标准
-- 需要接上拉电阻
它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个I2C通讯总线中,可连接多个I2C通讯设备,支持多个通讯主机及多个通讯从机。
一个I2C总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线 (SCL)。数据线即用来表示数据,时钟线用于数据收发同步。
也就是说所有IIC设备的SCL,以及SDA都连在一起,设备SCL和SDA都要配置成开漏模式,SCL和SDA各添加一个上拉电阻,阻值一般为4.7k欧姆左右。
-- !!那么怎么判别是哪一个从机向主机发送的数据呢?
每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问.
IIC软件层协议
-- I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。
- 1、开始信号(双方通信的开始):SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
- 2、结束信号(双方通信的结束):SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
-- 对比:SPI有一个缺点:发送过去的数据不知道对方到底收到没。iic避免了这个问题:专门有一个信号叫做应答信号:等待接收方的应答信号。
-- 从机收到这个数据,就会发送一个应答信号,主机收到应答信号,就知道数据发送成功。在iic通信中,每发送一个字节,从机都会发送一个应答。高电平1叫做非应答,0叫做应答。也就是说主机发送数据,从机收到数据,主机会检测到低电平,从机没接收到信号,主机会检测到高电平。双方不通信的时候会是高电平,所以一般将高电平叫做非应答
-- 如果整条iic总线保持静默,两条设备线都是处于高低平
(起始信号和终止信号都是由主机发送的。在起始信号产生之后,总线就处于被占用的状态,在终止信号产生之后,总线就处于空闲状态,起始信号: 一般时钟在最后再回拉低方便时序的拼接)
-
3、主机发送一个字节:SCL低电平期间,主机将数据的一位放到SDA线上(高位先行),然后拉高SCL(也叫做释放SCL),从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,一次循环8次就可以发送一个字节。
-
4、主机接收一个字节:(主机在接收之前,主机需要释放SDA,若不释放,不论从机发送什么,SDA始终都是低电平)SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL(置高电平),主机将在SCL高电平期间读取数据位所以SCL高电平期间SDA不允许有数据变化,循环上述过程8次即可接收一个字节 。
-
5、应答信号: 发送数据的设备:发送完8bit一个字节的数据之后,会等待一定的时间,等接接收方的应答信号(SDA在接收前,拉高释放SDA ),接收端通过拉低SDA数据线,给发送端发送一个应答信号,以提醒发送端我这边已经接受完成,数据可以继续传输,接下来,发送端就可以继续发送数据了。
接收数据的设备:接收到 8bit一个字节数据后,在下一个时钟,需要向发送数据的设备发出一位数据,其中数据0低电平信号,通知发送方已收到数据,数据1 高电平信号,就是没有通知。
-- 在iic通信中,从机不会主动传输数据的,一般主动发起通信的是主机,起始信号和结束信号都是由主机发送的(与SPI一样)
-- tip:通信最基础的就是发送和接收(类似usart和SPI)
-- 什么叫串行通信(一位一位发),要发送一字节,就要发送8次
-- 疑问:上述的情况下MCU都是做主机的,为什么从机没有发送和接收
因为一般从机的通信都是订死的,主机会根据不同的从机做调整。
-- 那么一主多从,怎么选中与指定的从机通信呢?
-
就像SPI通信是通过片选实现的从机通信的。
-
而iic是通过地址实现的从机通信的。在iic总线上的每个设备都有唯一的设备地址 。iic实际上是一个地址通信,每一个iic的从机器件都有自身的地址
-
比如触摸屏有自身的地址,EEPROM也有自身的地址
-
但是一条iic总线上不会有地址相同的从机,如果地址一样,是不允许连接到一个iic总线上
-
每个iic的从设备地址都不一样,从设备的地址只能从手册上查看
-- 在一个项目中,光照传感器的地址是一样的,如果想接多个光照传感器呢?怎么实现?
- 1、选择不同型号的光照传感器
-- 如果只有一个型号怎么办?
- 2、再开一个iic总线或者改器件的地址
-- 器件的地址怎么改?
- iic模块会有一个引脚ADDR,就是用来修改器件地址的引脚。
从机设备地址 -- 从手册中查看
-- 主机根据从机的地址与从机通信。在I2C协议里,分为 7 位和 10 位地址,大多使用 7 位。每个设备出厂时,都会被分配一个地址。若相同芯片接同一个总线,可手动改变(改变从机某个引脚的电平)最后几位地址。
-- 在开始通信的第一个字节一般是 7bit 的地址位+1bit 的读写位(也可以称之为读写位)。数据方向位为“1”时表示主机由从机读数据,该位为“0”时表示主机向从机写数据。
- 注意:就算可以修改同类型设备的地址,一个总线上也不能挂载很多个。
最多能挂载同样地址的三个器件,有拉低,拉高,悬空的方法
IIC 写操作
- 1、产生 start
- 2、传送器件地址 Device_Address,器件地址的最后一位为数据的传输方向位,R/W 低电平0 表示主机往从机写数据(W),1 表示主机从从机读数(R)。ACK 应答,应答是从机发送给主机的应答。
- 3、传送写入器件寄存器地址分别传送高地址和低地址,即数据要写入的位置。
- 4、传送要写入的数据 Data。
- 5、产生 stop 信号
-- SCL默认是高电平,SCL如果变成低电平,只能是主机控制这个引脚发送低电平。主机要想发送,就会先将SCL拉低,这就说明主机正在占用总线,从机就不能发送。主机将数据的一位放到SDA线上,怎么放?就是将SDA数据线拉高就是1,拉低就是0.
IIC 读操作
-- 与写操作类似
- 1、产生 start 信号
- 2、 传送器件地址(写 Device_Address)+读写位,ACK。
- 3、传送字地址,ACK。
- 4、再次产生 start 信号
- 5、 再传送一次器件地址,ACK。
- 6、 读取一个字节的数据,读数据最后结束前无应答 ACK 信号。
- 7、 产生 stop 信号
-- 再看官方手册上是怎么说的
- 总结:想要实现 iic 通信就是要主机与从机之间产生 iic 的时序信号。
第一种,是通过配置两个引脚 为开漏模式,然后通过 cpu 执行代码控制引脚输出高电平,编写逻辑,生成 iic 的通信时序。
第二种,使用 stm32 上的片上外设,通过寄存器操作,直接产生 iic 时序。
硬件IIC和模拟 IIC 使用
-- 在讲硬件I2C之前不得不吐槽一下这个硬件I2C外设,有时候就突然会卡在某个事件的检测,需要关闭电源重新启动才有用,不过虽然可能硬件I2C可能会有问题,可能以后不一定用的到但是我们主要是学习如何用硬件实现I2C协议,对我们以后学别的协议肯定会有帮助。
硬件 I2C:是指直接利用 STM32 芯片中的硬件 I2C 外设,该硬件 I2C 外设跟 USART串口外设类似,只要配置好对应的寄存器,外设就会产生标准串口协议的时序。使用它的I2C外设则可以方便地通过外设寄存器来控制硬件I2C外设产生I2C协议方式的通讯,而不需要内核直接控制引脚的电平。
软件模拟I2C:即直接使用CPU内核按照 I2C 协议的要求控制GPIO输出高低电平。如控制产生 I2C 的起始信号时,先控制作为 SCL 线的 GPIO 引脚输出高电平,然后控制作为 SDA 线的GPIO引脚在此期间完成由高电平至低电平的切换,最后再控制SCL 线切换为低电平,这样就输出了一个标准的 I2C 起始信号。
-- 硬件 I2C 直接使用外设来控制引脚,可以减轻 CPU 的负担。不过使用硬件I2C 时必须使用某些固定的引脚作为 SCL 和 SDA,软件模拟 I2C 则可以使用任意 GPIO 引脚,相对比较灵活。
模拟 IIC 使用
-- 参照官方代码
-- 1、首先配置引脚模式这里拿举例 --开漏模式
- PB6--iic 时钟引脚 SCL
- PB7--iic 数据引脚 SDA --开漏模式
-- 2、封装时序信号
- (1) 起始信号
SDA=1;
SCL=1;
Dealyus(5);
SDA=0;
Dealyus(5);
SCL=0;
Dealyus(5);
- (2) 停止信号
SDA=0;
SCL=1;
Dealyus(5);
SDA=1;
Dealyus(5);
- (3) 发送单字节 -高位先发
- (4) 接收单字节
- (5) 主机发送应答
SDA=0;
- (6) 主机接收应答
SDA=1;
-- 注意:在IO初始化中,我们并没有配置上拉电阻,但是前面我们明明讲过要用上拉电阻,这是为什么呢?
- 答:是我们封装的模块上面有:
-- 应答
-- 接收数据
-- 硬件连接 -- 4个引脚要连
-
PB6 -- SCL
-
PB7 -- SDA
-
vcc -- 3.3v
-
GND