I2C总线
I2C(IIC---Inter Integrated Circuit 内部集成电路)
以上为I2C大体结构图,其中时钟线SCL用于传输时钟信号,数据线SDA来传输实际的数据。
主机与从机
1.主机的职责
假如由从机1和从机2,从机1想向SDA上发送一个低电平,从机2想向SDA上发送一个高电平,如此同一时刻就会发生冲突。为了避免冲突的发送,必须对总线的使用情况做一个管理。
我们规定:在同一时刻,只允许有一个设备向外去发送数据。此规则由主机负责管理,因此主机相当于I2C总线的管理员。
1、波特率的选择
I2C总线中,由主机产生SCL信号,通过SCL线分配给所有从机。因此主机可以通过控制时钟信号频率来调节波特率(即:控制通信速度)。
2、数据通信的方向
仅又主机可以主动向从机发起数据传输,从机不能主动向主机发送数据,必须等待主机读取从机时,从机才能把准备好的数据发送给主机。
传输方向有:主机-->从机、从机-->主机,不存在从机-->从机。
2.数据接收和发送
每个从机都有一个8位的地址,且地址最后一位X的取值代表读(1)或写(0);
主机在总线上发送地址后才能与对应的从机通信,且通信开始与结束都由主机决定;
当SCL为高电平时,SDA上的数据是不允许变化的,因为SCL在高电平时采集数据(起始、停止除外)。
3.I2C数据帧格式
空闲:SCL和SDA均为高电平。
起始位:当SCL为高电平时,SDA由1置0;
停止位:当SCL为高电平时,SDA由0置1;
应答ACK:主机每向从机发送一帧数据后,会立刻释放掉SDA占控权,此时SDA为高电平;随后从机立刻发送一个低电平,表示“收到”。同样,主机接收到从机发送的数据后,也会向从机发送ACK,表示接收到了。
I2C模块简介
在STM32内部有两个I2C模块(即I2C1、I2C2),挂在APB1总线上。每个I2C模块有三个引脚,分别为:SCL、SDA、SMBA;本文不涉及SMBA引脚的讲述。
如下为I2C引脚的重映射(C8T6为例):
复用功能 | Remap=0 | Remap=1 |
I2C1_SCL | PB6 | PB8 |
I2C1_SDA | PB7 | PB9 |
I2C1_SMBA | PB5 | |
I2C2_SCL | PB10 | / |
I2C2_SDA | PB11 | / |
I2C2_SMBA | PB12 | / |
寄存器组与内部结构
1.内部结构
如下为I2C内部结构框图:
不管是I2C1还是I2C2,这两个片上外设的时钟都来自于PCLK1,顺着时钟往里走,有个SCL控制电路模块,将PCLK1转换为SCL信号,并且通过配置CCR来控制SCL的频率以及形状。
对于SDA,其结构与USART类似,具有双缓冲结构(图中绿色部分)。
2.I2C的初始化
首先将SDA、SCL引脚设置为开漏模式(实现“线与”),然后开启I2C时钟,配置寄存器参数,最后闭合总开关。
3.速度模式
对于I2C的时钟信号,有5种速度(频率)可选择,如下:
速度模式 | 波特率max |
标准模式(Sm) | 100K |
快速模式(Fm) | 400K |
快速增强模式(Fm+) | 1M |
高速模式(HSm) | 3.4M |
超快速模式(UFm) | 5M |
而对于STM32,只有标准模式和快速模式,即波特率最大为400K。
一些标志位
BUSY标志位:用于查询总线的空闲状态,0-总线空闲、1-总线忙碌。
START位:用于产生一个起始位,写1-产生起始位、产生后START自动置0。
STOP位:用于产生一个停止位,写1-产生停止位、写0-无停止位。当STM32作主机接收从机数据时,当发送完NAK信号后,要立刻发送停止位。
SB标志位:用于检测起始位是否发送完成,0-没有发生完成、1-发生完成。
AF、ADDR标志位:当寻址或数据发送成功时,ADDR=1(相当于收到ACK信号)、寻址或数据发送失败,AF=1(相当于收到NAK信号)。
在使用AF之前,通常要先对其清零。对于ADDR,当我们先读取SR1寄存器,再读取SR2寄存器后,就会清除ADDR(不要问为什么,ST公司就是这么设计的)
TxE标志位:1-发送数据寄存器TDR为空、0-TDR里面还有待发送的数据。
RxNE标志位:1-接收数据寄存器RDR非空,0-RDR为空。
BTF标志位:发送数据时:1-TDR和移位寄存器均为空,代表数据发送完成、0-数据未发送完成;接收数据时:1-RDR和移位寄存器均非空、0-相反。
ACK位:将ACK位写1-STM32芯片发送出ACK信号,写0-则发送NAK信号。注意,ACK只发送在正在进入移位寄存器或即将进入移位寄存器的字节之后。
I2C通信接收数据的一般流程:
I2C通信发生数据的一般流程: