协议详解_I2C协议详解

I2C通信协议

bc934eac3dd721aac1ff2bebea6cd9c6.png

I2C通信协议的基础

简介

I2C「Inter-integrated Circuit」总线支持设备之间的短距离通信,用于处理器和一些外围设备之间的接口,它只需要两根信号线来完成信息交换。I2C最早是飞利浦在1982年开发设计。

a54737630052e4ccb753b9eb16b58712.png

I2C是同步传输信号,关于同步和异步这个经常在面试的时候会考到,同步和异步的核心的,我把消息发出去,我要关心你有没有收到,你收到了之后,我才会发下一条消息。异步就是,我发消息给你,我不管你收到消息没有,我都直接发下一条消息。所以SPI和I2C是同步通讯,UART是异步通讯。

I2C

I2C最少只需要两根线,和异步串口类似,**但是,I2C可以支持多个slave设备。**和SPI不同的是,I2C可以支持mul-master系统,允许有多个master并且每个master都可以与所有的slaves通信「master之间不可通过I2C通信,并且每个master只能轮流使用I2C总线」。master是指启动数据传输的设备并在总线上生成时钟信号以驱动该传输,而被寻址的设备都作为slaves。

63b5049e5f653cc4d457d3b3173ff54a.png

I2C的数据传输速率位于串口和SPI之间,大部分I2C设备支持100KHz和400KHz模式。使用I2C传输数据会有一些额外消耗,每发送8bits数据,就需要额外1bit的元数据「ACK或NACK」,这个也是I2C通讯的核心,应答信号。I2C支持双向数据交换,由于仅有一根数据线,故通信是半双工的。

硬件复杂度也位于串口和SPI之间,而软件实现可以相当简单。

I2C协议

I2C协议把传输的消息分为两种类型的帧:一个地址帧 「用于master指明消息发往哪个slave」 一个或多个数据帧 「 在SDA线上传输的数据帧,每一帧是8-bit的数据」。

f46c189f1c13eb5de8f1a1cfaa139f4c.png

I2C时序,帧和位

数据在SCL处于低电平时放到SDA上,在SCL变为高电平后进行采样,也就是说在时钟上升沿的时候,数据是有效的。

I2C数据传输的时序图如下:128d51c4ece35bf8347d1a9c30897ca2.png

启动信号-Start为了标识传输正式启动,master设备会将SCL置为高电平「当总线空闲时,SDA和SCL都处于高电平状态」,然后将SDA拉低,这样,所有slave设备就会知道传输即将开始。如果两个master设备在同一时刻都希望获得总线的所有权,那么谁先将SDA拉低,谁就赢得了总线的控制权。在整个通信期间,可以存在多个start来开启每一次新的通信序列「communication sequence」,而无需先放弃总线的控制权。

4e5d240a28294b6ab1e9b47242191f14.png
起始信号

地址帧-address frameI2C不像SPI有一个片选线,所以就需要指定I2C的地址,而且地址有7+1 形式,也有 9+1的形式,7+1指的是7位地址加一个读写位位标志bit。9+1 指的是9位地址加一个读写位标志bit。读写bit写1表示读操作,写0表示写操作。

应答信号-ACK当主设备发送完地址帧之后,会放弃SDA总线控制权,让从设备获得SDA控制权,此时从设备应该在第9个时钟脉冲之前回复一个ACK「将SDA拉低」以表示接收正常,如果接收设备没有将SDA拉低,则说明接收设备可能没有收到数据「如寻址的设备不存在或设备忙」或无法解析收到的消息,如果是这样,则由master来决定如何处理「stop或repeated start condition」。

b83c42f46ba1ac15985426c90190fa91.png
应答信号

数据帧-data frames在地址帧发送之后,就可以开始传输数据了。主设备负责产生时钟,并且在时钟上升沿之前准备好数据。每个数据帧8bits,数据帧的数量可以是任意的,直到产生停止条件。每一帧数据传输「8-bit」之后,接收方就需要回复一个ACK或NACK。

停止信号-Stop当所有数据都发送完成时,主设备需要产生一个停止信号,告诉从设备自己已经操作完成。停止停止信号在SDA置于低电平时,将SCL拉高并保持高电平,然后将SDA拉高。PS:在正常传输数据过程中,当SCL处于高电平时,SDA上的值不应该变化,防止意外产生一个停止信号。

fc6b19f9e0466aa20f486a1c901b0c28.png
停止信号

重复开始信号-repeated start condition主设备可以发起多个开始信号来完成数据的传输,只要不发停止信号,总线上的其他主设备就不能占据这条总线,有时候发送完一组数据后,希望重新发数据,所以就有了重复开始信号。重复的开始信号为,SDA在SCL低电平时拉高,然后SCL拉高

重复开始条件的传输时序如下图所示:bc49ec86dff084417d98eef49008a69c.png

时钟拉伸-clock stretching如果主设备发送的速度比从设备接收的速度快,因为是同步传输,可能就会出现问题,这时候,从设备可以通过控制时钟线,要求主设备线暂停传输,这就叫时钟拉伸。

通常时钟都是由master提供的,slave只是在SDA上放数据或读数据。而时钟拉伸则是slave在master释放SCL后,将SCL主动拉低并保持,此时要求master停止在SCL上产生脉冲以及在SDA上发送数据,直到slave释放SCL,让SCL变成高电平。之后,master便可以继续正常的数据传输了。可见时钟拉伸实际上是利用了时钟同步的机制,只是时钟由slave产生。

如果系统中存在这种低速slave并且slave实现了clock stretching,则master必须实现为能够处理这种情况,实际上大部分slave设备中不包含SCL驱动器的,因此无法拉伸时钟。

包含时钟拉伸的I2C数据传输时序图为:1d8d329560e12ae3a0e4906324ef3102.png

10-bit地址空间:上面讲到I2C支持10-bit的设备地址,此时的时序如下图所示:4a20ccc4eee0a3acf3c11f7141e8ec8a.png

在10-bit地址的I2C系统中,需要两帧来传输slave的地址。第一个帧的前5个bit固定为b11110,后接slave地址的高2位,第8位仍然是R/W位,接着是一个ACK位,然后再发送另外8bit的地址,发送完后从设备会给出应答。

d22ffb8f27a50dbe76a61a7dba23c5f8.png

I2C的上拉电阻

I2C总线要求总线不工作的时候保持在高电平状态,所以I2C总线默认需要上拉电阻,而且上拉电阻的大小也会直接影响时序,一般是1.5K,2.2K,和4.7K。我工作到现在目前用的最多的电阻就是4.7K的。

上拉分为内部上拉和外部上来,如果CPU有内部上拉了,就没有必要使用外部上拉了。

既然I2C就是通过高低电平来识别的,为什么还需要上拉电阻呢?直接搞一个VCC接上去不是更好吗?欢迎评论回答。

与串行端口、SPI对比

串行端口

串行端口是异步的「不传输时钟相关数据」,两个设备在使用串口通信时,必须先约定一个数据传输速率,并且这两个设备各自的时钟频率必须与这个速率保持相近,某一方的时钟频率相差很大都会导致数据传输混乱。

异步串行端口在每个数据帧中都要插入至少一个起始位和一个终止位,意味着每传输8bits的数据实际要花费10bits的传输时间,从而降低了数据传输速率。

另一个问题是异步串行端口的设计就是针对两个设备之间通信的,那么如果有多个设备连接到一个串口上,就必须解决信号碰撞的问题(bus contention),通常要通过额外硬件来完成。

最后就是数据传输速率,异步串行通信并没有一个理论上的速率限制,大部分UART设备只支持一些特定的波特率,最高通常在230400bps左右

SPI

SPI最明显的缺点就是引脚数量,使用SPI总线相连的一个master和一个slave需要四根线(MISO/MOSI/SCK/CS),每增加一个slave,就需要在master上增加一个CS引脚。当一个master接多个slaves的时候,疯狂增长的引脚连接是难以忍受的,并且对紧凑的PCB layout是一个挑战。

SPI总线上只允许有一个master,但可以有任意多个slaves(只受限于总线上设备的驱动程序的能力,以及设备上最多能有多少个CS引脚)。

SPI可以很好的用于高速率全双工的连接「这个是SPI的优点」,对一些设备可支持高达10MHz(10Mbps)的传输速率,因此SPI吞吐量大得多。SPI两端的设备通常是一个简单的移位寄存器,让软件的实现很简单。

SPI的具体文章可以查看下面链接
SPI协议详解

时钟同步和仲裁

如果两个master都想在同一条空闲总线上传输,此时必须能够使用某种机制来选择将总线控制权交给哪个master,这是通过时钟同步和仲裁来完成的,而被迫让出控制权的master则需要等待总线空闲后再继续传输。在单一master的系统上无需实现时钟同步和仲裁。

时钟同步

时钟同步是通过I2C接口和SCL之间的线“”(wired-AND)来完成的,如果有多个master同时产生时钟,那么只有所有master都发送高电平时,SCL上才表现为高电平,否则SCL都表现为低电平

总线仲裁

总线仲裁和时钟同步类似,当所有master在SDA上都写1时,SDA的数据才是1,只要有一个master写0,那此时SDA上的数据就是0。一个master每发送一个bit数据,在SCL处于高电平时,就检查看SDA的电平是否和发送的数据一致,如果不一致,这个master便知道自己输掉仲裁,然后停止向SDA写数据。

也就是说,如果master一直检查到总线上数据和自己发送的数据一致,则继续传输,这样在仲裁过程中就保证了赢得仲裁的master不会丢失数据。输掉仲裁的master在检测到自己输了之后也不再产生时钟脉冲,并且要在总线空闲时才能重新传输。仲裁的过程可能要经过多个bit的发送和检查。

所以,会存在一个情况,如果两个master如果发送的时序和数据完全一样,则两个master都能正常完成整个的数据传输。

I2C波形

设定I2C读的地址:01101101(0x6d) 10001000(0x88),注意观察第9个时钟为低电平,表示从设备应答

Slave Read Address:0x6d,ID register value:0x88

a79969801d63a7e07759ede247ab79e2.png
img

I2C源码

收集了两个I2C源码,一个是GPIO口模拟I2C,一个是androitd i2c tools

下载链接如下

链接:https://pan.baidu.com/s/1KQQuATd5Lul_IzKavzoncA 密码:8cd2

猜你喜欢

串口通讯就该这么学

串口打印知多少?

STM32F429的USB是个坑?

9237fa819792984e91ae98e5b70adb19.png

1ea46855921fdd70450e3e0a4d74c723.png

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

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

相关文章

http 302错误_http面试题

作者:忘れられたくない出自:SegmentFault 思否原文:segmentfault.com/a/1190000024538846http状态码分类1xx服务器收到请求2xx请求成功3xx重定向4xx客户端错误5xx服务端错误常见状态码200 成功301 永久重定向302 临时重定向304资源未被修改40…

controller属于哪一层_孺教网分享|家长层次有五层,家长们都来看看,你属于哪一层?...

经常听到这样一些话:养不教父之过,有其父必有其子。孩子是父母的影子,父母是孩子的第一任老师.......这些都反映了在孩子成长的过程中,家庭教育的重要性。而家庭教育往往体现在非智力因素方面,比如感恩、诚信、善良、尊…

cad里面f命令用不了_CAD出现命令无效、失灵等问题?不用慌,两招帮你快速解决...

一、CAD常见无效问题1、填充命令无效我们有时候需要对某一区域进行填充,但是却发现怎么也填充不出来,这个时候就应该检查一下【选项】设置了,具体操作步骤如下:①命令行中输入【OP】,按下回车键调出【选项】对话框&…

卫生纸玫瑰花折法5步_餐巾纸折纸玫瑰花的折法图解教程

餐巾纸折纸玫瑰花的折法图解教程折纸玫瑰花的制作方法非常的多,但是常见的折纸玫瑰花制作方法基本上都是以方形纸张进行折叠来制作而成的。这里介绍的这种折纸玫瑰的制作方法更加的简单、经济和环保一些。同时其有着一个极大的优点,那就是无论在哪里都可…

mysql status_mysql status查看

总结了几种查看MySQL运行状况的方法,如下:1、phpMyAdmin最简单的方式,在phpMyAdmin直接点击状态查看,详细如下图。这查看的是MySQL的一些运行状况数值,这种方式被大多数系统管理员所不齿,因为专业的MySQL服…

windows mysql 备份_Windows下MySQL数据库备份脚本(二) | 系统运维

说明:MySQL数据库安装目录:C:\Program Files\MySQL\MySQL Server 5.0MySQL数据库存放目录:C:\Program Files\MySQL\MySQL Server 5.0\dataMySQL数据库备份目录:D:\MySQLdata_Bak实现目的:备份MySQL数据库存放目录中的m…

mysql8解决区分大小写问题_球磨机“包球”和“饱磨”分不清?点进来快速区分,解决问题...

球磨机的“包球”和“饱磨”现象都是设备在磨矿过程中出现的常见故障,大多数用户对这两种情况不是特别了解,出现问题时也不知从何下手,导致机器无法正常作业。其实“包球”和“饱磨”有一定的相似之处,同时在产生原因、处理方法等…

控制浏览器增加新页签的js_技术网站重写复制按键 js 跳转到注册页,就能增加用户?...

背景技术网站重写复制按键的 js ,作为开发人员你会为了复制一段代码而注册一个用户吗?一个小需求变动,将跳转详情页改为 target_blank 的方式打开新页面。原来用 Vue.js 的路由代码 push 需要换成 resolve ,本文将介绍该需求调整过…

win7系统一直反复重启_iPhone7开机白苹果反复重启进不了系统维修过程

故障现象iPhone7开机时在出现苹果图标后反复重启,无法进入系统。维修过程拿到手机之后开机测试,在显示苹果图标界面反复重启。这种故障是开机过程不能通过自检造成的。由于客户要保留资料,所以是不能刷机。根据经验判断应该是基带部分有问题。…

mysql去掉小数点多余0_mysql数据库个性化需求:版本号排序

概述今天主要介绍一个MySQL数据库版本号排序问题,一起来看看吧~需求按版本号排序,版本号字段为字符类型,其中1.2.10应大于1.2.9,但mysql数据库会认为1.2.9大于1.2.1正确的版本号应该是 1.3.0 大于 1.2.231.2.10 大于 1.2.9实现sql…

mysql语句在哪编写_mysql常见问题七:编写sql语句

一、删除除了学号字段以外,其它字段都相同的冗余记录,只保留一条!(也就是要删除凤姐和田七中一条重复数据只留一条)要求结果数据:原始数据:CREATE TABLEtbl_students (idint NOT NULL,namevarchar(10) DEFAULT NULL,sa…

sum()转字符串_Python字符串与内置函数

字符串创建变量来保存字符串 字符串可以通过单、双、三引号创建字符串message "Hello,world"#变量mseeage,值为hello,worldprint(message)输出结果:Hello,worldPython3,有3种数值类型分别为:int(整形)#创建变量为a,值为496a 496 #type查看类…

obj文件编辑软件_工程动画制作 | MAX文件导出obj、fbx格式在Bentley软件中应用

一、利用3dmax打开max模型,利用材质球吸取材质。看材质是否为标准材质(standard),如若是,继续下一步操作。如若不是,修改材质球属性,保留贴图为子材质,更改为标准材质。二、处理模型面数、点数问题。利用修…

python 安装pandas 权限不够_详解Python学习之安装pandas

一、python pip的安装与使用1、pip 是 python 包管理工具,该工具提供了对python 包的查找、下载、安装、卸载的功能。目前如果你在 python.org 下载最新版本的安装包,则是已经自带了该工具。python 2.7.9 或 python 3.4 以上版本都自带 pip 工具。pip 官…

java的类是什么_java类是什么意思

java类就是具备某些共同特征的实体的集合,它是一种抽象的数据类型,它是对所具有相同特征实体的抽象。在面向对象的程序设计语言中,类是对一类“事物”的属性与行为的抽象。举一个例子说明下类,比如Person(人)就是一个类&#xff0…

java 耦合度_Java第三十八天,Spring框架系列,使用工厂模式降低程序耦合度

一、什么是耦合程序之间的依赖关系:①类之间的依赖②方法之间的依赖注意:不可能完全的消除依赖关系,而只能是降低程序之间的依赖关系二、解耦降低程序之间的依赖关系:1.解决类之间的依赖关系:①通过读取配置文件来获取…

Java 实现sha_Java实现SHA算法的方法详解

本文实例讲述了Java实现SHA算法的方法。分享给大家供大家参考,具体如下:一 简介安全散列算法固定长度摘要信息二 SHA算法SHA-1、SHA-2(SHA-224、SHA-256、SHA384、SHA-512)三 SHA算法实现package com.imooc.security.sha;import java.security.MessageDi…

linux mysql 脚本带参数_Linux下用SHELL脚本执行带输入输出参数的ORACLE存储过程并得到结果...

存储过程 myproc(in_num in number,out_num out number)sql脚本模板mysql.sql{var nret number;execute :nret : 0;--初始化call存储过程 myproc(in_num in number,out_num out number)sql脚本模板mysql.sql{var nret number;execute :nret : 0;--初始化call myproc(in_code,:n…

MySQL自动建立集合自动分片_1.mongodb初步使用总结

mongoDB2.6使用总结一、准备工作下载java驱动包驱动包下载地址:http://www.doczj.com/doc/3305bc20960590c69ec376c0.html/artifact/org.mongodb/mongo-java-driver mongoDB下载:http://www.doczj.com/doc/3305bc20960590c69ec376c0.html/在线api&#x…

springcloud 创建子父项目_idea搭建springCloud----搭建父子项目(二)

今天介绍一下 : idea 搭建父子项目父项目:springCloud_ht子项目:eureka_server(注册中心)1-1.新建父项目:1-2 起名称 springCloud_ht1-3 什么都不选,next1-4 :起项目名称:springCloud_ht1-5: 该目录为下图,但是项目为红…