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,什么是串口? 串口是计算机上一种非常通用的设备通信的协议(不要 ...
随机推荐
- python3.6新特性
print(f'{6:^30}') print('\n'.join([' '.join([f'{i}*{j}={i*j:2d}' for j in range(1,i+1)]) for i in ra ...
- Arguments Optional 计算两个参数之和的 function
创建一个计算两个参数之和的 function.如果只有一个参数,则返回一个 function,该 function 请求一个参数然后返回求和的结果. 例如,add(2, 3) 应该返回 5,而 add ...
- 踩坑之mongodb配置文件修改
一.说明 本文档是在mongodb为3.4下编写的,仅作为参考 配置mongodb有两种方式,一种是通过mongod和mongos两个命令:另外一种方式就是配置文件的方式.因为更容易去管理,所以后者更 ...
- qsort.c源码
/* 版权所有(C) 1991-2019 自由软件资金会. 该文件属于是GUN C语言函数库,由Douglas C. Schmidt(schmidt@ics.uci.edu)所写. GUN C语言函数 ...
- 北京2018网络赛A题
题意:给你一个迷宫,迷宫有开始节点和结束节点,问你从开始走到结束的最小时间,其中,#代表这个点有毒气,身上必须带着氧气瓶才行,B代表每次进入这个点可以带一个氧气瓶,最多身上带五个,P代表进入这个点加速 ...
- Go语言中数组
数组是一个值类型 func ArrayTest1(){ var arryA [3]int = [3]int{1,2,3} //创建一个数组B,将B中第二个元素设置为200 arryB := arryA ...
- MYSQL OR与AND同时出现的用法
表中数据 MySQL中or和and的用法 SELECT * from student WHERE id = 1 or id = 2 AND age = 20; -- 查询结果是id = 2且age = ...
- 【CF1146】Forethought Future Cup - Elimination Round
Forethought Future Cup - Elimination Round 窝也不知道这是个啥比赛QwQ A. Love "A" 给你一个串,你可以删去若干个元素,使得最 ...
- MapReduce-TextInputFormat 切片机制
MapReduce 默认使用 TextInputFormat 进行切片,其机制如下 (1)简单地按照文件的内容长度进行切片 (2)切片大小,默认等于Block大小,可单独设置 (3)切片时不考虑数据集 ...
- springBoot和Mybatis输出sql日志
利用slf4j来输出日志. 首先需要版本兼容的slf4j-log4j12.log4j.slf4j-api.slf4j-nop.slf4j-simple这5个包. 可以去maven知识库中找到这5个包的 ...