I2C协议详解以及在STM32上的具体使用方法

BN冰凝STM32 2023-09-09 14:16:28 6213阅读 举报



本文将对I2C协议的定义,总线结构,协议内容以及I2C协议在STM32上的具体使用方法等方面进行详细介绍。

一.I2C通信的定义

I2C又写作IIC,英文全称是Inter-Integrated Circuit,两线式串行总线,由飞利浦公司开发用于连接微控制器及其外围设备。IIC是一种多向控制总线,就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实施数据传输的控制源。这种方式简化信号传输总线。
I2C只有一跟数据总线 SDA(Serial Data Line),串行数据总线,只能一位一位的发送数据,属于串行通信,采用半双工通信。何为半双工通信?简单理解就是可以实现双向的通信,但不能在两个方向上同时进行,不能两个方向上同时发送,必须轮流交替进行,其实也可以理解成一种可以切换方向的单工通信,同一时刻必须只能一个方向传输,只需一根数据线。
对于I2C通讯协议把它分为物理层和协议层物理层规定通讯系统中具有机械、电子功能部分的特性(硬件部分),确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准(软件层面)。

二.I2C通信的总线结构


首先来认识一下I2C总线的两根重要的线,一条是时钟线SCL,另一条是数据线SDA。

时钟线主要用于数据收发同步,数据线主要用于传输数据。

I2C总线结构包括一个主机和多个从机,主机和从机之间通信通过地址来确定,每个I2C从机设备都有一个唯一的地址。

总线通过上拉电阻接到电源,这里的上拉电阻大小一般选择4.7K欧姆或者10K欧姆都是可以的。当 I2C 设备空闲时会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平

I2C的引脚的工作模式一般是设置为开漏输出,关于什么是开漏输出以及其他GPIO的工作模式可以参照这篇文章 《详解MCU的GPIO引脚的各种配置方式》

下图是I2C引脚开漏输出的内部结构图:

复用开漏输出的情况上面的PMOS不工作

1.当输出寄存器输出高电平,引脚输出高阻态相当于(开路),假设该引脚接到I2C的SDA总线上,则总线被默认拉成高电平。

2.当输出寄存器输出低电平,引脚输出低电平。

所以当SCL和SDA引脚的寄存器都输出高电平时,实际引脚是高阻态,因为引脚外边又接了两个上拉电阻,所以被上拉成高电平了。

当输出寄存器输出低电平时,下面的N-MOS导通接地,所以引脚输出低电平。

 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线,也就是设备在发送数据之前会检测I2C总线是否忙碌(忙碌总线应该为低电平)。

I2C 具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式下可达 3.4Mbit/s,但目前大多 I2C 设备尚不支持高速模式。

每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问的,地址也是一个数据,主机可以同过SDA发送这个地址出去,则挂载在总线上的设备会自行匹配,匹配成功之后就可以互相通信了。


三.I2C通信的协议

1)空闲状态

I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。


2)起始信号与停止信号

起始信号:当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。

停止信号:当SCL为高期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。




3)应答信号ACK

发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。 

发送端发送完一个字节必须要释放数据线SDA,否则可能因为发送端保持的状态是低电平而导致接收端回复不了高电平。


对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。




4)数据有效性

I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。


即:数据在SCL的上升沿到来之前就需准备好。并在在下降沿到来之前必须稳定。



5)数据的传送

在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。


四.STM32通过I2C协议通信读写EEPROM的具体方法


1.主机写数据到从机


这里发送完最后一个字节时,主机不一定要接收到从机发送的非应答信号才可以发送停止信号,就算从机应答了主机也可以直接发送停止信好终止通讯

其中 S 表示由主机的 I2C 接口产生的传输起始信号(S),这时连接到 I2C 总线上的所有从机都会接收到这个信号。起始信号产生后,所有从机就开始等待主机紧接下来 广播(由SDA线传输数据)

从机地址(SLAVE_ADDRESS)。在 I2C 总线上,每个设备的地址都是唯一的,当主机广播的地址与某个设备地址相同时,这个设备就被选中了,没被选中的设备将会忽略之后的数据信号(引脚输出高阻态与两根总线断开连接)。


根据 I2C 协议,这个从机地址可以是 7 位或 10 位,从机接收到匹配的地址后,主机或从机会返回一个应答(ACK)或非应答(NACK)信号,只有接收到应答信号后,主机才能继续发送或接收数据。


在地址位之后,是传输方向的选择位,表示后面的数据传输方向

该位为 0 时:主机向从机写数据。

该位为 1 时:主机由从机读数据。


2.主机向从机读取数据

记住,数据接收方要产生应答信号(代表我还要数据)或非应答信号(我不要要数据了),不一定就是主机或从机某一个产生。

  • 3.读和写数据混合格式

第一次通讯是确定读写从机设备内部寄存器或存储器的地址,第二次则是读或写上一次确定内部寄存器或存储器的地址上面的数据。


EEPROM和STM32之间使用I2C通讯。使用硬件实现协议。



1.初始化I2C相关的GPIO


2.配置I2C外设的工作模式


3.编写I2C写入EEPROM的byte write函数,编写读取的random read函数(简单但效率低);编写page write和seq read函数并校验(提高工作效率)


4.使用两个读写函数进行读写校验,需要写EEPROM内部时序完成的等待函数。






标签: #I2C协议# #STM32#

版权声明:
作者:BN冰凝
链接:https://www.dianziwang.net/p/137789dacd2b16.html
来源:STM32
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以点击 “举报”


登录 后发表评论
0条评论
还没有人评论过~