I2C通信基本原理及其实现
I2C是一种总线式结构,它只需要SCL时钟信号线与SDA数据线,两根线就能将连接与总线上的设备实现数据通信,由于它的简便的构造设计,于是成为一种较为常用的通信方式。
由于I2C采用的是主从式通信方式,所以,通信的过程完全由主设备仲裁。在通信之前,必须由主设备发送一个起始信号,决定数据是否可以开始传送,并且在结束通信时,必须再由主设备发送一个结束信号,以表示通信已经结束。

因为,通信之前,主设备需要发送一个起始信号,所以,先讲一下起始信号。通过上面的图就可以知道(上图中的第一个波形图是SDA数据线,第二个波形图是SCL时钟信号线),起始信号是在SCL时钟信号线处于高电平时,SDA数据线由高电平转换为低电平,也就是产生一个下降沿,就意味着起始信号已经发送,数据的通信可以进行了。代码如下:
void I2C_Start()
{
I2C_SDA = 1;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();//建立时间是I2C_SDA保持时间>4.7us
I2C_SDA = 0;
I2C_Delay10us();//保持时间是>4us
I2C_SCL = 0;
I2C_Delay10us();
}
同样的,由上图可知:结束信号,就是在SCL时钟信号线处于高电平时,SDA数据线由低电平变为高电平 ,也就是,SDA数据线产生一个 上升沿。代码如下:
void I2C_Stop()
{
I2C_SDA = 0;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();//建立时间大于4.7us
I2C_SDA = 1;
I2C_Delay10us();
}

接下来就是该讲一下,I2C数据的发送问题了。由于I2C是主从式通信,也就意味着一根总线上可以挂载多个从设备,那么主设备如何区分这些从设备呢?主设备如何知道是在与哪一个从设备在通信呢?答案是:通过地址。每一个从设备都有自己的地址编码,也就是说,主设备在与具体的某一个从设备通信之前,必须先发送地址,以表示与主设备通信的是该设备。从上图可知,主设备在发送完起始信号后,立刻开始了发送从设备的地址。那么如何发送数据地址呢?首先,在SCL时钟信号线处于低电平时,SDA数据线上的地址信息要开始准备了。I2C通信一个必须注意的点就是,在传送地址信息时,都是从高位开始传送,
I2C_SDA = dat >> 7;
dat = dat << 1;
接着,SCL时钟信号线开始由低电平向高电平转换,这个时候,SDA数据线上的数据开始在传送了,当SCL时钟信号线上的信号再由高电平转换位低电平的时候,一个Bit位的数据已经传送完毕。在地址信息传送完毕之后,还会有一个应答信号,因为,为了确保从设备接收到已经发送的数据,从设备就会向主设备发送一个应答信号,若主设备接收到应答信号则说明数据传送成功,否则数据传送失败。很重要的一点是,总线一直是由主设备控制,那么当从设备想要向主设备发送一个应答信号时,主设备需要是释放总线,将总线权限交给从设备。
所以,从设备在向主设备发送应答信号时,主设备应该释放总线,代码如下:
I2C_SDA = 1;
接着,由上图可知,当SCL时钟信号线再次拉高时,就进入了第9个时钟周期,也就是此时开始传送应答信号。当成功应答时,返回1,否则返回0。完整代码如下:
I2C_SDA = 1;
I2C_Delay10us();
I2C_SCL = 1; while(I2C_SDA && (ack == 1))
{
b++;
if(b > 200)
{
I2C_SCL = 0;
I2C_Delay10us();
return 0;
}
} I2C_SCL = 0;
I2C_Delay10us();
return 1;
}
最后,就是I2C设备(也就是主设备)数据的接收。此时,从设备发送数据给主设备,也就是,主设备进行数据的接收。那么,主设备同样要释放总线权限。也就是
I2C_SDA = 1;
首先,SCL时钟信号线为低电平,这时,SDA数据线要准备好数据了,接着,SCL时钟信号线由低电平变为高电平,此时,数据传送开始了,当SCL时钟信号线再次变为低电平是,一个Bit的数据传送结束。代码如下:
uchar I2C_ReadByte()
{
uchar a = 0,dat = 0;
I2C_SDA = 1; I2C_Delay10us();
//I2C_SCL = 0;
for(a=0; a<8; a++)
{
I2C_SCL = 1;
I2C_Delay10us();
dat <<= 1;
dat |= I2C_SDA;
I2C_Delay10us();
I2C_SCL = 0;
I2C_Delay10us();
}
return dat;
}
I2C的底层时序到这里基本上就已经结束了。
I2C通信基本原理及其实现的更多相关文章
- MCU开发之I2C通信
程序状态字PSW是8位寄存器,用于存放程序运行的状态信息,PSW中各位状态通常是在指令执行的过程中自动形成的,但也可以由用户根据需要采用传送指令加以改变.各个标志位的意义如下: PSW.7(Cy):进 ...
- 【转载】GPIO模拟i2c通信
I2C总线的通信过程(见图4-8)主要包含三个主要阶段:起始阶段.数据传输阶段和终止阶段. 1. 起始阶段 在I2C总线不工作的情况下,SDA(数据线)和SCL(时钟线)上的信号均为高电平.如果此时主 ...
- 由于用mpu6050模块,所以要用上i2c通信原理。
i2c通信原理 i2c总线只有两根双向信号线,一根是数据线SDA,一根是时钟线SCL. 每个接到i2c总线上的器件都有唯一的地址,主机与其他器件之间的数据传送可以是由主机发送给其他器件.主机为发送器, ...
- AT24C0X I2C通信原理
/********************************************************************** * AT24C0X I2C通信原理 * 说明: * 之前 ...
- 【转】三种方法让你在I2C通信中同时和多个从机通信
ref:http://tieba.baidu.com/p/3769008030 对于不同地址的模块就不用多说了,直接分别对其地址进行通信即可.那么若拿到相同地址的模块,或者直接是相同的多个模块怎么办呢 ...
- ESP8266开发之旅 基础篇⑤ ESP8266 SPI通信和I2C通信
设备与设备之间的通信往往都伴随着总线的使用,而用得比较多的就当属于SPI总线和I2C总线,而恰巧NodeMcu也支持这两种总线通信,所以本章的主要内容就是讲解ESP8266 SPI和I2C总线 ...
- Socket通信基本原理
Http通信: http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据. Socket通信: Socket通信则是在双方建立起连接后就 ...
- STM32的I2C通信
I2C总线是由NXP(原PHILIPS)公司设计,有十分简洁的物理层定义,其特性如下: 只要求两条总线线路:一条串行数据线SDA,一条串行时钟线SCL: 每个连接到总线的器件都可以通过唯一的地址和一直 ...
- ARM学习笔记15——串口通信基本原理【转】
计算机串口基本理论 1.什么是串口? 2,什么是RS-232? 3,什么是RS-422? 4,什么是RS-485? 5,什么是握手? 1,什么是串口? 串口是计算机上一种非常通用的设备通信的协议(不要 ...
随机推荐
- 03-三层交换机的OSPF实验
三层交换机的OSPF实验 1.OSPF介绍 开放式最短路径优先(英语:Open Shortest Path First,缩写为 OSPF)是对链路状态路由协议的一种实现,隶属内部网关协议(IGP),故 ...
- [转帖]Windows7/2008中批量删除隧道适配器的方法
https://www.jb51.net/os/windows/479838.html 客户现场的硬件信息总是发生变化 这里查找一下资料 尝试一下. 1.在网卡属性的“网络”中,将“Internet协 ...
- Windows apache-flume-1.6.0+Kafka+Es
apache-flume-1.6.0 kafka_2.11-1.1.0 elasticsearch1.5.1 flume配置 a1.sources = kafkaSource a1.channels ...
- 安装vue-cli
1.路径 https://nodejs.org/en/ cmd 创建项目 1.创建一个基于 webpack 模板的新项目 vue init webpack projectname(项目名) 2.项目名 ...
- 消息队列与Kafka
2019-04-09 关键词: 消息队列.为什么使用消息队列.消息队列的好处.消息队列的意义.Kafka是什么 本篇文章系本人就当前所掌握的知识关于 消息队列 与 kafka 知识点的一些简要介绍,不 ...
- JQ高级
一.选择器 css语法选择器 $('css3 选择器位‘) 索引匹配 $('div:eq(0)') $('div').eq(0) 内容 $('div:contains(标签文本内容)') // 注:采 ...
- Floyd-蒟蒻也能看懂的弗洛伊德算法(当然我是蒟蒻)
今天来讲点图论的知识,来看看最短路径的一个求法(所有的求法我以后会写,也有可能咕咕咕) 你们都说图看着没意思不好看,那今天就来点情景 暑假,_GC准备去一些城市旅游.有些城市之 ...
- 大数据-hadoop生态之-HDFS
一.HDFS初识 hdfs的概念: HDFS,它是一个文件系统,用于存储文件,通过目录树定位文件,其次,他是分布式的,由很多服务器联合起来 实现功能,集群中的服务器各有各自的角色 HDFS设计适合一次 ...
- python通过套接字来发送接收消息
案例如下: 1.启动一个服务端套接字服务 2.启动一个客户端套接字服务 3.客户端向服务端发送一个hello,服务端则回复一个word,并打印 参考地址:https://www.cnblogs.com ...
- Springboot集成FreeMarker
Apache官网对FreeMarker的解释如下: Apache FreeMarker™是一个模板引擎 :一个基于模板和变化的数据来生成文本输出(HTML网页,电子邮件,配置文件,源代码,等等)的Ja ...