7.1.1 I2C总线简介

1.I2C总线的基本结构

I2C总线由数据线SDA和时钟线SCL构成,每条线都通过上拉电阻接向正电源,所有采用I2C接口标准的器件均并行挂接在总线上,如图7-1所示。

I2C总线通常采用主从工作方式,整个系统中只有一个主控器件(单片机),其它器件都是具有I2C总线接口的外围从器件。每个I2C器件都具有唯一的地址,单片机作为主控器件,可以按器件地址访问每个器件,还可以按器件单元地址访问每个器件中的每个指定的存储单元。

图7-1 I2C总线系统硬件结构框图

由于I2C总线上各器件均采用漏极开路结构与总线连接,因此上拉电阻是不可缺少的。I2C总线的传输速率主要有100kHz与400kHz两种,采用100kHz速率时,上拉电阻一般为10kΩ,采用400kHz速率时,上拉电阻一般为2 kΩ。

当I2C总线上没有信息传送时,数据线SDA和时钟线SCL都为高电平,因此总线在空闲状态保持高电平。连接到总线上的任一器件输出低电平,都会将总线拉向低电平,这种连接方式称为“线与”。

I2C总线协议规定,将数据传送到总线的器件作为发送器,从总线接收数据的器件为接收器,主控器件和从器件都可以作为发送器或接收器,但串行时钟、启动信号和停止信号是由主控器件产生的,数据发送或接收的模式也是由主控器件规定的。

2.I2C总线的主要特点

(1)简单

(2)通信方便

7.1.2 I2C总线的信息传送

当I2C总线上的主控器件与某个从器件进行一次数据传输时,典型的时序过程如图7-1所示,通常需要经过下述步骤:

图7-1 I2C总线时序

1.发送启动信号

在I2C总线上执行一次数据传输时,必须首先由主控器件发出启动信号。I2C总线的协议规定,在SCL高电平期间,SDA的下降沿作为启动信号。在启动信号发出之后,总线就处于被占用的状态。具有I2C总线接口的所有从器件检测到启动信号之后,就开始时刻监测总线状态,做好响应的准备。

2.发送器件地址

主控器件发送启动信号之后,紧接着发出1字节的器件地址,用来确定I2C总线上的哪个从器件作为通信对象。

器件地址码由一个字节构成,其结构如表7-1所示。高4位为器件类型识别码,用来说明这是哪种类型的器件(例如E2PROM的类型识别码为1010);后面的3位为片选码,用来说明同一类型器件中的哪一个;最低位R/W实际上不是地址,而是方向位,用来设置主控器件与从器件的数据传送方向。R/W=0,表明主控器件对从器件执行写操作;R/W=1,表明主控器件对从器件执行读操作。

表7-1 I2C器件地址码结构

D7

D6

D5

D4

D3

D2

D1

D0

器件类型码

片选

R/W

从器件收到启动信号以后,就时刻监测着总线状态,如果接收到与自身相匹配的器件地址,就产生一个应答信号,发送到总线上。

3.应答信号

I2C总线协议规定,每成功地传送一个字节数据(含地址及命令字)之后,接收器件都必须产生一个应答信号,接收器件在第9个时钟周期将SDA拉为低电平,表示传输的数据字节已正确接收。

接收器件收到一个完整的数据字节后,如果忙于处理内部中断等事务,无法立刻接收下一字节,可以将SCL线拉向低电平,从而使主控器件处于等待状态。直到接收器件准备好接收下一字节时,才释放SCL线使之为高电平,从而使数据传送可以继续进行。

4.数据传输

主控器件向I2C总线发送器件地址并得到从器件应答后,便伴随着时钟脉冲,开始一位一位的数据传输,每个字节均按高位在前、低位在后的顺序进行传送。在一次数据传输的过程中允许传送的数据字节数没有限制,但每传输一个字节之后,都必须在得到应答信号后才能进行下一个字节的传送。

根据I2C协议的规定,仅当总线空闲时才允许启动数据传输。在进行数据传输时,时钟信号SCL为高电平期间,数据线SDA上的数据必须保持稳定,不允许有跳变现象,如图7-2所示(如有跳变,则可能被误认为是启动或停止信号)。只有在时钟信号为低电平期间,数据线上的状态才允许变化。

图7-2 I2C总线数据传输期间的有效性规定

5.非应答信号

当主控器件为接收器件时,主控器件对接收到的最后一个字节不应答,以向发送数据的从器件表示数据传送结束。从器件收到非应答信号后,必须使数据线保持高电位,以便主控器件产生停止信号。

6.发送停止信号

当全部数据传送完毕以后,主控器件发送停止信号,释放总线控制权。I2C总线的协议规定,在SCL高电平期间,SDA的上升沿作为停止信号。在停止信号发出之后,总线就处于空闲状态。总线上的所有从器件接收到停止信号之后,均使输出保持高电平。

7.1.3 I2C总线时序的编程实现

目前,已有许多较新型号的单片机产品具备了I2C总线接口功能,例如Philips公司的LPC93X、Atmel公司的ATMEGA48、TI公司的MSP430等。这类单片机工作时,I2C总线状态由硬件监测,不需要用户介入,编程应用非常方便。

传统的51系列单片机不具备I2C总线接口,但在单主机应用系统中可以通过软件方法来模拟I2C总线的工作时序,实现对I2C器件的控制。

下面逐一介绍模拟I2C总线基本时序的各个子程序。

1.I2C启动信号的软件模拟

在I2C总线上执行一次数据传输时,首先必须由主机发出启动信号。根据I2C总线的时序规则,在SCL高电平期间,SDA的下降沿作为启动信号,如图7-1所示。具有I2C总线接口的从器件接收到启动信号后,就会做出响应。

在51系列单片机上产生I2C启动信号的程序代码如下:

void I2C_start()

{

SDA = 1; // SDA高电平,为产生下降沿做准备

delay();

SCL = 1; // SCL高电平

delay(); // 延时>4.7μs

SDA = 0; // 在SCL高电平期间的SDA下降沿作为启动信号

delay(); // 延时>4μs

SCL = 0; // SCL低电平

delay();

}

图7-1 I2C启动信号 图7-2 I2C停止信号

2.I2C停止信号的软件模拟

在I2C总线上执行完数据传输之后,应该由主机发出停止信号。根据I2C总线的时序规则,在SCL高电平期间,SDA的上升沿作为停止信号,如图7-2所示。具有I2C总线接口的从器件接收到停止信号后,就会做出响应。

在51系列单片机上产生I2C停止信号的程序代码如下:

void I2C_stop()

{

SCL=0;

delay();

SDA = 0; // SDA低电平,为产生上升沿做准备

delay();

SCL = 1; // SCL高电平

delay(); // 延时>4μs

SDA = 1; // SDA上升沿,作为停止信号

delay(); // 延时>4.7μs

}

3.I2C应答信号的软件模拟

在I2C总线上传输一个数据字节后,接收器件应该发送一个应答信号,表示数据已正确接收。在SCL高电平期间,接收器件将SDA拉为低电平,即为应答信号,如图7-3所示。

当51系列单片机作为接收器件时,可以利用下述程序代码产生I2C应答信号:

void I2C_acknowledge()

{

SDA=0; // SDA低电平,作为应答信号

delay();

SCL=1; // SCL从低到高

delay(); // 延时>4.7μs

SCL=0; // SCL高电平保持一段时间,然后恢复为0

delay();

SDA=1; // SDA恢复高电平,I2C总线处于空闲状态

delay()

}

图7-3 I2C应答信号 图7-4 I2C非应答信号

4.I2C非应答信号的软件模拟

当51系列单片机作为接收器件时,在接收到一个数据字节之后,向I2C总线发送一个非应答信号,则表示结束数据传输。在SCL高电平期间,保持SDA为高电平,即为非应答信号。

在51系列单片机上产生I2C非应答信号的程序代码如下:

void I2C_notacknowledge()

{

SDA=1; // SDA保持高电平,作为非应答信号

delay();

SCL=1; // SCL从低到高

delay(); // 延时>4.7μs

SCL=0; //

delay();

SDA=0;

}

5.I2C应答信号检验的软件模拟

当51系列单片机作为发送器件时,每发送一个数据字节之后,必须在下一个时钟周期等待接收器件回送到I2C总线上的应答信号,只有在获得应答信号之后,才能继续执行后面的操作。如果在SCL高电平期间检验SDA为0,则说明有应答信号,否则认为无应答信号。

在51系列单片机上检验I2C应答信号的程序代码如下:

bit I2C_check_acknowledge() // 返回值为1说明有应答,为0说明无应答

{

bit i;

SDA=1; // 单片机I/O端口特性要求读SDA端口前必须写1

delay();

SCL=1; // SCL高电平

delay(); // SCL高电平持续时间约5μs

if(SDA==1) // 判断是否接收到从器件发回的应答信号

i=0; // 若i=0,说明无应答信号

else

i=1; // 若i=1,说明有应答信号

SCL=0;

delay();

return i; // 返回检验结果值

}

上述程序的返回值为bit类型,如果主控器件收到了应答信号,检验应答信号的返回结果为“1”,否则返回值为“0”。

6.单片机向I2C总线发送1个字节数据

单片机向I2C总线上发送1个数据字节时,必须遵守I2C协议的规定,按照从高位到低位的顺序,依次将数据字节中的8个二进制位发送到总线。

当调用下述程序时,把准备发送的数据传递给参数data,程序中的语句temp=temp

IIC 概述之源码仿真的更多相关文章

  1. U-BOOT概述及源码分析(一)

    嵌入式Linux系统从软件角度通常可以分为以下4个层次: 引导加载程序 | Linux内核 | 文件系统 | 用户应用程序 嵌入式Linux系统中典型分区结构: 正常启动过程中,Bootloader首 ...

  2. Netty 源码 Channel(一)概述

    Netty 源码 Channel(一)概述 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) Channel 为 Netty ...

  3. [源码解析] PyTorch 分布式(1)------历史和概述

    [源码解析] PyTorch 分布式(1)------历史和概述 目录 [源码解析] PyTorch 分布式(1)------历史和概述 0x00 摘要 0x01 PyTorch分布式的历史 1.1 ...

  4. Celery 源码解析三: Task 对象的实现

    Task 的实现在 Celery 中你会发现有两处,一处位于 celery/app/task.py,这是第一个:第二个位于 celery/task/base.py 中,这是第二个.他们之间是有关系的, ...

  5. Celery 源码解析五: 远程控制管理

    今天要聊的话题可能被大家关注得不过,但是对于 Celery 来说确实很有用的功能,曾经我在工作中遇到这类情况,就是我们将所有的任务都放在同一个队列里面,然后有一天突然某个同学的代码写得不对,导致大量的 ...

  6. Celery 源码解析六:Events 的实现

    在 Celery 中,除了远程控制之外,还有一个元素可以让我们对分布式中的任务的状态有所掌控,而且从实际意义上来说,这个元素对 Celery 更为重要,这就是在本文中将要说到的 Event. 在 Ce ...

  7. ffmpeg源码编译安装(Compile ffmpeg with source) Part 1 : 通用部分

    本页内容包含了在Unix/Linux中用源码包编译的通用的结构 可能不仅仅适用于ffmpeg 为啥使用源码包编译 编译源码可以扩展功能, 实现相对于自己平台的最优化, 还可以自定义的修改 概述 大部分 ...

  8. Orchard源码:EventBus&EventHandler

    概述 看源码是一件吃力又很爽的事情,昨天还被搞的一头雾水,今天忽然守得云开见月明.明白它设计意图的同时,感觉自己又提升了一步:) Orchard刚开始看往往毫无头绪,建议可以从Orchard.Fram ...

  9. 【Spark】源码分析之RDD的生成及stage的切分

    一.概述 Spark源码整体的逻辑(spark1.3.1): 从saveAsTextFile()方法入手 -->saveAsTextFile()  --> saveAsHadoopFile ...

随机推荐

  1. 一句话输出网站404页面,REFER及相关排序

    cat www.log|awk '$9~/404/ {print $7"," $11}'|sort|uniq -c|sort -nr > ./www404.csv

  2. Another Look at Events(再谈Events)

    转载:http://www.qtcn.org/bbs/simple/?t31383.html Another Look at Events(再谈Events) 最近在学习Qt事件处理的时候发现一篇很不 ...

  3. How to make vcredist_x86 reinstall only if not yet installed

    Since you don't want to tell what minimal version of Visual C++ redistributable package you require, ...

  4. 8.2.1.10 Nested-Loop Join Algorithms 嵌套循环 关联算法:

    8.2.1.10 Nested-Loop Join Algorithms 嵌套循环 关联算法: MySQL 执行关联在表之间使用一个嵌套循环算法或者变种 Nested-Loop Join Algori ...

  5. COJ 0979 WZJ的数据结构(负二十一)

    WZJ的数据结构(负二十一) 难度级别:C: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你实现一个数据结构,完成这样的功能: 给你一个 ...

  6. memory_target not supported on this system

  7. mysql优化整理(索引)

    什么是索引? 索引是表记录的单个或多个字段重新组织的一种方法,其目的是提高数据库的查询速度,本质上就是一种数据结构. 索引的类型:primary(主键).secondary(其他) 索引的数据结构 I ...

  8. nginx本地的测试环境添加SSL

    要在本地添加SSL,首先要做的是防火墙是不是放开了443端口,同时,在nginx安装时是不是支持了ssl模块,这个安装网上很容易找到相关资料 防火墙,个人还是用iptables比较直观 先将selin ...

  9. (转)Linux下apache限速和限制同一IP连接数的实现

    单位有一台DELL的服务器,4核双CPU,4G内存,1TB的存储空间,闲来无事,申请了域名http://www.zxzy123.cn,做了个网站,本以为用这样的配置做个下载站是绰绰有余了,没想到上线没 ...

  10. (转)Linux整合apache和tomcat构建Web服务器

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://wenzhongxiang.blog.51cto.com/6370734/1285 ...