当前课程知识点:ARM微控制器与嵌入式系统 > 第五章 ARM微控制器的各种外设 > 5.7.1 ARM微控制器外设:I2C通讯简介 > 5.7.1 ARM微控制器外设:I2C通讯简介
各位同学大家好
我是清华大学工程物理系的曾鸣老师
欢迎大家继续回到我们
ARM微控制器与嵌入式系统的MOOC课堂
那么在这个单元里呢
我们继续进行微控制器的外设学习
特别是关于通讯的这一类外设
我们前面有很多个单元都已经涉及到了
各种各样的通讯
大家一定记得我们在学的第二类外设
就是UART的异步串行通讯
那是一个共着地线之外
用两根数据线
你收我发 你发我收的一种
不共享时钟的异步串行通讯
那么在那个里头大家可能印象最深的
是关于UART那样一个数据帧的格式
那么在前两个单元呢
我们又学习了SPI这样一种同步的串行通讯
那么SPI同步串行通讯一个特点
就是除了主机和从机之间
彼此收发的数据线之外
还有一个大家的共用的一个时钟线
由主机发给从设备
因为有了共用的时钟
它是一个同步的串行通讯
那么与之一脉相承的呢
我们在今天还会再学习一类新的
同步串行通讯
那也就是I2C通讯
那么我们在这个单元的内容彻底学完以后
我会带着大家再来回顾
可能那个时候大家领会的会更深
我先给大家建立一种概念和印象
就是从异步的UART
到SPI 到我们现在学的I2C
其实单就通讯这个话题
我们也在逐步的深入
我们从一个简单的不共享时钟的数据帧
到彼此之间共享时钟信号
有主从 有总线的初步概念的SPI
再到有严格的电气定义
乃至通讯协议层Protocol定义的
这样一种总线 I Square C
那么我们在后面的学习会发现
I Square C 或者叫I2C
是一类非常典型的串行通讯
那么我们在这门课的范畴里
不会有时间再给大家去讲USB和以太网
但顺着这个脉络如果大家学好了I2C的通讯
会发现USB通讯还有未来要学习以太网通讯
都是沿着这条脉络的一个自然延伸
包括当中的握手 数据帧这样一些环节
都会帮助大家以后非常方便的去进行理解
那么讲了这么多
究竟什么是I2C通讯呢
首先看一看它的定义和名字
大家会注意到我把它称为I2C
那么写成中文的时候
或者写成书面的时候大家写的是I2C
那么大家记住把它念成I2C
或者英文的 I Square C
它是Inter-IC Bus的缩写
那么也就是IC的芯片当中
集成电路当中
互通互联总线的这样一种意思
所以从定义上来讲顾名思义
它是一种面向两线制的
串行的双向的同步通讯的接口
那么它有专用的logo
就是这张图看着很简单黑白两色
那么我们一般典型的
I Square C或者I2C的通讯连起来呢
就像这张电路图所示
除了大家共的地以外
从主机上拉出两根线
一根是时钟
一根是双向的数据线
那么上面大家看着我们都画了两个电阻
待会再讨论这件事
可以有一个或者多个设备
通过这个时钟线和数据线与主机相连
这就是I Square C I2C的通讯的基本的感觉
那么在详细的讲它的这些线的含义
和电气的定义之前
我们必须先知道它的渊源
那么这样一种总线 I2C的总线
其实诞生不是一天两天
它诞生于1982年
所以到今年已经有30多年的历史
那么从最早的速度不超过100K赫兹
不断的在各个版本的发布当中
维持了最基本的兼容性
而它所接受的速度 性能这些东西
都在不断的进行一些微调和改善
那么要讲一个有点八卦的历史渊源呢
就是我们在上几个单元学的
SPI的同步串行通讯
主要是由摩托罗拉公司提出的
而我们都知道摩托罗拉公司的半导体部
spin-out出来成为日后的飞思卡尔
而我们现在学习的I2C通讯呢
主要由飞利浦公司在1980年代提出
而它的半导体部日后spin-out出来
成为了恩智浦也就是NXP
那么在不久以前NXP又跟Freescale
进行了并购 合并成了一家公司
所以曾经激烈竞争的这两种
同步串行通讯标准
最后它们的母公司合为了一体
所以这个半导体企业
就是这样分分合合的进行发展
那么抛开这个历史的渊源
我们在深入学习之前先给大家一个概念
I2C通讯是一个怎样的通讯
首先它是串行的
它只有有限根线
所以我们的数据 我们的时钟
都是一个Clock 一个Clock进行跳变
然后它是同步的
从主机到一个或者多个从设备
它有一根时钟线是大家共享的
大家在一个时钟节拍下去看这些数据
然后无论在时钟和数据线上
这个信号是单端的
也就是用5伏或者3.3伏来代表逻辑一
然后这样一种通讯它是双向的
也就是说刚才提到我们有一根是时钟线
在时钟驱使下的另外一根数据线
既可以由主机向设备的方向传输数据
也可以交由设备驱动
由设备向主机发送数据
这个时候它是双向的通讯
那么大家注意这一点
它与我们之前学过的SPI有显著的区别
大家回忆一下
SPI它有两根数据线
一个是MOSI 一个是MISO
每根线其实方向是定死了的
由主到从 由从到主
在I2C的通讯里头
这一根数据线可能会承载双向的数据
也就是分别由主机或者设备来驱动
那么就意味着它一定会有一些协议
来协商什么时候该谁说话 对吧
这是大家可以想到的
另外也意味着它不是双工的
它不可能双方同时发数据
所以它是双向但非双工
此外呢
从我们刚才讲的这些理所当然的概念时候
已经大家感觉到了
它是一个有Master有Slave的一个主从协议关系
同时因为它是一个主对一个从
或者一个主对多个从
所以从它的名字已经定义了
从当年设计总线的时候
它就是一种BUS
总线概念的一种通讯协议
所以就跟SPI一个主设备接多个从设备一样
但是大家注意SPI
一个主设备接多个从设备的时候
它需要多个片选信号
来分别选中不同的设备
而大家从这张图上能看出来
I2C接多个从设备的时候
它始终除掉地线
只有时钟和数据这两根线
意味着它对从设备的选择
包括刚才讲到的对数据方向的控制
都是在通讯的本身里完成的
这就是我刚才隐隐约约提到的
它开始引入了完善的数据帧
或者叫Protocol数据协议的概念
在后面我们会一点一点的学习
那么有了基本的概念
我们必须要花一点点的时间
真正去理解I2C这样一种通讯的形式
和通讯的特点背后的电气特性
这是为什么这种总线能够以这种方式通讯
乃至后面我们要讲的通讯协议
为什么是这样的一个关键的基础知识
那么I2C最最重要的一个特点
就是它的主机和从设备
所使用的这两根信号引脚
也就是SDA
Serial data串行数据引脚和SCL串行时钟引脚
都不是我们之前所学过的普通IO
我们之前所学过的普通IO
我们从电子学的角度来讲
一般是推挽输出
也就是通过对电源对地的两个晶体管的开关
它可以输出一个逻辑一的高电平
无论是3.3伏还是5伏
或者输出一个逻辑0的低电平0伏 对吧
那么在我们的I2C的这样的引脚里头
它们更多的时候采用的是我们称为
开漏输出或者是开集电极输出
那么它们对应的英文
分别是对应场效应管里的
Open Drain的这个OD输出
或者是对于晶体管的Open Collector
也就是OC的输出
那么这几个术语大家可能很难理解
在这门课的范畴里
我们抛开晶体管的细节的知识
定性的通过这两张图来加以理解
我们输出的极在内部的电路里
产生了0或者1的这种逻辑关系以后
那么我们控制这样一个
最后输出的
场效应管或者晶体管大家记得
在最开始我给大家讲过
在数字电路范畴我们把它都理解为开关
所以当它要输出逻辑0低电平的时候
这个开关导通
使这个引脚对外表现出来是接了地
强制为低电平接地导通
而当它要输出逻辑1的时候
它的方式是控制这个晶体管截止
也就是这个引脚对内的这个回路
对地是高阻的
于是这个回路的阻抗变得很大
那么在这样一种模式下面这个引脚拉出来
如果外面有一个上拉电阻
就意味着当片内的这个引脚
这个开与漏或者是开集电极的引脚导通
输出逻辑0的时候
由于这个开关的闭合
使这个引脚上面看到的电压是0伏
而我们希望输出逻辑1伏的时候
我们看到的逻辑1
并不是由于这个引脚输出了一个高电平电压
而是因为这个引脚
使自己的内阻变成了一个高阻抗
也就是内部的开关是断开的
于是这个引脚通过上拉的电阻跟电源相连
使这个电阻上面的电流非常小的情况下
我们读到引脚的电位是个高电压
这个高电压是取自于外部的上拉电阻
我不知道这样讲大家明白了没有
那么翻到下一页
我来给大家举一个更形象的例子
也就是在我们看到的I2C通讯的总线里头
无论主机还是从设备
各自都伸出了两个引脚
分别挂在了SDA和SCL这样一根通讯线上
那么在这根线上所有的信号是可以线与的
大家想想为什么
什么叫线与或者叫逻辑与的关系
那么我们把能够线与这件事情
我们翻译一下
就是在这样一根信号线上
它通过两个上拉电阻进行上拉
如果主设备和从设备
所有接到同一根信号线上的引脚
此时都想输出逻辑1
也就是它们那个开漏
或者开集电极的片内的开关那个晶体管
都是截止
于是它们每一个接到这根线上的引脚
都是高阻的状态
那么换言之这根线上对地是高阻的
所以我们线上的电平
就通过上拉电阻维持在了高电平
而如果主机或者从设备当中
有任何一个设备希望输出逻辑0
那么它们就会使自己这个引脚片内的
那个晶体管导通
那么于是这根线上
就会通过其中这一个芯片的这一个引脚
对地导通
于是就使电压被拉下来变成0电平
那么这件事情用两句话来翻译
第一句话就是
有点像我们大家在坐电车或者在玩游戏
有一根线被一个电阻拉在了天上
然后很多人都轻轻的扶住这根线
那么大家都不使劲往下拽的时候
这根线就维持高电平
而如果主机和从设备当中
有任何一个对应的引脚
想把这根线上的电压
或者我们形象讲这根线给拉下来
它输出逻辑0一导通这根线上的电压
就被拉下来变成逻辑0
所以这就是I2C总线上
主设备与从设备连在一起的
这些引脚之间的一种逻辑关系
那么这样一种逻辑关系再翻译过来
就是刚才我说的线与这句话大家想一想
只有大家都希望它是1的时候
线上的电压才是逻辑1
任何一个设备不管是主还是从
希望把它往下拉成逻辑0的时候
这根线上的电压
就会因为它的晶体管导通拉下来变成逻辑0
所以大家都是1它才是1
任何一个希望它是0它就是逻辑0
这是不是与的关系呢
所以大家记住这么一个概念
就是形象上来讲I2C总线通讯的信号是很多人
很多芯片拽住一根线
大家都不拉它就是逻辑1
任何一个都可以把它拉下来变成逻辑0
从逻辑上来讲就是线与的关系
所以这是我们I2C通讯当中的
一个理解上的难点
因为这一类引脚
与我们之前学过的IO是不一样的
大家记住它是开漏或者开集电极输出
内部结构就是一个对地的导通开关
为零就是导通拉到地
不为零就是截止高阻
然后大家串在一起
那么理解了这样一件事
我们就会慢慢的理解后面I2C
很多通讯协议方面的事情
比如现在我们有一个最基本的概念
就是I2C的引脚线
其实内部的引脚无论主从
都只能控制它导通对地或者高阻
或者它一定要有一个上拉电阻
来提供它的基础电平
而当大家都不通讯
都是高阻的时候
这根信号线的平时的默认状态
一定是逻辑1的
那么最后要给大家说的一件事情
逻辑1有指定这个电压是多少吗
其实是没有的
所以取决于我们的主机
或者我们通讯的从设备
对什么样的电压兼容
我们可以选择这个上拉电阻
是接到5伏还是接到3.3伏
恰好这一件事情变得兼容性很好
很灵活
那么回过头来我们看看
I2C有了这样一些特点
后面我们会讲它的协议
它有什么优点呢
大家想一想会发现
它是我们学过通讯协议里头
能够一个设备接多个设备
这样一种总线里头
要的信号线好像是最少的
只要两根线对不对
那么一根数据线
一根时钟线
这个数据还是双向的
第二个呢
我们说它的协议简单
有同学会打个问号
说曾老师你不是说它比这个
UART和SPI都要麻烦吗
那是大家学习以后你们看一看麻烦
另外看看它跟USB跟以太网这些比
它其实还是简单的
另外就是它的协议相对是比较容易实现的
那么我们的微控制器
往往有这个I2C的通讯模块
如果没有
我们用的微控制器
我们用的FPGA其实很多时候
可以把普通的IO引脚配置成开漏
或者开集电极的输出
而不是工作在那种推挽的IO模式
那么我们可以通过对IO的编程
模拟出这样的通讯协议和总线
其实它是非常容易实现的
然后支持它的器件非常多
它虽然是飞利浦提出的
恩智浦这个继承的总线协议
那么实际上我们会跟选SPI的时候一样
我们会发现恩智浦、德州仪器 TI
ST、美信 Maxim很多很多厂商的
大量丰富的测量器件
ADC各种各样的外设都有I2C的接口
然后还有一个好处就是它是一种Bus
一种总线的协议
非常简单的仍然只是这两根线加上地
就是三根线就能在一个接口上
挂接多个设备
方便大家设计一个复杂的电路
扩充你的功能
然后刚才我们也讲过
它可以是5伏 可以是3.3伏
它的速率可以从100K到几兆BPS
然后如果我们愿意牺牲速度
它的通讯距离也可以从几米延长到十几米
所以应该说I2C在我们学过的通讯里
特别是在接多个通讯的时候
往往可能用的比UART
用的SPI还要多
特别是在比如曾老师的领域
这个高能物理实验里头
我们的慢控制大量的这个传感器
大量的这种芯片配置会使用I2C的方式
因为只需要一个接口
就能把一块板上多个设备串起来
全部引入控制
通过以后要讲到的地址来逐一进行读写
那么在这里
我们来建立对于I2C电气层的
最后一点点概念
就是它的这个电平和信号的基本规范
那么对于它的电平和信号的基本规范呢
大家跟SPI回忆一下
就会发现I2C要规范的多得多
我们在学习SPI的时候
说它最大的优点是灵活
最大的缺点也是灵活
因为SPI大家记得有两种相位
两种时钟极性
还有两种这个字节字位序
排列组合以后
拿到一个芯片能不能接到SPI的时候
我们要先看芯片手册
大家还记得那个液晶屏 对吧
然后看看时钟的范围 相位的极性
再来正确的配置
否则彼此都是SPI还通讯不上
I2C作为一个比较完善的
有Protocol 有协议的这样一种通讯协议
它在电气层已经做了比较严格的规范
严格的规范当中有这么几点
第一在I2C的通讯协议里规定了
I2C的时钟永远是电平有效的
大家理解这句话
我们在SPI里经常是在
上升沿和下降沿的时候
去采集 拾数据线的数据
或者让数据线的数据发生变化
那么I2C跟它不一样并且定义死了
它是以电平有效
也就是总是在时钟信号
为高电平或者低电平的这个时间段里
发生变化 发生作用
这是第一句话
第二呢 规定了I2C的标准通讯
总是数据线的数据
应该在时钟信号为低电平的时候发生切换
就是一个比特一个比特切换的时候
必须在时钟信号为低电平的时候发生切换
而应该在时钟信号
为高电平的那个时间段里保持不变
便于主机和从机来确认数据的值是多少
所以表现出图就是这张图
总在低电平切换总在高电平不变
那么小概率的情况下
可以在时钟信号为高电平的时候
发生数据线的变化
什么时候呢
大家回忆UART
跟这个异步串行通讯UART有点像
如果在时钟线为高电平的时候
数据线从默认状态
大家谁都没往下拉的高电平
发生了一次由高向低的跳变
那么意味着这是一个Start起始信号
我们称为起始位
那么意味着一笔通讯要发起了
那么如果在时钟线为高电平的时候
发生一次数据线
由低电平向高电平的跳变
那么意味着这是一个stop位
一个停止信号
表示一次完整的通讯结束了
所以如我们前面所说
数据总是得在
时钟信号为低电平的时候发生跳变
为高电平的时候保持不变
仅当开始和停止位的时候
在时钟信号为高电平的时候发生跳变
那么这样一种电气的定义
就把我们I2C通讯的这个
电平标准 时序关系全都定义死了
它比SPI要严格和规范的多
那么我们有这么多个设备
可以跟一个主机
接在了一个I2C的通讯总线里
我们从电气层讲清楚了它们的引脚
是开漏或者开集电极的
也就是形象的比喻
是大家一起拽着一根绳
谁使劲 任何一个人使劲
都可以把它拽下来这样一种关系
然后我们理解了
这个两根线时钟线和数据线之间的
电平和时序逻辑
在下个单元
我给大家详细的讲这样一种
I2C完成一笔完整通讯的
数据帧或者叫通讯协议
Protocol的实际的内容
那么在那个里头会给大家建立
I2C是一种或者是我们学习过的
第一种带有地址的通讯协议
那么在下一个单元
我们再来仔细的学习
-1.1 课程概览
--1.1 课程概览
-1.2 如何学好嵌入式系统
-2.1 计算机的基本概念、发展历史
-2.2 从晶体管到CPU
-2.3 概念CPU、微控制器MCU和嵌入式系统
-2.4 八卦计算机史
-2.5 不同领域、不同系列的嵌入式系统
-2.6 ARM历史与MKL25Z128 MCU
--2.6 ARM历史与MKL25Z128 MCU【习题】
-3.1 CPU的基本结构和运行机制
-3.2.1 堆栈的概念
--3.2.1 堆栈的概念【习题】
-3.2.2 堆栈的概念-头脑体操
-3.3.1 ARM的体系结构
--3.3.1 ARM的体系结构【习题】
-3.3.2 ARM的体系结构-头脑体操
-3.4.1 中断的概念和机制
-3.4.2 中断子程的概念和编程
-3.5 复位、时钟、存储器和总线
--3.5 复位、时钟、存储器和总线【习题】
-3.6 小结:MCU的总体结构和程序运行机制
--3.6 小结:MCU的总体结构和程序运行机制【习题】
-4.1 第一种外设:IO
-4.2 IO外设的编程实操-点亮LED
-4.3 IO外设的进阶知识
-4.4 嵌入式开发的基本概念与工具链
-4.5 嵌入式开发的进阶知识
-4.6 嵌入式开发中的C语言(上)
--4.6 嵌入式开发中的C语言(上)【习题】
-4.7 嵌入式开发中的C语言(下)
--4.7 嵌入式开发中的C语言(下)【习题】
-E0.1 实验零 开发板的初步认识与工具链的安装
-E0.2 实验零 体验一个例程的编译与下载
-E0.3 实验零 编写第一个程序:点亮核心板LED
-E1 实验一 点灯秘籍
-5.1 ARM微控制器外设学习概述
-5.2.1 ARM微控制器外设:通讯
-5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)
--5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)
--5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)【习题】
-5.2.3 ARM微控制器外设:异步串行通讯UART的原理(下)
--5.2.3 ARM微控制器的外设:异步串行通讯UART的原理(下)
--5.2.3 ARM微控制器外设:异步串行通讯UART的原理(下)【习题】
-5.2.4 ARM微控制器外设:RS-232串口与USB虚拟串口
--5.2.4 ARM微控制器外设:RS-232串口与USB虚拟串口
-5.2.5 ARM微控制器外设:UART的寄存器编程(上)
--5.2.5 ARM微控制器外设:UART的寄存器编程(上)
-5.2.6 ARM微控制器外设:UART的寄存器编程(下)
--5.2.6 ARM微控制器外设:UART的寄存器编程(下)
--5.2.6 ARM微控制器外设:UART的寄存器编程(下)【习题】
-E2 实验二 UART编程实操
-5.3.1 ARM微控制器外设:IO的中断编程(上)
-5.3.2 ARM微控制器外设:IO的中断编程(下)
-5.4.1 ARM微控制器外设:定时器的原理
-5.4.2 ARM微控制器外设:定时器的编程
--5.4.2 ARM微控制器外设:定时器的编程【习题】
-E3 实验三 定时器中断编程实操
-5.5.1 ARM微控制器外设:PWM的原理
-5.5.2 ARM微控制器外设:PWM寄存器与编程
-5.5.3 ARM微控制器外设:PWM编程实例—电子音乐
--5.5.3 ARM微控制器外设:PWM编程实例—电子音乐
-E4 实验四 数码管显示编程实操
-5.6.1 ARM微控制器外设:SPI通讯简介
--5.6.1 ARM微控制器外设:SPI通讯简介【习题】
-5.6.2 ARM微控制器外设:SPI寄存器与编程
-5.6.3 ARM微控制器外设:SPI编程实例—OLED显示屏驱动
--5.6.3 ARM微控制器外设:SPI编程实例—OLED显示屏驱动
-5.7.1 ARM微控制器外设:I2C通讯简介
-5.7.2 ARM微控制器外设:I2C的通讯协议
-5.7.3 ARM微控制器外设:I2C寄存器与编程
--5.7.3 ARM微控制器外设:I2C寄存器与编程【习题】
-5.7.4 ARM微控制器外设:I2C编程实例—加速度传感器
--5.7.4 ARM微控制器外设:I2C编程实例—加速度传感器
-5.8.1 ARM微控制器外设:ADC简介
-5.8.2 ARM微控制器外设:ADC基础
-5.8.3 ARM微控制器外设:ADC寄存器与编程
-E5 实验五 ADC编程实操
-E6 挑战实验
--E6 挑战实验
-6.1 嵌入式系统的接口与设计
-6.2 嵌入式系统的实例