STM32F429 >> 12. I²C 通讯

版权声明:如需转载请标注 https://blog.csdn.net/weixin_40973138/article/details/86498401

本工程板级支持包文件适用于野火stm32f429 开发板。

I²C 物理层

在这里插入图片描述

一个I²C 总线只使用两条总线线路,一条双向串行数据线(SDA),一条串行时钟线(SCL)。

I²C 协议层

1. I²C基本读写过程

在这里插入图片描述
其中黑色表示数据由主机传输至从机。S 表示传输开始信号;SLAVE_ADDRESS 表示从机地址;
白色表示数据由从机传输至主机。R/W 表示传输方向选择位,1为读,0为写;A/A 表示应答(ACK)或非应答(NACK)信号;P 表示停止传输信号。

2. 通讯的起始和停止信号

  • 起始信号:当SCL 线是高电平时SDA 线从高电平向低电平切换;
  • 停止信号:当SCL 是高电平时SDA 线由低电平向高电平切换。
    在这里插入图片描述

3. 数据有效性

SCL 为高电平的时候SDA 表示的数据有效,
SCL 为低电平时,SDA 的数据无效,SDA 常在这时进行电平切换。

4. 地址及数据方向

总线上每个设备都有自己的独立地址,主机发起通讯时通过 SDA 信号线发送设备地址(SLAVE_ADDRESS)来查找从机。
I²C 协议规定设备地址可以是 7位或 10 位,实际中 7 位的地址应用比较广泛。紧跟设备地址的一个数据位用来表示数据传输方向,它是数据方向位(R/W),第 8位或第 11 位。数据方向位为“1”时表示主机由从机读数据,该位为“0”时表示主机向从机写数据。
在这里插入图片描述

5. 响应

I²C 的数据和地址传输都带响应。响应包括“应答(ACK)”和“非应答(NACK)”两种信号。
作为数据发送方,在发送完一个字节的数据后,在第九个时钟脉冲来临前释放SDA 线(电平拉高)。然后在第九个脉冲高电平期间读取SDA 电平高低,当其为高电平时,即为非应答信号;当为低电平时即为应答信号。
作为数据接收端时,当设备(无论主从机)接收到 I2C 传输的一个字节数据或地址后,若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号,发送方会继续发送下一个数据;若接收端希望结束数据传输,则向对方发送“非应答(NACK)”信号,发送方接收到该信号后会产生一个停止信号,结束信号传输。
在这里插入图片描述

STM32 的I²C 特性及架构

若直接控制 STM32的两个 GPIO 引脚,分别用作 SCL及 SDA,按照上述信号的时序要求,直接像控制 LED 灯那样控制引脚的输出(若是接收数据时则读取 SDA电平),就可以实现 I2C 通讯。
同样,若按照 USART的要求去控制引脚,也能实现 USART通讯。
所以只要遵守协议,就是标准的通讯。

直接控制 GPIO 引脚电平产生通讯时序时,需要由 CPU 控制每个时刻的引脚状态,所以称之为“软件模拟协议”方式。

相对地,还有“硬件协议”方式,STM32 的 I²C 片上外设专门负责实现 I²C 通讯协议,只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU只要检测该外设的状态和访问数据寄存器,就能完成数据收发。

STM32 的I²C 架构刨析

在这里插入图片描述

  1. 通讯引脚
    在这里插入图片描述

  2. 时钟控制逻辑

  3. 数据控制逻辑
    I²C 的 SDA信号主要连接到数据移位寄存器上,数据移位寄存器的数据来源及目标是数据寄存器(DR)、地址寄存器(OAR)、PEC寄存器以及 SDA数据线。

当向外发送数据的时候,数据移位寄存器以“数据寄存器”为数据源,把数据一位一位地通过 SDA 信号线发送出去;
当从外部接收数据的时候,数据移位寄存器把 SDA信号线采样到的数据一位一位地存储到“数据寄存器”中。

若使能了数据校验,接收到的数据会经过 PCE计算器运算,运算结果存储在“PEC寄存器”中。
当 STM32 的 I²C 工作在从机模式的时候,接收到设备地址信号时,数据移位寄存器会把接收到的地址与 STM32的自身的“I²C 地址寄存器”的值作比较,以便响应主机的寻址。
STM32 的自身 I²C 地址可通过修改“自身地址寄存器”修改,支持同时使用两个 I²C 设备地址,两个地址分别存储在 OAR1和 OAR2中。
4. 整体控制逻辑
整体控制逻辑负责协调整个 I²C 外设,控制逻辑的工作模式根据我们配置的“控制寄存器(CR1/CR2)”的参数而改变。
在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR1和 SR2)”,我们只要读取这些寄存器相关的寄存器位,就可以了解 I²C 的工作状态了。

除此之外,控制逻辑还根据要求,负责控制产生 I²C 中断信号、DMA请求及各种 I²C 的通讯信号(起始、停止、响应信号等)。

通讯过程

使用 I²C 外设通讯时,在通讯的不同阶段它会对“状态寄存器(SR1及 SR2)”的不同数据位写入参数,我们通过读取这些寄存器标志来了解通讯状态。

主发送器

在这里插入图片描述

  1. 控制产生起始信号(S),当发生起始信号后,它产生事件“EV5”,并会对 SR1 寄存器的“SB”位置 1,表示起始信号已经发送;
  2. 紧接着发送设备地址并等待应答信号,若有从机应答,则产生事件“EV6”及“EV8”,这时 SR1 寄存器的“ADDR”位及“TXE”位被置 1,ADDR 为 1表示地址已经发送,TXE为 1 表示数据寄存器为空;
  3. 以上步骤正常执行并对 ADDR 位清零后,我们往 I²C 的“数据寄存器 DR”写入要发送的数据,这时 TXE位会被重置 0,表示数据寄存器非空,I²C 外设通过SDA 信号线一位位把数据发送出去后,又会产生“EV8”事件,即 TXE 位被置 1,重复这个过程,就可以发送多个字节数据了;
  4. 当我们发送数据完成后,控制 I²C 设备产生一个停止信号§,这个时候会产生EV2事件,SR1的 TXE位及 BTF位都被置 1,表示通讯结束。

若使能I²C 中断,以上所有事件产生时,都会产生I²C 中断信号,进入同一个中断服务函数。

主接收器

在这里插入图片描述

  1. 起始信号(S)是由主机端产生的,控制发生起始信号后,它产生事件“EV5”,并会对 SR1寄存器的“SB”位置 1,表示起始信号已经发送;
  2. 紧接着发送设备地址并等待应答信号,若有从机应答,则产生事件“EV6”这时SR1 寄存器的“ADDR”位被置 1,表示地址已经发送。
  3. 从机端接收到地址后,开始向主机端发送数据。当主机接收到这些数据后,会产生“EV7”事件,SR1寄存器的 RXNE 被置 1,表示接收数据寄存器非空,我们读取该寄存器后,可对数据寄存器清空,以便接收下一次数据。此时我们可以控制 I²C发送应答信号(ACK)或非应答信号(NACK),若应答,则重复以上步骤接收数据,若非应答,则停止传输;
  4. 发送非应答信号后,产生停止信号§,结束传输。

EEPROM

这是本开发板上的EEPROM 硬件设计
在这里插入图片描述
EEPROM 芯片的设备地址一共有 7位,其中高 4 位固定为:1010 b,低 3 位则由 A0/A1/A2信号线的电平决定。其中R/W 位是读写方向位,与地址无关。
在这里插入图片描述
按照我们此处的连接,A0/A1/A2均为 0,所以 EEPROM的 7 位设备地址是:1010000b ,即 0x50。
由于 I²C通讯时常常是地址跟读写方向连在一起构成一个 8 位数,且当R/W位为 0时,表示写方向,所以加上 7 位地址,其值为“0xA0”,常称该值为 I²C设备的“写地址”;当 R/W位为 1时,表示读方向,加上 7位地址,其值为“0xA1”,常称该值为“读地址”。

向EEPROM 发送数据

在I²C 写数据通讯中,除了向EEPROM 发送设备地址外,还需发送两个字节数据,第一个数据是内存地址,第二个数据才是真正需要写入的信息。
在这里插入图片描述

单个字节数据写入

页写入

EEPROM 定义了一种页写入时序,即第一个数据被解释为要写入的内存地址address1,后续可连续发送n 个数据,这些数据依此写入到address1,address2,address3…中

但AT24C02 型号的芯片页写入时序最多可以一次发送8个数据,该值也称为页大小
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从EEPROM 读取数据

从EEPROM 读取数据是一个复合的I²C 时序,实际上包含一个写过程和一个读过程
在这里插入图片描述
第一个通讯过程:

  1. 首先发送开始信号;
  2. 然后使用I²C 发送设备地址寻址(写方向)首先使用I²C 发送设备地址寻址(写方向);
  3. 接着发送要读取的“内存地址”;

第二个通讯过程:

  1. 再次发送开始信号;
  2. 再次使用I²C 发送设备地址寻址,但此时是读方向;
  3. 随后EEPROM 就会向主机返回从“内存地址”开始的数据,并一个字节一个字节地传输(当主机发送“非应答信号”时,即停止传输

由于I²C 通讯代码较多,代码已转移https://blog.csdn.net/weixin_40973138/article/details/86531427

猜你喜欢

转载自blog.csdn.net/weixin_40973138/article/details/86498401