STM32—I2C

news2024/11/24 2:17:27

1.I2C

  • I2C总线(Inter l0 BUs)是由Philips公司开发的一种通用数据总线
  • 两根通信线:SCL(Serial Clock)、SDA(Serial Data)
  • 同步,半双工
  • 带数据应答
  • 支持总线挂载多设备(一主多从、多主多从)

MPU6050模块:可以进行姿态测量,使用了12C通信协议

第3个图片是AT24C02,存储器模块

第4个图片是DS3231,实时时钟模块

2.硬件电路

  • 所有I2C设备的SCL连在一起,SDA连在一起
  • 设备的SCL和SDA均要配置成开漏输出模式
  • SCL和SDA各添加一个上拉电阻,阻值一般为4.7KQ左右

这个图就是I2C的一个典型电路模型,这是一个一主多从的模型,左边CPU就是我们的单片机,作为总线的主机,主机的权力很大,包括,对SCL线的完全控制,任何时候,都是主机完全掌控SCL线,另外在空闲状态下,主机可以主动发起对SDA的控制,只有在从机发送数据和从机应答的时候,主机才会转交SDA的控制权给从机,这就是主机的权力

然后看下面,这一系列都是被控IC,也就是,挂载在I2C总线上的从机,这些从机可以是姿态传感器、OLED、存储器、时钟模块等,从机的权利比较小,对于SCL时钟线,在任何时刻都只能被动的读取,从机不允许控制SCL线,对于SDA数据线,从机不允许主动发起对SDA的控制,只有在主机发送读取从机的命令后,或者从机应答的时候,从机才能短暂地取得SDA的控制权,这就是一主多从模型中协议的规定

然后看接线,这里第一条写的是,所有I2C设备的SCL连在一起,SDA连在一起,这就是接线要求,在这个图里可以看到,主机SCL线一条拽出来,所有从机的SCL都接在这上面,主机SDA线也是一样,拽出来,所有从机的SDA接在这上面,这就是SCL和SDA的接线方式

先忽略上面两个电阻,假设我们就这样连接,那如何规定每个设备SCL和SDA的输入输出模式呢,SCL应该好规定,因为现在是一主多从,主机拥有SCL的绝对控制权,所以主机的SCL可以配置成推挽输出,所有从机的SCL都配置成浮空输入或者上拉输入,数据流向是,主机发送,所有从机接收,但是到SDA线这里,就比较麻烦了,因为这是半双工的协议,所以主机的SDA在发送的时候是输出,同样,从机的SDA也会在输入和输出之间反复切换,如果你能协调好输入输出的切换时机,那其实也没问题,但是这样做,如果总线时序没协调好,极有可能发生两个引脚同时处于输出的状态,如果这时又正好是一个输出高电平,一个输出低电平,那这个状态就是电源短路,这个状态是要极力避免的,所以为了避免总线没协调好导致电源短路这个问题,12C的设计是,禁止所有设备输出强上拉的高电平,采用外置弱上拉电阻加开漏输出的电路结构,这两点规定就是上面的这两条,设备的SCL和SDA均要配置成开漏输出模式,SCL和SDA各添加一个上拉电阻,阻值一般为4.7KQ左右

所有的设备,包括CPU和被控IC,它引脚的内部结构都是右图这样的,左边这一块是SCL的结构,这里SCLK就是SCL的意思,右边这一块是SDA的结构,这里DATA就是SDA的意思,首先引脚的信号进来,都可以通过一个数据缓冲器或者是施密特触发器,进行输入,因为输入对电路没有任何影响,所以任何设备在任何时刻都是可以输入的,但是在输出的这部分,采用的是开漏输出的配置,图为推挽输出

开漏输出就是去掉这个强上拉的开关管,输出低电平时,下管导通,是强下拉,输出高电平时,下管断开,但是没有上管了,此时引脚处于浮空的状态,这就是开漏输出

和这里图示是一样的,输出低电平,这个开关管导通,引脚直接接地,是强下拉,输出高电平,这个开关管断开,引脚什么都不接,处于浮空状态,这样的话,所有的设备都只能输出低电平而不能输出高电平,为了避免高电平造成的引脚浮空,这时就需要在总线外面,SCL和SDA各外置一个上拉电阻,这是通过一个电阻拉到高电平的,所以这是一个弱上拉

用我们之前将的弹簧和杆子的模型来解释就是,SCL或SDA就是一根杆子,为了防止有人向上推杆子,有人向下拉杆子,造成冲突,我们就规定,所有的人,不准向上推杆子,只能选择往下拉或者放手,然后,我们再外置一根弹簧向上拉,你要输出低电平,就往下拽,这根弹簧肯定拽不赢你,所以弹簧被拉伸,杆子处于低电平状态,你要输出高电平,就放手,杆子在弹簧的拉力下,回弹到高电平,这就是一个弱上拉的高电平,但是完全不影响数据传输,这样做有什么好处?

  • 第一,完全杜绝了电源短路现象,保证电路的安全,你看所有人无论怎么拉杆子或者放手,杆子都不会处于一个被同时强拉和强推的状态,即使有多个人同时往下拉杆子,也没问题
  • 第二,避免了引脚模式的频繁切换,开漏加弱上拉的模式,同时兼具了输入和输出的功能,你要是想输出,就去拉杆子或放手,操作杆子变化就行了,你要是想输入,就直接放手,然后观察杆子高低就行了,因为开漏模式下,输出高电平就相当于断开引脚,所以在输入之前,可以直接输出高电平,不需要再切换成输入模式了
  • 第三,就是这个模式会有一个“线与”的现象,就是只要有任意一个或多个设备输出了低电平,总线就处于低电平,只有所有设备都输出高电平,总线才处于高电平,12C可以利用这个电路特性,执行多主机模式下的时钟同步和总线仲裁,所以这里SCL虽然在一主多从模式下可以用推挽输出,但是它仍然采用了开漏加上拉输出的模式,因为在多主机模式下会利用到这个特征

3.I2C时序基本单元

起始和终止,都是由主机产生的,从机不允许产生起始和终止,所以在总线空闲状态时,从机必须始终双手放开,不允许主动跳出来去碰总线,如果允许的话,那就是多主机模型了

高电平期间,SDA不允许变化,SCL处于高电平之后,从机需要尽快地读取SDA,一般都是在上升沿这个时刻,从机就已经读取完成了,因为时钟是主机控制的,从机并不知道什么时候就会产生下降沿了,你从机要是磨磨唧唧的,主机可不会等你的,所以从机在上升沿时,就会立刻把数据读走,那主机在放手SCL一段时间后,就可以继续拉低SCL,传输下一位了,主机也需要在SCL下降沿之后尽快把数据放在SDA上,但是主机有时钟的主导权,所以主机并不需要那么着急,只需要在低电平的侄意时刻把数据放在SDA上就行了

另外注意,这里是高位先行,所以第一位是一个字节的最高位B7,然后依次是次高位B6,这个和串口不一样,另外,由于这里有时钟线进行同步,所以如果主机一个字节发送一半,突然进中断了,不操作SCL和SDA了,那时序就会在中断的位置不断拉长,SCL和SDA电平都暂停变化,传输也完全暂停,等中断结束后,主机回来继续操作,传输仍然不会出问题,这就是同步时序的好处

最后就是,由于这整个时序是主机发送一个字节,所以在这个单元里,SCL和SDA全程都由主机掌控,从机只能被动读取,这就是发送一个字节的时序

刚才我们说了,释放SDA其实就相当于切换成输入模式,或者这样来理解,所有设备包括主机都始终处于输入模式,当主机需要发送的时候,就可以主动去拉低SDA,而主机在被动接收的时候,就必须先释放SDA,不要去动它,以免影响别人发送,因为总线是线与的特征,任何一个设备拉低了,总线就是低电平,如果你接收的时候,还拽着SDA不放手,那别人无论发什么数据,总线都始终是低电平,你自己给它拽着不放,还让别人怎么发送呢,是吧,所以主机在接收之前,需要释放SDA

当我们在调用发送一个字节之后,就要紧跟着调用接收应答的时序,用来判断从机有没有收到刚才给它的数据,如果从机收到了,那在应答位这里,主机释放SDA的时候,从机就应该立刻把SDA拉下来,然后在SCL高电平期间,主机读取应答位,如果应答位为0,就说明从机确实收到了,这个场景就是,主机刚发送一个字节,然后说,有没有人收到啊,我现在把SDA放手了哈,如果有人收到的话,你就把SDA拽下来,然后主机高电平读取数据,发现,唉,确实有人给它拽下来了,那就说明有人收到了,如果主机发现,我松手了,结果这个SDA就跟着回弹到高电平了,那就说明没有人回应我,或者它收到了但是没给我回应,这就是发送一个字节,接收应答的流程

同理,在接收一个字节之后,我们也要给从机发送一个应答位,发送应答位的目的是告诉从机,你是不是还要继续发,如果从机发送一个数据后,得到了主机的应答,那从机就还会继续发送,如果从机没得到主机的应答,那从机就会认为,啊,我发送了一个数据,但是主机不理我,可能主机不想要了吧,这时从机就会乖乖地释放SDA,交出SDA的控制权,防止干扰主机之后的操作,这是应答位的执行流程

4.I2C时序

4.1指定地址写

起始条件开始后,主机必须首先调用发送一个字节,来进行从机的寻址和指定读写标志位,如图示的波形,表示本次寻址的目标是1101000的设备,同时,最后一位读写标志为0,表示主机接下来想要发送数据,接着从机发送应答,

在这个时刻,主机要释放SDA,所以如果单看主机的波形,应该是这样,释放SDA之后,引脚电平回弹到高电平,

但是根据协议规定,从机要在这个位拉低SDA,所以单看从机的波形,应该是这样,该应答的时候,从机立刻拽佳SDA,然后应答结束之后,从机再放开SDA

那现在综合两者的波形,结合线与的特性,在主机释放SDA之后,由于SDA也被从机拽住了,所以主机松手后,SDA并没有回弹高电平,这个过程,就代表从机产生了应答,最终高电平期间,主机读取SDA,发现是0,就说明,我进行寻址,有人给我应答了,传输没问题,如果主机读取SDA,发现是1就说明,我进行寻址,应答位期间,我松手了,但是没人拽住官,没人给我应答,那就直接产生停止条件吧,并提示一些信息

然后这个上升沿,就是应答位结束后,从机释放SDA产生的,从机交出了SDA的控制权,因为从机要在低电平尽快变换数据,所以这个上升沿和SCL的下降沿,几乎是同时发生的

由于之前我们读写位给了0,
所以应答结束后,我们要继续发送一个字节,同样的时序再来一把,第二个字节,就可以送到指定设备的内部了,从机设备可以自己定义第二个字节和后续字节的用途,一般第二个字节可以是寄存器地址或者是指令控制字等,比如MPU6050定义的第二个字节就是寄存器地址,比如AD转换器,第二个字节可能就是指令控制字,比如存储器,第二个字节可能就是存储器地址

那图示这里,主机发送这样一个波形,我们--判定,数据为0001 1001,即,主机向从机发送了0x19这个数据,在MPU6050里,就表示我要操作你0x19地址下的寄存器了,接着同样,是从机应答,主机释放SDA,从机拽住SDA,SDA表现为低电平,主机收到应答位为0,表示收到了从机的应答,然后继续,同样的流程再来遍,主机再发送一个字节,这个字节就是主机想要写入到0x19地址下寄存器的内容了,就表示,我要在0x19地址下,写入0xAA,

最后是接收应答位,如果主机不需要继续传输了,就可以产生停止条件(Stop,P),在停止条件之前,先拉低SDA,为后续SDA的上升沿作准备,然后释放SCL,再释放SDA,这样就产生了SCL高电平期间,SDA的上升沿,这样一个完整的数据帧就拼接完成了

这个数据帧的目的就是,对于指定从机地址为1101000的设备,在其内部0x19地址的寄存器中,写入0XAA这个数据,这就是指定地址写的时序

4.2当前地址读

起始条件开始后,主机必须首先调用发送一个字节,来进行从机的寻址和指定读写标志位,

如图示的波形,表示本次寻址的目标是1101000的设备,同时,最后一位读写标志为1,表示主机接下来想要读取数据,紧跟着,发送一个字节之后,接收一下从机应答位,从机应答0,代表从机收到了第一个字节,在从机应答之后,

从这里开始,数据的传输方向就要反过来了,因为刚才主机发出了读的指令,所以这之后,主机就不能继续发送了,要把SDA的控制权交给从机,主机调用接收一个字节的时序,进行接收操作,然后在这一块,从机就得到了主机的允许可以在SCL低电平期间写入SDA,然后主机在SCL高电平期间读取SDA,那最终,主机在SCL高电平期间依次读取8位,就接收到了从机发送的一个字节数据,0000 1111,也就是0x0F

那现在问题就来了,这个0xOF是从机哪个寄存器的数据呢,我们看到,在读的时序中12C协议的规定是,主机进行寻址时,一旦读写标志位给1了,下一个字节就要立马转为读的时序,所以主机还来不及指定,我想要读哪个寄存器,就得开始接收了,所以这里就没有指定地址这个环节,那主机并没有指定寄存器的地址,从机到底该发哪个寄存器的数据呢,这就需要用到我们上面说的当前地址指针了

在从机中,所有的寄存器被分配到了一个线性区域中,并且,会有一个单独的指针变量,指示这其中一个寄存器,这个指针上电默认,一般指向0地址,并且,每写入一个字节和读出一个字节后,这个指针就会自动自增一次,移动到下一个位置,那么在调用当前地址读的时序时,主机没有指定要读哪个地址,从机就会返回当前指针指向的寄存器的值,那假设,我刚刚调用了这个指定地址写的时序,在0x19的位置写入了0xAA,那么指针就会+1,移动到0x1A的位置,我再调用这个当前地址读的时序,返回的就是0x1A地址下的值,如果再调用一次呢,返回的就是0x1B地址下的值,这就是当前地址读时序的操作逻辑,由于当前地址读并不能指定读的地址,所以这个时序用的不是很多

4.3指定地址读

下面的时序在这里分隔一下,前面的部分是指定地址写,但是只指定了地址,还没来得及写,后面的部分是当前地址读,因为我们刚指定了地址,所以再调用当前地址读,两者加在一起,就是指定地址读了

首先,最开始,仍然是启动条件,然后发送一个字节,进行寻址,这里指定从机地址是1101000,读写标志位是0,代表我要进行写的操作,经过从机应答之后,再发送一个字节,第二个字节,用来指定地址,这个数据就写入到了从机的地址指针里了,也就是说,从机接收到这个数据之后,它的寄存器指针就指向了0x19这个位置,之后,我们要写入的数据,不给它发,而是直接再来个起始条件,

这个Sr(Start Repeat)的意思就是重复起始条件,相当于另起一个时序,因为指定读写标志位只能是跟着起始条件的第一个字节,所以如果想切换读写方向,只能再来个起始条件,然后起始条件后,重新寻址并且指定读写标志位,此时读写标志位是1,代表我要开始读了,接着主机接收一个字节,这个字节是不是就是0x19地址下的数据,这就是指定地址读

另外在这里,你也可以再加一个停止条件,这样也行,这样的话,就是两个完整的时序了,先起始,写入地址,停止,因为写入的地址会存在地址指针里面,所以这个地址并不会因为时序的停止而消失,我们就可以再起始,读当前位置,停止,这样两条时序也可以完成任务

但是12C协议官方规定的复合格式是一整个数据帧,就是先起始、再重复起始、再停止,相当于把两条时序拼接成一条了

4.4高级一点

如果你只想写一个字节,那就停止,就行了,如果你想写多个字节,就可以把这最后一部分,多重复几次,写入一次后,地址指针会自动+1,变成0x1A,所以这第二个数据就写入到了0x1A的位置

这样这个时序就进阶为,在指定的位置开始,按顺序连续写入多个字节

然后同理,当前位置读和指定位置读,也可以多次执行这最后一部分时序,由于地址指针在读后也会自增,所以这样就可以连续读出一片区域的寄存器

如果你只想读一个字节就停止的话,在读完一个字节之后,一定要给从机发个非应答(Send Ack, SA),非应答,就是该主机应答的时候,主机不把SDA拉低,从机读到SDA为1,就代表主机没有应答,从机收到非应答之后,就知道主机不想要继续了,从机就会释放总线,把SDA控制权交还给主机,如果主机读完仍然给从机应答了,从机就会认为主机还想要数据,就会继续发送下一个数据,而这时,主机如果想产生停止条件,SDA可能就会因为被从机拽住了,而不能正常弹回高电平

如果主机想连续读取多个字节,就需要在最后一个字节给非应答,而之前的所有字节都要给应答,简单来说就是主机给应答了,从机就会继续发,主机给非应答了,从机就不会再发了,交出SDA的控制权,从机控制SDA发送一个字节的权利,开始于读写标志位为1,结束于主机给应答为1,这就是主机给从机发送应答位的作用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2140839.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IAPP发布《2024年人工智能治理实践报告》

文章目录 前言一、黑箱问题►透明度、可理解性与可解释性二、法律和政策中的注意事项►欧盟的《通用数据保护条例》►欧盟的AI法案►NIST的AI风险管理框架►美国的第14110号行政命令►《生成式人工智能服务管理暂行办法》►新加坡的AI验证三、实施人工智能治理►模型卡与系统卡…

2023高教社杯全国大学生数学建模竞赛C题 Python代码演示

目录 问题一1.1 蔬菜类商品不同品类或不同单品之间可能存在一定的关联关系,请分析蔬菜各品类及单品销售量的分布规律及相互关系。数据预处理数据合并提取年、月、日信息对蔬菜的各品类按月求销量均值 季节性时间序列分解STL分解加法分解乘法分解 ARIMALSTM import p…

热成像目标检测数据集

热成像目标检测数据集 V2 版本 项目背景 热成像技术因其在安防监控、夜间巡逻、消防救援等领域的独特优势而受到重视。本数据集旨在提供高质量的热成像图像及其对应的可见光图像,支持热成像目标检测的研究与应用。 数据集概述 名称:热成像目标检测数据…

多目标优化算法求解LSMOP(Large-Scale Multi-Objective Optimization Problem)测试集,MATLAB代码

LSMOP(Large-Scale Multi-Objective Optimization Problem)测试集是用于评估大规模多目标优化算法性能的一组标准测试问题。这些测试问题通常具有大量的决策变量和目标函数,旨在模拟现实世界中的复杂优化问题。 LSMOP测试集包含多个子问题&am…

深度学习之微积分预备知识点

极限(Limit) 定义:表示某一点处函数趋近于某一特定值的过程,一般记为 极限是一种变化状态的描述,核心思想是无限靠近而永远不能到达 公式: 表示 x 趋向 a 时 f(x) 的极限。 知识点口诀解释极限的存在左…

2024 VMpro 虚拟机中如何给Ubuntu Linux操作系统配置联网

现在这是一个联网的状态 可以在商店里面下载东西 也能ping成功 打开虚拟网络编辑器 放管理员权限 进行设置的更改 选择DNS设置 按提示修改即可 注意的是首选的DNS服务器必须是114.114.114.114 原因 这边刚刚去查了一下 114.114.114.114 是国内的IP地址 8.8.8.8 是国外的I…

【人工智能】OpenAI最新发布的o1-preview模型,和GPT-4o到底哪个更强?最新分析结果就在这里!

在人工智能的快速发展中,OpenAI的每一次新模型发布都引发了广泛的关注与讨论。2023年9月13日,OpenAI正式推出了名为o1的新模型,这一模型不仅是其系列“推理”模型中的首个代表,更是朝着类人人工智能迈进的重要一步。本文将综合分析…

PFC和LLC的本质和为什么要用PFC和LLC电路原因

我们可以用电感和电容的特性,以及电压和电流之间的不同步原理来解释PFC(功率因数校正)和LLC(谐振变换器)。 电感和电容的基本概念 电感(Inductor): 电感是一种储存电能的组件。它的…

PhotoZoom Pro / Classic 9.0.2激活版安装激活图文教程

图像格式中,位图格式的图像是由点阵像素组成的数据文件,所以呢在把位图图像放大的时候,就会发现看到它是由于许多点构成,这就是为什么数码照片在使用普通的工具放大时会失真的原因。不过呢由于一些日常需求,我们经常需…

图神经网络模型扩展5--3

以图卷积网络为例,在每一层卷积中,我们需要用到两个输入A∈Rnn 和X∈Rnd。 很容易想象,当输入的图数据很大时(n 很大),图卷积网络的计算量是很大的,所需要的内存也是很大的。推广到更一般的信息传递网络,在每一层中&am…

Python 课程12-Python 自动化应用

前言 Python 自动化应用 可以帮助开发者节省时间和精力,将重复性、手动操作变为自动化脚本。例如,Python 可以用于自动化处理文件、邮件、生成报表,甚至可以控制浏览器执行复杂的网页操作任务。借助 Python 的强大库和工具,可以轻…

Kubernetes 常用指令2

kubernetes 常用命 令 1. 编写 yaml 文件 2. kubectl create 通过配置文件名或标准输入创建一个集群资源对象,支 持 json 和 yaml 格式的文件 语法: kubectl create -f 文件名 kubectl create deployment 资源名 --image镜像名 kubectl create deplo…

视频格式转为mp4(使用ffmpeg)

1、首先安装ffmpeg,下载链接如下 https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-6.1.1-full_build.7z 安装后确保ffmpeg程序加到PATH路径里,cmd执行ffmpeg -version出现下图内容表示安装成功。 2、粘贴下面的脚本到文本文件中,文件后缀…

【Linux进程控制】进程创建|终止

目录 一、进程创建 fork函数 写时拷贝 二、进程终止 想明白:终止是在做什么? 进程退出场景 常见信号码及其含义 进程退出的常见方法 正常终止与异常终止 exit与_exit的区别 一、进程创建 fork函数 在Linux中fork函数是非常重要的函数&#x…

魔方财务升级指南

本文将详细介绍如何升级魔方财务系统,确保您能够顺利地更新到最新版本。 重要提示 在进行任何系统升级之前,请务必备份数据。这是良好的习惯,也是我们的建议。 备份数据库,并下载到本地。最好将网站目录文件打包,并…

【最新华为OD机试E卷-支持在线评测】最长连续子序列(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

沉浸式利用自然语言无代码开发工具生成式AI产品应用(上)

背景 小伙伴们过去在开发应用时,经常需要编写大量代码文件以实现业务逻辑,想必肯定有小伙伴开发过类似于快消行业索赔处理、订单库存跟踪和项目审批等系统。去解决这些业务实际问题,我们需要定制地开发业务应用程序为这些问题提供解决方案。…

S100A9:鸡支原体感染中的免疫调控“双面间谍”【AbMole】

在生物学研究的广阔天地里,总有一些分子扮演着令人意想不到的角色。今天,我们要探索的主角是S100A9蛋白,一种在鸡支原体感染过程中展现出惊人双重功能的分子。这项来自华中农业大学动物科技学院与兽医学院的最新研究成果,揭示了S1…

(一)springboot2.6.13+mybatis-plus3.5.3.1+shardingsphere4.0.0-RC2

1,POM配置 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0…

【Mac】系统环境配置

常用工具 Navicat PJ版本&#xff1a;this Host切换器 SwitchHosts termius 一款好用的Linux服务器连接工具&#xff1a; termius 小飞机 dddd&#xff1a;&#x1fa9c; Git mac安装git有好多种方式&#xff0c;自带的xcode或者通过Homebrew来安装&#xff0c;本文的…