[米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-17 I2C通信协议原理

软件版本:Anlogic -TD5.9.1-DR1_ES1.1

操作系统:WIN10 64bit

硬件平台:适用安路(Anlogic)FPGA

实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板

板卡获取平台:https://milianke.tmall.com/

登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

目录

1概述

1.1 I2C简介

1.2 I2C总线协议

1.3 典型I2C数据帧格式


1概述

我们知道I2C总线具备广泛的用途,比如寄存器的配置,EEPROM的使用,更重要的是I2C总线上可以挂载非常多的外设。 对于一些低速器件的访问非常节省IO资源,由于是标准的总线接口,使用起来非常方便。I2C总线是OC开路,支持双向传输,所以总线上需要上拉电阻,如下图。

1.1 I2C简介

IIC(I2C)(Inter-Integrated Circuit,集成电路总线,是IICBus的简称),由NXP(原PHILIPS)公司在1980年代开发的两线式串行通信总线,多用于主机和从机在数据量不大且传输距离短的场合。

IIC一般只有两根总线:

·SDA(Serial data line)是双向的串行数据线,既可用于发送数据,也可接收数据(单向传输,半双工)

·SCL(Serial clock line)是双向的串行时钟线,控制数据发送的时序,主设备产生时钟,从设备接收时钟

IIC 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。IIC总线上可以挂很多设备:多个主设备,多个从设备。IIC支持多主控,其中任何一个能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率,但是在任何时间点上只能有一个主控。所有接到I2C总线上的从设备的串行数据SDA分别接到IIC总线的SDA上,从设备的时钟线SCL分别接到IIC总线的SCL上。IIC总线上的每个从设备都有自己一个唯一的地址,来确保不同设备之间访问的准确性。

IIC的高阻态:

由于IIC的所有从设备是接在一根总线上的,那么我们进行通信的时候往往只是几个从设备进行通信,那么这时候其余的空闲从设备可能会受到总线干扰。为了避免总线信号的混乱,要求各设备连接到总线的输出端时必须是漏极开路(Open Drain,简称OD)输出或集电极开路(OC)输出,所以SDA和SCL总线都需要上拉电阻。此时空闲设备被拉到了高阻态,即漏极开路,可以理解为断路, 整个IIC总线只有开启了的设备才会正常进行通信,而不会干扰到其他设备。

IIC器件地址:

IIC总线上的每一个设备都有一个器件地址(slave address)。I2C通用器件的器件地址=种类型号(D[7:4])+及寻址码D[3:1]+ R/W读写位D[0]。

种类型号D[7:4]:由半导公司生产时就已设定好了,这4位地址固定且用户不可更改(合法范围为0001至1110)

寻址码D[3:1]:用户自定义地址码,同一IIC总线上最多挂8片同种类芯片

读写位D[0]:表示总线上数据的传输方向,0为主设备写数据到从设备,1为主设备读从设备的数据

传输速率:

双向总线在标准模式下可以达到100kb/s,快速模式下可以达到400kb/s,高速模式下可达 3.4Mbit/s。

1.2 I2C总线协议

由于节课讲解的I2C是基于ZYNQ的I2C控制器,实际上可以不需要非常清楚I2C的详细时序,但是作为初学者,如果第一次学习I2C总线的,还是有必要学习下。

I2C协议把传输的消息分为两种类型的帧:

一个地址帧 :用于master指明消息发往哪个slave;

一个或多个数据帧: 由master发往slave的数据(或由slave发往master),每一帧是8-bit的数据。

注:协议要求每次放到SDA上的字节长度必须为8位,并且每个字节后须跟一个ACK位,在下面会讲到。

数据在SCL处于低电平时放到SDA上,并在SCL变为高电平后进行采样。读写数据和SCL上升沿之间的时间间隔是由总线上的设备自己定义的,不同芯片可能有差异。

I2C数据传输的时序图如下:

1、开始条件(start condition):

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

2、地址帧(address frame): 

地址帧总是在一次通信的最开始出现。一个7-bit的地址是从最高位(MSB)开始发送的,这个地址后面会紧跟1-bit的操作符,1表示读操作,0表示写操作。

3、应答AC K/NACK

接下来的一个bit是NACK/ACK,当这个帧中前面8bits发送完后,接收端的设备获得SDA控制权,此时接收设备应该在第9个时钟脉冲之前回复一个ACK(将SDA拉低)以表示接收正常,如果接收设备没有将SDA拉低,则说明接收设备可能没有收到数据(如寻址的设备不存在或设备忙)或无法解析收到的消息,如果是这样,则由master来决定如何处理(stop或repeated start condition)。

4、数据帧(data frames): 

在地址帧发送之后,就可以开始传输数据了。Master继续产生时钟脉冲,而数据则由master(写操作)或slave(读操作)放到SDA上。每个数据帧8bits,数据帧的数量可以是任意的,直到产生停止条件。每一帧数据传输(即每8-bit)之后,接收方就需要回复一个ACK或NACK(写数据时由slave发送ACK,读数据时由master发送ACK。当master知道自己读完最后一个byte数据时,可发送NACK然后接stop condition)。

5、停止条件(stop condition):

当所有数据都发送完成时,master将产生一个停止条件。停止条件定义为:在SDA置于低电平时,将SCL拉高并保持高电平,然后将SDA拉高。

注意,在正常传输数据过程中,当SCL处于高电平时,SDA上的值不应该变化,防止意外产生一个停止条件。

6、重复开始条件(repeated start condition):

有时master需要在一次通信中进行多次消息交换(例如与不同的slave传输消息,或切换读写操作),并且期间不希望被其他master干扰,这时可以使用“重复开始条件” —— 在一次通信中,master可以产生多次start condition,来完成多次消息交换,最后再产生一个stop condition结束整个通信过程。由于期间没有stop condition,因此master一直占用总线,其他master无法切入。

为了产生一个重复的开始条件,SDA在SCL低电平时拉高,然后SCL拉高。接着master就可以产生一个开始条件继续新的消息传输(按照正常的7-bit/10-bit地址传输时序)。重复开始条件的传输时序如下图所示:

7、时钟拉伸(clock stretching)(了解即可): 

有时候,低速slave可能由于上一个请求还没处理完,尚无法继续接收master的后续请求,即master的数据传输速率超过了slave的处理能力。这种情况下,slave可以进行时钟拉伸来要求master暂停传输数据 —— 通常时钟都是由master提供的,slave只是在SDA上放数据或读数据。而时钟拉伸则是slave在master释放SCL后,将SCL主动拉低并保持,此时要求master停止在SCL上产生脉冲以及在SDA上发送数据,直到slave释放SCL(SCL为高电平)。之后,master便可以继续正常的数据传输了。可见时钟拉伸实际上是利用了时钟同步的机制(见下文),只是时钟由slave产生。

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

所以更完整的I2C数据传输时序图为:

8、10-bit地址空间(了解即可):

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

在10-bit地址的I2C系统中,需要两个帧来传输slave的地址。第一个帧的前5个bit固定为b11110,后接slave地址的高2位,第8位仍然是R/W位,接着是一个ACK位,由于系统中可能有多个10-bit slave设备地址的高2bit相同,因此这个ACK可能由多有slave设备设置。第二个帧紧接着第一帧发送,包含slave地址的低8位(7:0),接着该地址的slave回复一个ACK(或NACK)。

注意,10-bit地址的设备和7-bit地址的设备在一个系统中是可以并存的,因为7-bit地址的高5位不可能是b11110。实际上对于7-bit的从设备地址,合法范围为b0001XXX-b1110XXX,’X’表示任意值,因此该类型地址最多有112个(其他为保留地址[1])。

两个地址帧传输完成后,就开始数据帧的传输了,这和7-bit地址中的数据帧传输过程相同。

9、时钟同步和仲裁(了解即可):

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

10、时钟同步(了解即可):

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

11、总线仲裁(了解即可):

 总线仲裁和时钟同步类似,当所有master在SDA上都写1时,SDA的数据才是1,只要有一个master写0,那此时SDA上的数据就是0。一个master每发送一个bit数据,在SCL处于高电平时,就检查看SDA的电平是否和发送的数据一致,如果不一致,这个master便知道自己输掉仲裁,然后停止向SDA写数据。也就是说,如果master一直检查到总线上数据和自己发送的数据一致,则继续传输,这样在仲裁过程中就保证了赢得仲裁的master不会丢失数据。

输掉仲裁的master在检测到自己输了之后也不再产生时钟脉冲,并且要在总线空闲时才能重新传输。

仲裁的过程可能要经过多个bit的发送和检查,实际上两个master如果发送的时序和数据完全一样,则两个master都能正常完成整个的数据传输。

1.3 典型I2C数据帧格式

S:起始信号

P:终止信号

A/\bar{A}:应答/非应答信号

阴影部分:数据由主机向从机传送

无阴影部分:数据由从机向主机传送

主机向从机连续发送数据:

连续写(也称页写,需要注意的是IIC连续写时序仅部分器件支持)是主机连续写多个字节数据到从机,这个和单字节写操作类似,每个字节都需要一个应答信号。

S

从机地址

0(写)

A

数据

A

数据

P

从机向主机连续发送数据:

连续读(也称页读取)是主机连续从从机读取多个字节数据,这个和单字节读操作类似,每个字节都需要一个应答信号。

S

从机地址

1(读)

A

数据

A

数据

P

主机向从机发送数据,再从机向主机发送数据:

不产生停止信号,改变主机从机数据的传输方向。

S

从机地址

0(写)

A

数据

S

从机地址

1(读)

A

数据

P

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

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

相关文章

【文心智能体】前几天百度热搜有一条非常有趣的话题《00后疯感工牌》,看看如何通过低代码工作流方式实现图片显示

00后疯感工牌体验:https://mbd.baidu.com/ma/s/6yA90qtM 目录 前言比赛推荐工作流创建工作流入口创建工作流界面工作流界面HTTP工具卡点地方 总结推荐文章 前言 前几天百度热搜有一条非常有有趣《00后疯感工牌》。 想着通过文心智能体去一键生成00后疯感工牌是不是…

2G内存的Linux云服务器到手却只有1.7G左右?找回消失的内存

使用命令 dmesg | grep -i memory 查看内核预留内存: [rootiZuf6hwfrhirwu85zqpl5kZ ~]# dmesg | grep -i memory [ 0.000000] Base memory trampoline at [ffff940980099000] 99000 size 24576 [ 0.000000] Reserving 161MB of memory at 688MB for crashkernel (…

MySQL 和 PostgreSQL,我到底选择哪个?

MySQL 和 PostgreSQL 是两个广泛使用的关系型数据库管理系统(RDBMS)。它们都具有强大的功能和广泛的社区支持,但在某些方面存在一些差异。本文将详细比较 MySQL 和 PostgreSQL,包括它们的特点、性能、扩展性、安全性以及适用场景等…

顺序表的应用——通讯录

通讯录的实现分为五个文件分别进行编写,分别为:SeqList.c,SeqList.h,Contact.c,Contact.h,test.c 其中前两个文件为上一篇博客中的顺序表的操作,后三个文件为通讯录功能的实现。 SeqList.h #d…

深度学习驱动智能超材料设计与应用

在深度学习与超材料融合的背景下,不仅提高了设计的效率和质量,还为实现定制化和精准化的治疗提供了可能,展现了在材料科学领域的巨大潜力。深度学习可以帮助实现超材料结构参数的优化、电磁响应的预测、拓扑结构的自动设计、相位的预测及结构…

自学鸿蒙HarmonyOS的ArkTS语言<十>@BuilderParam装饰器

作用:当子组件多处使用时,给某处的子组件添加特定功能 一、初始化 1、只能被Builder装饰的方法初始化 2、使用所属自定义组件的builder方法初始化 3、使用父组件的builder方法初始化 - 把父组件的builder传过去,参数名和子组件的builderPar…

SpringCloud教程 | 第十篇: 读取Nacos的配置

1、nacos服务器选用 2、test.yaml这一个DataId配置如下: config:name: aabb222 spring:application:name: testdatasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/hmblogs?useUni…

JuiceFS缓存特性

缓存 对于一个由对象存储和数据库组合驱动的文件系统,缓存是本地客户端与远端服务之间高效交互的重要纽带。读写的数据可以提前或者异步载入缓存,再由客户端在后台与远端服务交互执行异步上传或预取数据。相比直接与远端服务交互,采用缓存技…

HTML的简单应用 标记信件

前言: 暑假开始了,我也要正式开始学习web的相关知识了,先从三大件的html开始吧,目前只简单了解了html相关知识的基础,能写一些包含一些文字和图片的简单网页,其实会的东西还是不多,这边看书时发…

etcd的备份与恢复

一 为什么使用etcd 与ZooKeeper相比,etcd更简单,安装、部署和使用更加容易,并且etcd的某些功能是ZooKeeper所没有的。因此,在很多场景下,etcd 比ZooKeeper更受用户的青,具体表现在如下几个方面: 1 etcd更…

字节跳动十年经验老鸟,耗时大半年整理的软件测试面试真题【附答案】

软件测试工程师,和开发工程师相比起来,虽然前期可能不会太深,但是涉及的面还是比较广的。前期面试实习生或者一年左右的岗位,问的也主要是一些基础性的问题比较多。涉及的知识主要有MySQL数据库的使用、Linux操作系统的使用、软件…

操作系统详解之进程管理

一、进程 1.1 多道程序设计 允许多个程序同时进入内存并运行,提高CPU的利用率,目的是提高系统效率 a图内存中有四个程序,串行执行,因为这里只有一个程序计数器。 当有了多道程序技术之后就得到了b图,每个程序各自独立…

电脑显示mfc140u.dll丢失的修复方法,总结7种有效的方法

mfc140u.dll是什么?为什么电脑会出现mfc140u.dll丢失?那么mfc140u.dll丢失会给电脑带来什么影响?mfc140u.dll丢失怎么办?今天详细给大家一一探讨一下mfc140u.dll文件与mfc140u.dll丢失的多种不同解决方法分享! 一、mfc…

C++初学者指南-5.标准库(第一部分)--容器遍历

C初学者指南-5.标准库(第一部分)–容器遍历 文章目录 C初学者指南-5.标准库(第一部分)--容器遍历前向遍历基于范围的循环for_each / for_each_n迭代器的显式使用基于索引的循环 逆向遍历反向范围循环(C20)反向 for_each / for_each_n反向迭代器的显式使用基于索引的反向循环…

k8s核心操作_存储抽象_K8S中使用Secret功能来存储密码_使用免密拉取镜像_k8s核心实战总结---分布式云原生部署架构搭建033

注意在看的时候一定要把 dxxxx中的xxxx换成--o----c----k----e----r 然后我们再来看一个k8s中的secret的功能,这个功能 用来存储密码的,configMap是用来存配置的 比如我们有个pod,他的镜像,如果是需要密码的,那么 我们现在是从公共仓库拉取的,如果我们从私有仓库拉取,有密码…

18_Shell好用工具:sort

18_Shell好用工具:sort 选项说明-k指定要排序的列-nnumber,按照数值大小排序-rreverse,逆序-t分隔符-u去重-o保存排序到文件 一、数字升序 #sort1.txt文件纯数字 #升序 sort -n sort1.txt #降序 sort -nr sort1.txt二、数字升序去重 #数字…

Java SpringAOP简介

简介 官方介绍: SpringAOP的全称是(Aspect Oriented Programming)中文翻译过来是面向切面编程,AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生…

【前端7*】表格-表单2(弹窗在子组件)父子组件调用 vue element-ui

vue element-ui 中表单弹框的使用 写在最前面一、子组件 HelloWorld.vue1. 弹窗部分、将 visible 传值给父组件2.表单的 ruleForm 校验方法3.表单确认方法4. 提交确认方法:handleSummit5.表单渲染 二、父组件 HomeView.vue1.新增按钮、查看和编辑2.引用子组件弹窗3.…

强化学习——多臂老虎机问题(MAB)【附python代码】

文章目录 一、问题描述1.1 问题定义1.2 形式化描述1.3 累积懊悔1.4 估计期望奖励 二、解决方法2.1 ϵ-贪婪算法2.2 上置信界算法2.3 汤普森采样算法2.4 小结 一、问题描述 1.1 问题定义 有一个用于 K 根拉杆的老虎机,每一根拉杆都对应一个关于奖励的概率分布 R 。每…

Python项目实战之-爬取全网小说资源

python爬虫实战-小说爬取 基于requests模块与lxml模块编写的爬虫 基本思路 主要内容分为三个部分 使用requests模块获取网页内容使用lxml模块进行网页解析将解析出来的数据存储进MySQL数据库中 获取网页内容 网站分析 获取各个分类的href标签 代码如下 def novel_sort…