总线接口与计算机通信(一)I2C总线
1. I2C总线的基本概念
1)发送器(Transmitter):发送数据到总线的器件
2)接收器(Receiver):从总线接收数据的器件
3)主机(Master):初始化发送、产生时钟信号和终止发送的器件
4)从机(Slave):被主机寻址的器件
2. I2C总线的信号传输
1) 3种速率可选择
标准模式100kbps、快速模式400kbps、最高速率3.4Mbps
2) 具有特定的传输起始、停止条件
a) 起始条件:当SCL 处于高电平期间时,SDA 从高电平向低电平跳变时产生起始条件。 起始条件常常简记为S
b) 停止条件:当SCL 处于高电平期间时,SDA 从低电平向高电平跳变时产生停止条件。 停止条件简记为P
3) 数据传输从确定从机地址开始
a)多个从机可连接到同一条I2C 总线上,它们之间通过各自唯一的器件地址来区分
b)一般从机地址由7 位地址位和一位读写标志R/W 组成,7 位地址占据高7 位,读写位在最后。读写位是0,表示主机将要向从机写入数据;读写位是1,则表示主机将要从从机读取数据
4) 以字节为单位的数据传输方式
a) I2C 总线以字节(Byte) 为单位收发数据,主机总是先发地址再发数据
b) 在I2C总线传输数据过程中,每传输一个字节,都要跟一个应答状态位。遵循"谁接收谁产生"的原则,即总是由接收器产生应答位,应答位为0 表示接收器应答 (ACK) ;为1 则表示非应答(NACK)
c) 如果接收器在接收完最后一个字节的数据,或者不能再接收更多的数据时,应当产生非应答来通知发送器
一次iic交互的例子,写AT24C08
写AT24C08:
start信号 + addr + data[N] + stop信号
{
. master发送start信号: [scl高+sda下降沿] 2.1. master发送addr: 7位设备地址 + R/W; 发完立刻把电平拉高,等待slave的ack;
[sda在scl低电平的时候准备数据, 在scl上升沿时发送数据] * 8次
MSB---先发最高位数据sda.
2.2. slave收到master的start信号后,就开始监测master的数据了. 收到addr完毕并且发现addr就是自己的时候,马上拉低sda以表明传输有效(这就是所谓ack). 3.1 主机收到ack后接着发送数据data, 这里是写1个字节,那就和发送addr用同样的方法连续发送8个bit就是了.
同样,发完立刻把电平拉高,等待slave的ack;
3.2 slave收到8位data完毕,马上拉低sda以表明传输有效(ack). . master收到ack,马上发送stop信号以关闭通信. 说明:
iic协议允许一次连接中传输多个字节,具体最多允许多少个字节看器件(AT24C08允许8个字节连续传输), 但是必须以8bit为单位, 接收方要给一个ack才会继续后面的传输.
明确start和stop是由master发起的. }
(灰色为主机的工作时隙,白色为从机的工作时隙)
S:起始位(START)
SA:从机地址(Slave Address),7 位从机地址
W:写标志位(Write),1 位写标志 R:读标志位(Read),1 位读标志
A:应答位(Acknowledge),1 位应答
A:非应答位(Not Acknowledge),1 位非应答
D:数据(Data),每个数据都必须是8 位
P:停止位(STOP)
3. I2C 总线具有如下特点
1) I2C 总线是双向传输的总线,因此主机和从机都可能成为发送器和接收器。
不论主机是发送器还是接收器,时钟信号SCL都要由主机来产生。
2) 读取数据是依据SCL为低时,SDA的电平.
3) 进行数据传送时,在SCL为高电平期间,SDA线上电平必须保持稳定,只有SCL为低时,才允许SDA线上电平改变状态。并且每个字节传送时都是高位在前。
4) 关于时钟:
由于通讯的时钟是由主机(master)控制的, 所以slave不需要有设置工作频率, master快, slave就快, master慢, slave就慢. (甚至可以时快时慢, 忽快忽慢). 但通常会有一个固定频率.
现在的I2C都是由集成的模块实现, 集成的模块往往能够满足I2C通讯的最大通讯速度, 所以从这个角度考虑, slave是完全不需要考虑通讯频率的.
5) . 关于应答信号:
ACK=0时为有效应答位,说明从机已经成功接收到该字节,若为1则说明接受不成功。
主机在读取从机数据时,也会产生ack,但是主机读取最后一个字节时不需要产生ack.
6) 只需要由两根信号线组成,一根是串行数据线SDA,另一根是串行时钟线SCL。
7) SDA 和SCL 信号线都必须要加上拉电阻Rp(Pull-Up Resistor)。上拉电阻一般取值3~ 10KΩ
8) SDA 和SCL 管脚都是漏极开路(或集电极开路)输出结构
9) 同一IIC总线上同一型号的IC只能最多共挂8片同种类芯片
4. I2C总线注意点
1) . 在特殊情况下,若需禁止所有发生在I2C总线上的通信,可采用封锁或关闭总线,具体操作为在总线上的任一器件将SCL锁定在低电平即可。
2) . 如果从机需要延迟下一个数据字节开始传送的时间,可以通过把SCL电平拉低并保持来强制主机进入等待状态。
3) . 主机完成一次通信后还想继续占用总线在进行一次通信,而又不释放总线,就要利用重启动信号。它既作为前一次数据传输的结束,又作为后一次传输的开始。
4) . 总线冲突时,按"低电平优先"的仲裁原则,把总线判给在数据线上先发送低电平的主器件。
5) . SDA仲裁和SCL时钟同步处理过程没有先后关系,而是同时进行的。
5. I2C总线在手机上的常见应用
所应用范围包括:摄像头、调频收音机芯片、音频编解码芯片、模拟电视、光电鼠标等
IIC 通讯协议 <http://blog.csdn.net/zmq5411/article/details/6085740>
由时序图写出IIC通信的Master代码, 不咋准确,仅作理解使用:
//准备:
void init() // 初始化
{
SCL=;
delay();
SDA=;
delay();
} /*从下面开始, delay()的主要作用是维护周期.*/ //generate Start signal
void start() // 启动信号
{
SDA=;
delay();
SCL=;
delay();
SDA=;
delay();
}
//generate Stop signal
void stop() // 停止信号
{
SDA=;
delay();
SCL=;
delay();
SDA=;
delay();
}
// ACK
// 个人感觉这个ACK处理的不太好, 半个周期内理想条件下SDA已经置为1,这个时候SCL拉高没有问题. 但如果从机响应较慢呢? 就会形成 SCL=1 + SDA下降沿, 那就形成了一个start信号.
// 如果只是一个slave,这没什么,但是对于带了多个slave的总线,其他slave就进入接收预备状态,不太符合情理.
// 应该在这里可以多等一下,保证主机拉高sda以及从机拉低sda的过程均在SCL=0的时候完成. 即在SCL=1之前再加入delay,并且在SCL=1之前就可以读SDA了,读到ack之后再拉高.
void wait_ack() //等待回应信号
{
uchar i=;
SCL=;
delay(); //这个delay是为了维持半个周期.
while((SDA==)&&(i<)) //slave的ack会将sda拉低. 这里为什么要等255个循环? 是为了等待ack.
{
i++;
}
SCL=; //读到ack之后又拉低SCL, 准备下一个周期
delay();
} // writebyte
void writebyte(uchar date) // 写一个字节
{
uchar i, temp;
temp = date;
for(i=;i<;i++)
{
Temp = temp<<;
SCL = ;
delay();
SDA = CY;
delay();
SCL = ;
delay();
}
SCL = ;
delay(); // 这个delay是为了等待SCL稳定过渡到低电平同时维持半个周期的时间.
SDA = ; // 发完立刻把电平拉高,等待slave的ack;
delay(); // 这个delay是为了维持半个周期的时间.
} //readbyte
uchar readbyte()//读一个字节
{
uchar i, j, k;
SCL=;
delay();
SDA=;
for(i=;i<;i++)
{
SCL=;
delay();
if(SDA==)
j=;
else
j=;
k=(k<<)|j;
SCL=;
delay();
}
delay();
return k;
} // write_add
void write_add(uchar address, uchar info)//指定地址写一个字节数据
{
start();
writebyte(0xa0);//这是一个从机芯片硬件的地址+ /W信号,不同芯片会不一样
wait_ack();//等待应答
writebyte(address);//这是指定从机芯片的内部存储地址
wait_ack();
writebyte(info);
wait_ack();
stop();
} // read_add
uchar read_add(uchar address)//指定地址读一个字节数据
{
uchar dd;
start();
writebyte(0xa0); //这是一个从机芯片硬件的地址+ /W 信号,不同芯片会不一样
wait_ack();
writebyte(address);
wait_ack();
start();
writebyte(0xa1);//这是一个从机芯片硬件的地址+ R信号,不同芯片会不一样
wait_ack();
dd=readbyte();
stop();
return dd;
}
参考:
- 普通IO口模拟实现I2C通信及应用解析 http://blog.csdn.net/bluewhaletech/article/details/38706093,bluewhaletech
总线接口与计算机通信(一)I2C总线的更多相关文章
- 总线接口与计算机通信(二)SPI总线
SPI总线协议及SPI时序图详解 : http://blog.163.com/sunshine_linting/blog/static/44893323201181482335951/ 浅谈SPI总 ...
- 总线接口与计算机通信(五)CAN总线
CAN网络图示 CAN的特点 CAN协议具有以下特点. (1) 多主控制 在总线空闲时,所有的单元都可开始发送消息(多主控制). 最先访问总线的单元可获得发送权( ...
- 总线接口与计算机通信(三)UART起止式异步通用串行数据总线
串口简介 1. 什么是串口? 串口是计算机上一种非常通用的设备通信的协议.串口通信的概念非常简单,串口按位(bit) 发送和接收字节.尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送 ...
- 总线接口与计算机通信(四)USB外部总线(初级认识)
USB简介 USB是英文Universal Serial BUS(通用串行总线)的缩写,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯,是应用在PC领域的接口技术.USB接口支持设备的即插 ...
- I2C 总线原理与架构
一.I2C总线原理 I2C是一种常用的串行总线,由串行数据线SDA 和串行时钟线SCL组成.I2C是一种多主机控制总线,它和USB总线不同,USB是基于master-slave机制,任何设备的通信必须 ...
- i2c总线,核心,驱动详解
Linux I2C驱动分析(一)----I2C架构和总线驱动 一.I2C总线原理 I2C是一种常用的串行总线,由串行数据线SDA 和串线时钟线SCL组成.I2C是一种多主机控制总线,它和USB总线不同 ...
- 【转】I2C总线协议
I2C总线(Inter Integrated-Circuit)是由PHILIPS公司在上世纪80年代发明的一种电路板级串行总线标准,通过两根信号线——时钟线SCL和数据线SDA——即可完成主从机的单工 ...
- i2c总线,设备,驱动之间的关系
------ 总线上先添加好所有具体驱动,i2c.c遍历i2c_boardinfo链表,依次建立i2c_client, 并对每一个i2c_client与所有这个线上的驱动匹配,匹配上,就调用这个驱动的 ...
- Linux设备驱动模型之I2C总线
一.I2C子系统总体架构 1.三大组成部分 (1)I2C核心(i2c-core):I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册.注销方法,提供了与具体硬件无关的I2C读写函数. (2)I2 ...
随机推荐
- word2vec代码解释
以前看的国外的一篇文章,用代码解释word2vec训练过程,觉得写的不错,转过来了 原文链接 http://nbviewer.jupyter.org/github/dolaameng/tutorial ...
- 我的Python成长之路---第六天---Python基础(18)---2016年2月20日(晴)
os模块 提供对操作系统进行调用的接口 >>> import os >>> os.getcwd() # 获取当前工作目录,类似linux的pwd命令 '/data/ ...
- 关于Ubuntu12.04下code::blocks不能使用debug解决方法
问题描述: 系统:ubuntu 12.04 code::blocks版本:10.05 问题现象:debug->start 之后出现:warning: GDB: Fail ...
- 3,C语言文件读写
这两天看到一个关于文件读写的题目,索性就把相关内容总结下. C语言文件读写,无非是几个读写函数的应用,fopen(),fread(),fwrite()等,下面简单介绍下. 一.fopen() 函数原型 ...
- struts2 convention-plugin
导入这个插件,该插件的作用是替换掉struts.xml 原则是没有配置,全是约定 基本步骤 1.新建HomeAction,里面有个execute方法return success,请求home.acti ...
- iOS开发App上传的三大步骤
上传流程 1.itunse connect中->“我的App”中新建创建应用,填写相关的信息 a.项目名称(多创建几个),避免重名 b.想好应用的类型 c.应用截图(5.5,4.7,4,3.5寸 ...
- POJ 3276 Face The Right Way 翻转(开关问题)
题目:Click here 题意:n头牛排成一列,F表示牛面朝前方,B表示面朝后方,每次转向K头连续的牛的朝向,求让所有的牛都能面向前方需要的最少的操作次数M和对应的最小的K. 分析:一个区间反转偶数 ...
- MFC、C++ 、Windows编程高手
cnblogs: DoubleLi 1. DoubleLi 白手起家Win32SDK应用程序 http://www.cnblogs.com/lidabo/p/3450178.html#_Toc309 ...
- [转]数位dp小记
转载自:http://blog.csdn.net/guognib/article/details/25472879 参考: http://www.cnblogs.com/jffifa/archive/ ...
- ZOJ 3490 String Successor 字符串处理
一道模拟题,来模拟进位 暴力的从右往左扫描,按规则求后继就好了.除了Sample已给出的,还有一些需要注意的地方: 9的后继是10,而不是00: (z)的后继是(aa),而不是a(a): 输入虽然最长 ...