STM32的 I2C 片上外设专门负责实现 I2C 通讯协议, 只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU 只要检测该外设的状态和访问数据寄存器,就能完成数据收发。架构图如下所示。
通讯引脚:STM32 芯片有多个 I2C 外设,外设的 I2C 通讯信号引出到不同的 GPIO 引脚上,使用I2C时须配置这些指定的引脚。
时钟控制逻辑:SCL 线的时钟信号,由 I2C 接口根据时钟控制寄存器(CCR)控制,控制的参数主要为时钟频率。配置 I2C 的 CCR 寄存器可修改通讯速率相关的参数。STM32 的 I2C 外设都挂载在 APB1 总线上,使用 APB1 的时钟源 PCLK1。
SCL 时钟周期内的高电平时间为Thigh,低电平时间为Tlow,那么在标准模式下(I2C 通讯的“标准/快速”模式,这两个模式分别 I2C 对应 100/400Kbit/s 的 通讯速率),Thigh=CCR * TPCLK1;Tlow=CCR * TPCLK1(快速模式下Thigh=CCR * TPCLK1;Tlow=2 * CCR * TPCLK1)
。由此可知CCR对通信速率的影响。例子如下。
数据逻辑控制:I2C 的 SDA 信号主要连接到数据移位寄存器上。
数据寄存器(DR):当向外发送数据的时候,数据移位寄存器以数据寄存器(DR)为数据源,把数据一位一位地通过SDA信号线发送出去;从外部接收数据的时候,数据移位寄存器把 SDA 信号线采样到的数据一位一位地存储到数据寄存器(DR)中。
PEC寄存器:若使能了数据校验,接收到的数据会经过 PCE 计算器运算,运算结果存储在PEC寄存器中。
自身地址寄存器(OAR1、OAR2):I2C设备工作在从机模式的时候,接收到设备地址信号时,数据移位寄存器会把接收到的地址与从机自身的I2C地址寄存器的值作比较,以便响应主机的寻址。STM32 的自身 I2C 地址可通过修改自身地址寄存器(OAR1、OAR2)修改,支持同时使用两个 I2C 设备地址。(STM32 的 I2C 外设可同时使用两个地址,即同时对两个地址作出响应)
整体控制逻辑:负责协调整个 I2C 外设。控制逻辑负责控制产生 I2C 中断信号、DMA 请求及各种 I2C 的通讯信号(起始、停止、响应信号等)。
控制寄存器(CR1/CR2):控制逻辑的工作模式根据控制寄存器(CR1/CR2)的参数而改变。
状态寄存器(SR1 和 SR2):外设工作时,控制逻辑会根据外设的工作状态修改状态寄存器(SR1 和 SR2)。只要读取这些寄存器相关的寄存器位,就可以了解 I2C 的工作状态。
通信过程:使用 I2C 外设通讯时,在通讯的不同阶段会对状态寄存器(SR1 及 SR2)的不同数据位写入参数,我们通过读取这些寄存器标志来了解通讯状态。
主发送器流程:作为 I2C 通讯的主机端时,向外发送数据时的过程。
事件EV5:主发送器产生起始信号(S),当发生起始信号后,产生事件EV5,并会对 SR1 寄存器的“SB”位置 1,表示起始信号已经发送。
事件EV6、EV8:紧接着主发送器发送设备地址并等待应答信号,若有从机应答,则产生事件“EV6”及 “EV8”,这时 SR1 寄存器的“ADDR”位及“TXE”位被置 1,ADDR 为 1 表示地址已经发送,TXE 为 1 表示数据寄存器为空。
事件EV8:以上步骤正常执行并对 ADDR 位清零后,往 I2C 的数据寄存器(DR)写入要发送的数据,这时 TXE 位会被重置 0,表示数据寄存器非空,I2C 外设通过 SDA 信号线一位位把数据发送出去后,又会产生事件EV8,即 TXE 位被置 1, 重复这个过程,就可以发送多个字节数据了。
事件EV8_2:当发送数据完成后,控制 I2C 设备产生一个停止信号§,这个时候会产生 EV8_2 事件,SR1 的 TXE 位及 BTF 位都被置 1,表示通讯结束。
假如使能了 I2C 中断,以上所有事件产生时,都会产生 I2C 中断信号,进入同一 个中断服务函数,到 I2C 中断服务程序后,再通过检查寄存器位来判断是哪一个事件。
主接收器过程:作为 I2C 通讯的主机端时,从外部接收数据的过程。
和发送过程区别在于:
EV7事件:从机端接收到地址后,开始向主机端发送数据。当主机接收到这些数据后,会产生EV7事件,SR1 寄存器的 RXNE 被置 1,表示接收数据寄存器非空,读取该寄存器后,可对数据寄存器清空,以便接收下一次数据。此时可以控 制 I2C 发送应答信号(ACK)或非应答信号(NACK),若应答,则重复以上步骤接收 数据,若非应答,则停止传输;