花点时间让你彻底搞懂I2C总线
- 格式:doc
- 大小:112.00 KB
- 文档页数:3
I2C串行总线的组成及工作原理I2C是一种常用的串行通信协议,用于在电子设备之间进行数据传输。
它的全称是Inter-Integrated Circuit,即片间串行总线。
1. 主设备(Master Device):负责发起通信请求并控制整个传输过程的设备。
主设备通常是微控制器、处理器或其他智能设备。
2. 从设备(Slave Device):被主设备控制的设备。
从设备可以是各种外围设备,如传感器、存储器、显示器等。
3. SDA(Serial Data Line):用于数据传输的双向串行数据线。
主设备和从设备都可以发送和接收数据。
4. SCL(Serial Clock Line):用于同步数据传输的时钟线。
主设备产生时钟信号来同步数据传输。
5. VCC(Supply Voltage):提供电源电压给I2C总线上的设备。
6. GND(Ground):提供共地连接。
I2C总线的工作原理如下:1.初始化:主设备发起一次总线初始化,在I2C总线上产生一个启动信号。
启动信号表示I2C总线上有新的数据传输将开始。
2.寻址:主设备发送一个7位的设备地址到总线上指定要与之通信的从设备。
I2C总线上可以存在多个从设备,每个设备都有唯一的地址。
3.数据传输:主设备发送数据或者命令到从设备,或者从设备向主设备发送数据回复。
数据通过SDA线传输,时钟通过SCL线提供。
4.确认(ACK):数据传输完成后,每个接收设备都会回复一个确认信号,表示它已经成功接收数据。
主设备和从设备都可以发送确认信号。
5.停止:主设备发送一个停止信号来结束一次数据传输过程。
停止信号表示I2C总线上没有更多的数据传输。
I2C总线的工作原理是基于主从结构的,主设备控制数据传输的流程。
主设备通过发送启动信号来开始一个数据传输过程,并通过发送设备地址和数据来与特定的从设备进行通信。
通过SCL线的时钟同步,主设备和从设备可以准确地进行数据传输,避免了数据丢失和冲突。
I2C串行总线工作原理及应用I2C(Inter-Integrated Circuit)是一种串行总线协议,用于连接芯片和外设,允许它们之间进行通信和数据交换。
I2C总线由飞利浦公司(现在的恩智浦半导体)于1980年代初引入,是一种简单、高效、可扩展的通信协议。
I2C总线由两根信号线组成,分别是SCL(串行时钟线)和SDA(串行数据线),可以连接多个设备,每个设备都有一个唯一的地址,设备之间可以通过发送和接收数据来进行通信。
I2C总线的工作原理如下:1.主从模式:在I2C总线上,一个设备必须充当主设备,其他设备充当从设备。
主设备负责生成时钟信号和控制整个通信流程,从设备只能在主设备允许时传输数据。
2.起始和停止条件:通信开始时,主设备会发送一个起始条件来指示数据的传输开始。
而通信结束时,主设备会发送一个停止条件来指示数据的传输结束。
3.传输过程:在传输数据之前,主设备首先会发送一个地址码来指定要通信的从设备。
然后,主设备将数据传输到从设备(写操作)或从设备将数据传输给主设备(读操作)。
每个数据字节都会被从设备确认,并继续传输下一个数据字节。
4.时钟和数据线:SCL线用于同步数据传输的时钟信号,SDA线用于传输实际的数据。
数据传输是按字节进行的,每个字节有8个位,其中第一个位是数据位,后面的7个位是地址位或数据位。
I2C总线的应用非常广泛,包括但不限于以下几个方面:1.传感器:I2C总线可以用于将传感器连接到主控芯片。
例如,温度传感器、湿度传感器、光照传感器等可以通过I2C总线传输采集到的数据给主控芯片进行处理和分析。
2. 存储器:I2C总线可以连接EEPROM(Electrically Erasable Programmable Read-Only Memory)和其他类型的存储器芯片,用于存储数据和程序。
主控芯片可以通过I2C总线读取和写入存储器中的数据。
3.显示器:一些液晶显示器和OLED显示器可以通过I2C总线与主控芯片进行通信。
I2C 【2 】总线入门1)比来进修51单片机,学到A/D,D/A转换的时刻发明我板子上的转换芯片不是书上所讲的ADC0804和DAC0832而是PCF8591T,看了一下它的数据手册,发明它并不是书上所说的并行传输数据,是应用 I2C 总线传输的.搞了两天才搞懂,写出来给大家分享一下,不足之处请务必不吝指出.以上是I2C总线的简略介绍.就比如说AT24C02存储芯片,和PCF8591数模模数转换芯片都支撑I2C端口.(如下图)2)接下来看若何应用I2C总线进行通讯以上是I2C总线通讯的格局.由上图可以看出进行通讯须要以下几个步骤a.初始化I2C总线就是把SDA和SCL都变成高电平.void init()//初始化{SDA=1;delay();SCL=1;delay();}delay()为延时函数void delay()//延时4-5个微秒{;;}b.发送肇端旌旗灯号就是保持SCL为高电平,而SDA从高电平降为低电平(这是I2C总线的划定,别问我为什么)void start()//肇端旌旗灯号{SDA=1;delay();SCL=1;delay();SDA=0;delay();}c.发送地址字(芯片的硬件地址)(8591的数据手册)前四位对统一种芯片来说是固定的,不同的芯片之间不同.就像pcf8591是1001而at24c02是1010接下来三位A0,A1,A2是可编程的三个地址位,这里说说的编程并不是经由过程软件编程,而是把A0,A1,A2三个引脚接不同的电压来肯定命值.接VCC表示1,接GND表示0.为什么要有这三个呢?因为有可能你在I2C总线上“并联”了不止一个雷同的元件(比如说接了三个8591),那你若何来分辩你要操作的是哪一个芯片呢,就是经由过程设置A0,A1,A2的数值,来差别.可编程的地址一个有三位,也就是说最多可以接8个雷同的芯片在统一个I2C总线上.最后一位是读/写位,1为读,0为写.@若何写数据写数据只须要按照时序图1.先将SCL置0(只有它为0的时刻SDA才许可变化)2.转变SDA是数值(就是你当前要穿的一位是0照样1)3.把SCL置1(此时芯片就会读取总线上的数据)下面是代码#define uchar unsigned char#define uint unsigned intvoid write_byte(uchar date)//写一字节数据{uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;//左移一位移出的一位在CY中SCL=0;//只有在scl=0时sda能变化值delay();SDA=CY;delay();SCL=1;delay();}SCL=0;delay();SDA=1;delay();}发送地址的时刻只需把地址传给该函数即可.d.应答(ACK)每接收或发送一字节数据后都须要发送一位应答,来表是否收到了前面一个字节的数据.void respons()//应答相当于一个智能的延时函数{uchar i;SCL=1;delay();while((SDA==1)&&(i<250))//充公到应答,我等!~~i++;//等了250次充公到就不管他了,就当他收到了-_-//其实充公到的话可以停滞程序的SCL=0;delay();}e.发送/接收数据(取决于前面地址字的最后一位读/写位)发送数据和上面的发送地址挪用统一个函数,只要穿给他数据即可.吸收数据其实和发送数据差不多,只不过要把吸收到的数据一位一位拼装成一字节数据,看代码~uchar read_byte(){uchar i,k;SCL=0;delay();SDA=1;delay();for(i=0;i<8;i++){SCL=1;delay();k=(k<<1)|SDA;//先左移一位,再在最低位接收当前位SCL=0;delay();}return k;}f.应答g.·······如斯轮回,直到数据一个字一个字的发完h.发送终止旌旗灯号就是SCL在高电平的时刻SDA由低电平变成高电平void stop()//停滞旌旗灯号{SDA=0;delay();SCL=1;delay();SDA=1;delay();}以上就是全部数据传输的进程了为了更好的控制I2C总线我在此放两个例子,一个是书上(郭天祥的,你们懂的)EPROM存储准不时光的例子,还有就是用PCF8591进行D/A转换的例子.1.EPROM存储准不时光//JP10(P0)接JP12//我发明数据手册(电路图pdf)上错了 SCL连的是P2^1 而SDA连的P2^0//程序功效:在数码管上显示数字,每隔1s增长1//但是每次复位或者失落电程序都邑把当前数值存储到AT24C02中,并鄙人次启动时读取#include <reg51.h>#define uchar unsigned char#define uint unsigned intbit write=0;//写24c02的标志sbit SCL=P2^1; //串行时钟输入端sbit SDA=P2^0; //串行数据输入端sbit LS138A=P2^2;//138译码器的3位控制数码管的sbit LS138B=P2^3;sbit LS138C=P2^4;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数显管字模uchar second,tempt;//second用来计秒数 ,tempt用光降时存放0.05s的次数满20即1s写入void delay()//延时4-5个微秒{;;}void delay_1ms(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void start()//肇端旌旗灯号{SDA=1;delay();SCL=1;delay();SDA=0;delay();}void stop()//停滞旌旗灯号{SDA=0;delay();SCL=1;delay();SDA=1;delay();}void respons()//应答相当于一个智能的延时函数{uchar i;SCL=1;delay();while((SDA==1)&&(i<250))//充公到应答,我等!~~i++;//等了250次充公到就不管他了,就当他收到了-_- //其实充公到的话可以停滞程序的SCL=0;delay();}void init()//初始化{SDA=1;delay();SCL=1;}void write_byte(uchar date)//写一字节数据{uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;//左移一位移出的一位在CY中SCL=0;//只有在scl=0时sda能变化值delay();SDA=CY;delay();SCL=1;delay();}SCL=0;delay();SDA=1;delay();}uchar read_byte(){uchar i,k;SCL=0;SDA=1;delay();for(i=0;i<8;i++){SCL=1;delay();k=(k<<1)|SDA;//先左移一位,再在最低位接收当前位SCL=0;delay();}return k;}void write_add(uchar address,uchar date){start();write_byte(0xa0);//10100000 前四位固定接下来三位全体被接地了所以都是0 最后一位是写所认为低电平respons();write_byte(address);respons();write_byte(date);respons();stop();}uchar read_add(uchar address) {uchar date;start();write_byte(0xa0);respons();write_byte(address);respons();start();write_byte(0xa1);respons();date=read_byte();stop();return date;}void display(uchar ge,uchar shi) {P0=0xff;LS138A=0;//第一位LS138B=0;LS138C=0;P0=table[ge];delay_1ms(5);P0=0xff;LS138A=1;//第二位LS138B=0;LS138C=0;P0=table[shi];delay_1ms(5);P0=0xff;}void main(){init();second=read_add(2);//读出保存的数据if(second>=100)second=0;TMOD=0x01;//准时器工作方法1ET0=1;EA=1;TH0=(65536-50000)/256;TL0=(65536-50000)%256;TR0=1;//开端计时while(1){display(second/10,second%10);if(write==1){write=0;write_add(2,second);}}}void t0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;tempt++;if(tempt==20){tempt=0;second++;write=1;if(second==100)second=0;}}这是电路图为了更好的控制I2C总线我在此放两个例子,一个是书上(郭天祥的,你们懂的)EPROM存储准不时光的例子,还有就是用PCF8591进行D/A转换的例子.1.EPROM存储准不时光//I2C总线很壮大//程序功效:经由过程DA转换把输出电压逐渐增大,使加在上面的发光二级管慢慢变亮// 到最亮后再变暗,如斯轮回#include <reg51.h>#define uchar unsigned char#define uint unsigned int#define PCF8591 0x90 //PCF8591 地址sbit SCL=P2^1; //串行时钟输入端sbit SDA=P2^0; //串行数据输入端void delay()//延时4-5个微秒{;;}void delay_1ms(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void start()//开端旌旗灯号{SDA=1;delay();SCL=1;delay();SDA=0;delay();}void stop()//停滞旌旗灯号{SDA=0;delay();SCL=1;delay();SDA=1;delay();}void respons()//应答相当于一个智能的延时函数{uchar i;SCL=1;delay();while((SDA==1)&&(i<250))i++;SCL=0;delay();}void init()//初始化{SDA=1;delay();SCL=1;delay();}void write_byte(uchar date)//写一字节数据{uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;//左移一位移出的一位在CY中SCL=0;//只有在scl=0时sda能变化值delay();SDA=CY;delay();SCL=1;delay();}SCL=0;delay();SDA=1;delay();}void write_add(uchar control,uchar date){start();write_byte(PCF8591);//10010000 前四位固定接下来三位全体被接地了所以都是0 最后一位是写所认为低电平respons();write_byte(control);respons();write_byte(date);respons();stop();}void main(){uchar a;init();while(1){write_add(0x40,a);delay_1ms(5);a++;if(a>250)a=0;}}第21页,-共21页。
I2C总线原理及应用实例I2C总线是一种串行通信总线,全称为Inter-Integrated Circuit,是Philips(飞利浦)公司在1982年推出的一种通信协议。
它可以用于连接各种集成电路(Integrated Circuits,ICs),如处理器、传感器、存储器等。
I2C总线的原理是基于主从架构。
主设备(Master)负责生成时钟信号,并发送和接收数据,从设备(Slave)通过地址识别和响应主设备的命令。
I2C总线使用两根线来传输数据,一根是时钟线(SCL),用于主设备生成的时钟信号;另一根是数据线(SDA),用于双向传输数据。
1. 主设备发送起始位(Start)信号,将SDA线从高电平拉低;然后通过SCL线发送时钟信号,用于同步通信。
2.主设备发送从设备的地址,从设备通过地址识别确定是否响应。
3.主设备发送要传输的数据到从设备,从设备响应确认信号。
4. 主设备可以继续发送数据,或者发送停止位(Stop)信号结束通信。
停止位是将SDA线从低电平拉高。
1.温度监测器:I2C总线可以连接到温度传感器上,通过读取传感器的输出数据,进行温度的监测和控制。
主设备可以设置警报阈值,当温度超过阈值时,可以触发相应的措施。
2.显示屏:很多智能设备上的显示屏都采用了I2C总线,如液晶显示屏(LCD)或有机发光二极管(OLED)等。
主设备通过I2C总线发送要显示的信息,并控制显示效果,如亮度、对比度、清晰度等参数。
3.扩展存储器:I2C总线可以用于连接外部存储器,如电子存储器(EEPROM)。
通过I2C总线,可以读取和写入存储器中的数据,实现数据的存储和传输。
4.触摸屏控制器:许多触摸屏控制器也使用了I2C总线,主要用于将触摸信号传输给主设备,并接收主设备的命令。
通过I2C总线,可以实现对触摸屏的操作,如单击、滑动、缩放等。
5.电源管理器:一些电源管理器也采用了I2C总线,用于控制和监测电池电量、充电状态、电压、电流等参数。
I2C串行总线工作原理及应用I2C(Inter-Integrated Circuit)是一种串行总线通信协议,用于在数字系统之间传输数据。
它由飞利浦公司开发,用于连接微控制器、存储器和外围设备等数字电子设备。
I2C总线是一种非常常见的通信协议,被广泛应用于许多领域,包括消费电子、通信、工业自动化和汽车电子等。
I2C总线的工作原理是基于主从架构。
其中一个设备担任主机角色,控制总线的操作和数据传输。
其他设备则是从设备,等待主机的指令,并按照指令执行相应的操作。
总线上可以连接多个从设备,每个设备都有一个唯一的7位或10位地址,主机通过这个地址来选择要与之通信的从设备。
I2C总线是串行通信的,使用两根数据线:Serial Data Line(SDA)和Serial Clock Line(SCL)。
SDA用于传输数据,SCL用于传输时钟信号。
在每个时钟周期,主机通过变动SCL线上的电平来同步通信,而SDA线的电平表示数据位。
总线上的每个设备都必须能够感知和响应这些时钟信号,并在正确的时机进行数据传输。
I2C总线还有两种常见的模式:主模式和从模式。
主模式由主机设备控制,通常用于发起读写操作。
从模式由其他设备控制,用于响应读写操作。
主模式下,主机发送一个启动信号(Start),然后发送目标设备的地址(包括读/写位),设备响应后进行数据传输。
传输完成后,主机发送一个停止信号(Stop),结束通信。
从模式下,从设备等待主机的启动信号和地址,然后响应主机的读写操作。
I2C总线的应用广泛。
以下是一些常见的应用领域:1.消费电子产品:例如智能手机、电视、音频设备等都使用I2C总线连接不同的模块和传感器。
例如,智能手机使用I2C连接触摸屏、陀螺仪和环境传感器等多个外围设备。
2.工业自动化:I2C总线被用于连接传感器和执行器到PLC(可编程逻辑控制器)或其他控制系统。
通过I2C总线,传感器可以实时将数据传输给控制系统,并控制执行器的动作。
一. I2C总线简介I2C管理总线:(Intel-Integrated Circuit bus)I2C总线是一种由飞利浦Philip公司开发的串行总线,产生于80年代,最初为音频和视频设备开发,现主要在服务器管理中使用。
是两条串行的总线,它由一根数据线(SDA)和一根时钟线(SDL)组成。
◆I2C总线的数据传输过程基本过程为:●主机发出开始信号。
●主机接着送出1字节的从机地址信息,其中最低位为读写控制码(1为读、0为写),高7位为从机器件地址代码。
●从机发出认可信号。
●主机开始发送信息,每发完一字节后,从机发出认可信号给主机。
●主机发出停止信号。
I2C数据传输图◆I2C总线上各信号的具体说明:●开始信号:在时钟线(SCL)为高电平其间,数据线(SDA)由高变低,将产生一个开始信号。
●停止信号:在时钟线(SCL)为高电平其间,数据线(SDA)由低变高,将产生一个停止信号。
●应答信号:既认可信号,主机写从机时每写完一字节,如果正确从机将在下一个时钟周期将数据线(SDA)拉低,以告诉主机操作有效。
在主机读从机时正确读完一字节后,主机在下一个时钟周期同样也要将数据线(S DA)拉低,发出认可信号,告诉从机所发数据已经收妥。
(注:读从机时主机在最后1字节数据接收完以后不发应答,直接发停止信号)。
注意:在I2C通信过程中,所有的数据改变都必须在时钟线SCL为低电平时改变,在时钟线SCL为高电平时必须保持数据SDA信号的稳定,任何在时钟线为高电平时数据线上的电平改变都被认为是起始或停止信号。
◆I2C总线数据格式:I2C数据格式图I2C支持两种数据格式:_ 7-bit/10-bit 寻址数据格式_ 7-bit/10-bit 寻址和重复开始信号的数据格式✧S ―I2C 开始标识✧Slava address ―从设备地址。
有两种从地址类型:1)固定的从地址,I2C总线只能接一个同类型的固定的从地址设备。
2)半固定的从地址,前半部分地址是固定的,后半部分地址是可编程的,I2C总线只能接多个同类型的半固定的从地址设备。
i2c 总线协议的工作原理详解一、概述1、I2C 总线只有两根双向信号线。
一根是数据线SDA,另一根是时钟线SCL。
SCL:上升沿将数据输入到每个EEPROM 器件中;下降沿驱动EEPROM 器件输出数据。
(边沿触发)SDA:双向数据线,为OD 门,与其它任意数量的OD 与OC 门成\ 线与\关系。
I2C 总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平(SDL=1;SCL=1)。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA 及SCL 都是线与关系。
2、主设备与从设备系统中的所有外围器件都具有一个7 位的\从器件专用地址码\,其中高4 位为器件类型,由生产厂家制定,低3 位为器件引脚定义地址,由使用者定义。
主控器件通过地址码建立多机通信的机制,因此I2C 总线省去了外围器件的片选线,这样无论总线上挂接多少个器件,其系统仍然为简约的二线结构。
终端挂载在总线上,有主端和从端之分,主端必须是带有CPU 的逻辑模块,在同一总线上同一时刻使能有一个主端,可以有多个从端,从端的数量受地址空间和总线的最大电容400pF 的限制。
主端主要用来驱动SCL line;从设备对主设备产生响应;二者都可以传输数据,但是从设备不能发起传输,且传输是受到主设备控制的。
二、协议1.空闲状态I2C 总线总线的SDA 和SCL 两条信号线同时处于高电平时,规定为总线的空闲状态。
此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。
2.起始位与停止位的定义:起始信号:当SCL 为高期间,SDA 由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。
停止信号:当SCL 为高期间,SDA 由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。
起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。
I2C总线入门1)最近学习51单片机,学到A/DQ/A转换的时候发现我板子上的转换芯片不是书上所讲的ADC0804和DAC0832而是PCF859仃,看了一下它的数据手册, 发现它并不是书上所说的并行传输数据,是使用I2C总线传输的。
搞了两天才搞懂,写出来给大家分享一下,不足之处请务必不吝指出。
! ≡tt f Itiief II R J Ih PHiLlPSt j ΓC bFC 口対由⅞⅛⅞κΓt r SDA IUB L f W r■I. SeiL閃離找L#參G [⅛总蠻H件嗣时Mtfl ι⅛X⅛ttStM'QUIA ft/i CPU 1√ Kf?IC ZlHh IC J J Ie Z糾幣町遊i;I^I ILW*s4t∣ιIkh i P"⅛.BtflK硏是Jl伯的内评.iaiT IT K以上是I2C总线的简单介绍。
就比如说AT24C02存储芯片,和PCF8591数模模数转换芯片都支持I2C端口(如下图)2)接下来看如何使用I2C总线进行通信3. I S C总线通信格式图8,i+2 ⅛ PC总统上进彳J -次数撫传输的通信格式HJ. λ5WuJΓ IMPuJT λWλ√[T+ *1⅛∕'f ⅛ff融戟代答ftK >⅛祎:J*j*hrn⅛释止他号图S.I .2 I3C总纽上遊打谀散据传输的JfflG⅛A 以上是I2C 总线通信的格式。
由上图可以看出进行通信需要以下几个步骤S-Iead PDlPAOL1 8□ VCCAl匚⅛WPA2匚3GND匚4£AJNOITU迴VDDAINlI 2ISj AOUTAIN2 3]回” RE FAIN3 I 41^I3] AGNDPCF8591PAO ^5∏^↑2∖ EXTAt叵TrlOSCA2 T/JO)SeL^kVSS叵(VJ SDAIH2引脚图(Dlla.初始化I2C总线就是把SDA和SCL都变成高电平。
Void in it() 〃初始化{SDA=1;delay();SCL=1;delay();}delay ()为延时函数void delay() 〃延时4-5个微秒{;;}b.发送起始信号就是保持SCL为高电平,而SDA从高电平降为低电平(这是I2C总线的规定, 别问我为什么)void Start()// 起始信号{SDA=1;delay();SCL=1;delay();SDA=0;delay();}C.发送地址字(芯片的硬件地址)74地址12C总线象统中的每一片PCF859J通过发送有效地址封该黠件来激活。
I2C总线协议及工作原理I2C(Inter-Integrated Circuit)是一种串行通信总线协议,由Philips公司提出,适用于在电路板上连接各种集成电路的短距离通信。
I2C总线协议的工作原理是基于主从结构的,其中一个设备作为主设备,其他设备作为从设备。
主设备负责发起通信操作,而从设备则被动响应主设备的指令。
主设备在总线上发出启动信号,然后发送器件地址。
发起通信的主设备控制总线的速度和时序,并且主设备确定读写的类型。
从设备根据地址进行匹配,并根据主设备请求的读写进行响应。
通信完成后,主设备会发送停止信号释放总线。
在I2C总线上,每个设备都有一个唯一的7位或10位地址。
主设备在传输数据之前,会发送起始信号,这个信号告诉从设备通信即将开始。
随后主设备会发送一个地址字节,包含了要通信的从设备的地址和读写控制位。
如果从设备的地址和发送的地址匹配,从设备会发送一个应答(ACK)信号,表示准备好接收数据。
主设备然后才开始发送或接收数据。
数据在I2C总线上传输是以字节为单位的,并且每个字节之后都会有一个应答信号。
主设备负责设置时钟线的电平来控制数据的传输,而从设备负责读取或发送数据位。
在读取数据时,主设备会发送应答位,如果从设备准备好读取下一个字节,会发送应答信号;反之,如果从设备不准备好,会发送非应答信号。
在I2C总线上,主设备还可以使用多主模式,允许多个主设备操作相同的总线。
当多个主设备在通信总线上发起通信时,总线的冲突可能会发生。
为了解决这个问题,I2C总线使用了仲裁机制。
仲裁机制根据优先级决定那个设备能够继续发送数据,优先级高的设备可以中断优先级低的设备的传输,从而保证通信的顺利进行。
总结起来,I2C总线协议是一种简单、高效的串行通信协议。
它通过两根线实现设备之间的通信,并且支持多主模式。
它的工作原理是基于主从结构,主设备发起通信,从设备被动响应。
通过仲裁机制,解决了多主模式下的冲突问题。
<学习笔记>花点时间让你彻底搞懂I2C总线
前言
经常在论坛上看到有网友在咨询I2C的问题,这里就I2C总线做一个给比较全面的总结,感兴趣的网友可以耐心的看下去,相信对你会有帮助。
【1. 基础知识】
1.1. 关于口线电平
在I2C总线中有2个口线,SDA和SCL。
这两个口线对为OC输出。
什么是OC呢?相对OC还有什么输出呢?
OC就是开漏输出(Open Collector)的简称,有时候也叫OD输出(Open-Drain),OD是对mos管而言,OC是对双极型管而言,在用法上没啥区别。
相对于OC输出,另一种输出叫推挽输出(Push-Pull),一般的MCU管脚输出可以设置这两种模式。
这里分别介绍下这两种输出的不同点。
推挽输出:可以输出高、低电平连接数字器件,推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止.
开漏输出: 输出端相当于三极管的集电极未接任何电平,要得到高电平状态需要上拉电阻才行,适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。
对于MCU的开发者来讲,简单的这样理解就可以了。
如果管脚设置成推挽输出模式,输出高时,IO口相当于VCC, 输出低时IO口相当于接地。
如果管脚设置成开漏输出模式,输出高时,IO口的电平会和与其相连的口线进行与操作,如果都为高,才会被上拉拉成高电平,输出为低时,也相当于接地。
I2C总线要实现线与的功能,所以SDA和SCL口线都必须设置为开漏输出模式。
我们使用MCU的硬件I2C接口时,口线会被自动设置成开漏。
但有时候我们会使用IO口来模拟I2C 总线,这个时候我们如何设置口线呢?
这里要分两种情况,如果MCU的口线支持开漏输出模式,则可以直接把SDA和SCL 设置成开漏输出。
例如Silicon 的C8051系列MCU,它的口线就支持开漏和推挽输出。
如果MCU不支持开漏输出那怎么办呢?例如MSP430。
在网上我们看到很多的例程代码都是直接设置IO口的高低电平,这样做其实是不太合理的。
因为我们只满足了I2C总线在自己这端的时序要求。
而没有考虑到连接在总线上的其他器件。
如果总线上其他器件的电平和MCU输出的电平一致,这样做是没问题的,如果两边的电平不一致时,这样做就有一定风险造成IO 的损坏。
当你输出高时,相当于IO口连接到VCC,如果对方这是恰好输出的是低电平,那就相当于短路了。
当然如果软件做的合理,是可以避免这样的事情的,但总线上的很多器件都不是由你能控制的,如何设计出更合理的软件来避免这样的问题发生呢?
对于不支持开漏输出MCU,我们最合理的做法是,当设置口线电平为高时,我们把口线设置成输入状态,然后利用口线上的上拉电阻来把口线拉高。
这样即使是两边电平不一致时,也不会造成IO口的损坏。
1.2. 关于总线口线
大家都知道I2C是由SDA、SCL两个口线组成的。
这两个口线的高低电平组合、上升下降边沿组合就形成了总线的各种时序。
这里我们先做一个枚举,看下两个口线能组合出什么样的时序出来。
上表中灰色部分不是I2C总线关心的,9,10分别被定义为I2C的START和STOP信号。
I2C数据总线SDA是在时钟为高时有效,在时钟SCL为高期间,SDA如果发生了电平变化就会终止或重启I2C中线,所以我们在数据传输过程中,要在SCL为低的时候去更改SDA 的电平。
1.3. 关于I2C总线的时序
在上一节中我讲到了由SDA和SCL能形成的各种电平组合,那么这些组合如何在I2C 总线上得到应用的呢?
在这一节,我们一步一步的来分析I2C总线的逻辑时序。
首先是I2C的START信号。
START信号是在SCL位高电平时,SDA从高电平变成低电平。
大家想一下为什么是这样设计呢?
这个和I2C的多主性能有一定关系。
因为I2C的总线是开漏输出的,总线上接上上拉电阻后,SCL和SDA就变成了高电平,这个时候挂接在总线上的任意一个I2C主机口可以把SDA拉低,即产生了一个START信号,挂接在总线上的其他I2C主机检测到这个信号后就不能去操作I2C总线了,否则会发生冲突。
直到检测到一个STOP信号为止。
STOP的信号是在SCL口线为高时,SDA产生一个上升沿。
STOP信号之后,I2C总线恢复到初始状态
那么这两个时序如何在在我们软件中实现呢? 这里我以MSP430为例,探讨下如何合理的实现这样的代码. 首先,我们需要把SDA和SCL的口线都设置成输入模式(前面讲了为什么),当口线设置成输入模式时,PXOUT寄存器的值是用来设置口线是上拉还是下拉,PXOUT 需要设置成上拉。
(想一下为什么?)因为如果你设置成下拉的话,一般I2C的总线会接2个上拉电阻,就相当于总线上是图1的等效电路。
当我们设置为口线为输入时,口线的高电平就不会是VCC,而是一个分压后的电平。