I2C总线入门(很详细-很经典)
- 格式:doc
- 大小:470.50 KB
- 文档页数:16
【转】I2C总线相关知识1. I2C access1.1. I2C introductionI2C(Inter-Integrated Circuit)总线是由NXP恩智浦半导体公司在80年代开发的两线式串⾏总线,⽤来进⾏主控器与被控器的通信。
I2C总线具有接⼝线少,控制⽅式简单,器件封装形式⼩,通信速率较⾼等优点,是微电⼦通信控制领域⼴泛采⽤的⼀种总线标准。
I2C总线由两根信号线构成,⼀根是串⾏数据线SDA,⼀根是串⾏时钟线SCL,这两根信号线都是双向的,SDA的传输与SCL同步。
Figure 1中,连接到总线的器件为漏极开路输出结构,各器件之间执⾏线与的功能。
当总线空闲时,SDA和SCL必须接上拉电阻⾄⾼电平来省电。
串⾏的8 位双向数据传输位速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,⾼速模式下可达3.4Mbit/s。
I2C总线上可同时挂接多个器件,器件之间靠不同的编址来进⾏区分,每个连接到总线上的期间都可以通过唯⼀的地址与主机进⾏通信。
由于I2C是双向传输的总线,每个器件都可能成为主机(发送器)或者从机(接收器),时钟信号SCL由主机产⽣。
Figure 1 开漏输出RLXXXA⽀持⼀组I2C接⼝,I2C ⼯作在master mode情况下可完成上电后EEPROM auto-download动作。
⽽I2C⼯作在Slave mode时⽀持external CPU通过I2C access internal Switch core register.Figure 2 RLXXXA的I2C总线如果external cpu访问I2C,同时internal 8051通过I2C access eeprom,此时内部会错开,前者优先做动作。
1.2. I2C Transferring Data数据的有效性:SDA 线上的数据必须在时钟的⾼电平周期保持稳定。
只有在SCL 线的时钟信号为低电平时,才允许数据线的电平改变状态。
I2C总线简介1.概述:I²C是Inter-Integrated Circuit的缩写,发音为"eye-squared cee" or"eye-two-cee", 它是一种两线接口。
I²C 只是用两条双向的线,一条 Serial Data Line (SDA) ,另一条Serial Clock (SCL)。
SCL:上升沿将数据输入到每个EEPROM器件中;下降沿驱动EEPROM器件输出数据。
(边沿触发)SDA:双向数据线,为OD门,与其它任意数量的OD与OC门成"线与"关系。
2.输出级每一个I2C总线器件内部的SDA、SCL引脚电路结构都是一样的,引脚的输出驱动与输入缓冲连在一起。
其中输出为漏极开路的场效应管,输入缓冲为一只高输入阻抗的同相器,这种电路具有两个特点:1)由于SDA、SCL为漏极开路结构(OD),因此它们必须接有上拉电阻,阻值的大小常为1k8, 4k7 and 10k ,但1k8 时性能最好;当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线"与"关系。
2)引脚在输出信号的同时还将引脚上的电平进行检测,检测是否与刚才输出一致,为"时钟同步"和"总线仲裁"提供了硬件基础。
3.主设备与从设备系统中的所有外围器件都具有一个7位的"从器件专用地址码",其中高4位为器件类型,由生产厂家制定,低3位为器件引脚定义地址,由使用者定义。
主控器件通过地址码建立多机通信的机制,因此I2C总线省去了外围器件的片选线,这样无论总线上挂接多少个器件,其系统仍然为简约的二线结构。
终端挂载在总线上,有主端和从端之分,主端必须是带有CPU的逻辑模块,在同一总线上同一时刻使能有一个主端,可以有多个从端,从端的数量受地址空间和总线的最大电容 400pF的限制。
I2C总线基础知识1. 口线电平1.1 口线电平输出方式在I2C总线中有2个口线:SDA和SCL,这两个口线均为OC输出。
OC就是开漏输出(Open Collector)的简称,有时候也叫OD输出(Open-Drain),OD是对MOS管而言,OC是对双极型管而言,在用法上没什么区别。
相对于OC输出,另一种输出叫推挽输出(Push-Pull),一般的MCU管脚输出可以设置这两种模式。
这里分别介绍下这两种输出模式的不同点。
推挽输出 : 可以输出高、低电平连接数字器件,推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。
开漏输出 : 输出端相当于三极管的集电极未接任何电平,要得到高电平状态需要上拉电阻才行,适合于做电流型的驱动,其吸收电流的能力相对强(一般20mA以内)。
对于MCU的开发者来讲,简单的这样理解就可以了。
如果管脚设置成推挽输出模式,输出高时,IO口相当于VCC, 输出低时IO口相当于接地。
如果管脚设置成开漏输出模式,输出高时,IO口的电平会和与其相连的口线进行与操作,如果都为高,才会被上拉成高电平,输出为低时,也相当于接地。
1.2 口线设置I2C总线要实现线与的功能,所以SDA和SCL口线都必须设置为开漏输出模式。
我们使用MCU的硬件I2C接口时,口线会被自动设置成开漏。
但有时候我们会使用IO口来模拟I2C总线,这个时候设置口线要分两种情况:(1)MCU的口线支持开漏输出模式:可以直接把SDA和SCL设置成开漏输出。
例如Silicon 的C8051系列MCU,它的口线就支持开漏和推挽输出。
(2)MCU的口线不支持开漏输出(例如MSP430):在网上我们看到很多的例程代码都是直接设置IO口的高低电平,这样做其实是不太合理的。
因为我们只满足了I2C总线在自己这端的时序要求,而没有考虑到连接在总线上的其他器件,如果总线上其他器件的电平和MCU输出的电平一致,这样做是没问题的,如果两边的电平不一致时,这样做就有一定风险造成IO的损坏。
一. 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总线只能接多个同类型的半固定的从地址设备。
1 I2C总体介绍I2C总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
是微电子通信控制领域广泛采用的一种总线标准。
它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。
I2C总线的一些特征•只要求两条总线线路一条串行数据线SDA一条串行时钟线SCL。
由于连接到I2C总线的器件有不同种类的工艺(CMOS、NMOS、双极性)逻辑0(低)和1(高)的电平不是固定的。
它由VDD 的相关电平决定,每传输一个数据位就产生一个时钟脉冲。
•每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机从机关系软件设定地址,主机可以作为主机发送器或主机接收器。
主机是初始化总线的数据传输并产生允许传输的时钟信号的器件,此时任何被寻址的器件都被认为是从机。
• I2C是一个真正的多主机总线,如果两个或多个主机尝试发送信息到总线,在其他主机都产生0的情况下首先产生一个1的主机将丢失仲裁,仲裁时的时钟信号是用线与连接到SCL线的主机产生的时钟的同步结合。
在I2C 总线上产生时钟信号通常是主机器件的责任。
当在总线上传输数据时,每个主机产生自己的时钟信号。
主机发出的总线时钟信号只有在以下的情况才能被改变:慢速的从机器件控制时钟线并延长时钟信号;在发生仲裁时被另一个主机改变。
• SDA和SCL都是双向线路,都通过一个电流源或上拉电阻连接到正的电源电压。
当总线空闲时这两条线路都是高电平,连接到总线的器件输出级必须是漏极开路或集电极开路才能执行线与的功能。
串行的8位双向数据传输位速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s。
•片上的滤波器可以滤去总线数据线上的毛刺波保证数据完整•连接到相同总线的IC数量只受到总线的最大电容400pF限制2I2C数据传输2.1I2C数据的有效性SDA线上的数据必须在时钟的高电平周期保持稳定,数据线的高或低电平状态只有在SCL 线的时钟信号是低电平时才能改变。
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总线1.简介I2C(Inter-IC)总线10多年前由Philips公司推出,是近年来在微电子通信控制领域广泛采用的一种新型总线标准。
它是同步通信的一种特殊形式,具有接口线少,控制方式简化,器件封装形式小,通信速率较高等优点。
在主从通信中,可以有多个I2C总线器件同时接到I2C总线上,通过地址来识别通信对象。
2.I²C 总线术语发送端 - 发送数据到总线的器件。
当发送端器件可以主动将数据放到总线,我们称为主控发送端,若可以回应主控端的要求,即称为从属发送端。
接收端- 接收来自总线传输数据的器件。
当接收端器件可以主动接收数据时,我们称为主控接收端,若依照主控端要求而接收,称为从属接收端。
主控端 - 为启动数据传送 (START 指令)、产生时钟 (SCL) 信号并中止数据传送 (STOP指令) 的器件,主控端必须是传送端或接收端。
从属端 - 由主控端定址的器件。
从属端可以扮演接收端或发送端的角色。
多重主控端 - 在总线上可同时存一个以上的主控端,并且不会造成冲突或数据遗失。
通常来说运用 "bit-banged" 软件的主控端并不具有多重主控端能力,I²C 总线控制器提供了一个将多重主控端硬件 I²C 连接端口加入到 DSP 或 ASIC 的简单方法。
仲裁机制- 预先定义在特定时间内只有一个主控端能够取得总线控制权。
同步 - 预先将二个或二个以上的主控端时钟信号予以同步化的定义程序。
SDA- 串行数据信号线 (Serial Data)SCL - 串行时钟信号线 (Serial Clock)3.I2C总线结构I2C 总线上数据的传输速率在标准模式下可达100kbit/s,在快速模式下可达400kbit/s,在高速模式下可达3.4Mbit/s。
I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。
所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。
I2C总线入门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();}发送地址的时候只需把地址传给该函数即可。
I2C总线入门1)最近学习51单片机,学到A/D,D/A转换的时候发现我板子上的转换芯片不是书上所讲的ADC0804和DAC0832而是PCF8591T,看了一下它的数据手册,发现它并不是书上所说的并行传输数据,是使用 I2C 总线传输的。
搞了两天才搞懂,写出来给大家分享一下,不足之处请务必不吝指出。
以上是I2C总线的简单介绍。
就比如说AT24C02存储芯片,和PCF8591数模模数转换芯片都支持I2C端口。
(如下图)2)接下来看如何使用I2C总线进行通信以上是I2C总线通信的格式。
由上图可以看出进行通信需要以下几个步骤a.初始化I2C总线就是把SDA和SCL都变成高电平。
void init() //初始化{S DA=1;d elay();S CL=1;d elay();}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();}发送地址的时候只需把地址传给该函数即可。
I2C总线规范详细介绍一、I2C 总线术语的定义术语描述发送器发送数据到总线的器件接收器从总线接收数据的器件主机初始化发送产生时钟信号和终止发送的器件从机被主机寻址的器件多主机同时有多于一个主机尝试控制总线但不破坏报文仲裁是一个在有多个主机同时尝试控制总线但只允许其中一个控制总线并使报文不被破坏的过程同步两个或多个器件同步时钟信号的过程二、I2C 总线上数据传输的过程I2C 总线是一个多主机的总线,这就是说可以连接多于一个能控制总线的器件到总线。
由于主机通常是微控制器,让我们考虑以下数据在两个连接到I2C 总线的微控制器之间传输的情况。
这突出了I2C 总线的主机--从机和接收器--发送器的关系。
应当注意的是这些关系不是持久的,只由当时数据传输的方向决定。
传输数据的过程如下:1、假设微控制器A 要发送信息到微控制器B1)微控制器A 主机寻址微控制器B 从机2)微控制器A 主机发送器发送数据到微控制器B 从机接收器3)微控制器A 终止传输2、如果微控制器A 想从微控制器B 接收信息1)微控制器A 主机寻址微控制器B 从机2)微控制器A 主机接收器从微控制器B 从机发送器接收数据3)微控制器A 终止传输,甚至在这种情况下主机微控制器A 也产生定时而且终止传输三、I2C 总线的仲裁连接多于一个微控制器到I2C 总线的可能性意味着超过一个主机可以同时尝试初始化传输数据。
为了避免由此产生混乱,发展出一个仲裁过程。
它依靠线与连接所有I2C 总线接口到I2C 总线。
如果两个或多个主机尝试发送信息到总线,在其他主机都产生“0” 的情况下,首先产生一个“1”的主机将丢失仲裁。
仲裁时的时钟信号是用线与连接到SCL 线的主机产生的时钟的同步结合。
在I2C 总线上产生时钟信号通常是主机器件的责任,当在总线上传输数据时每个主机产生自己的时钟信号。
主机发出的总线时钟信号只有在以下的情况才能被改变:慢速的从机器件控制时钟线并延长时钟信号,或者在发生仲裁时被另一个主机改变。
I2C总线协议介绍(易懂)目录CONTENTS•I2C总线协议产生背景•I2C总线协议内容介绍•I2C总线协议总结一、I2C总线协议产生背景1电视机内IC 之间相互连接,IC 芯片体积增大功耗增大 成本增加 IC 芯片应用不便飞利浦公司为了硬件电路最简化,效益最大化,给芯片设计制造者和芯片应用者带来极大益处。
2 I2C 总线Logo3飞利浦公司将这种集成电路互连通信电路命名为Inter-Integrated Circuit,简称为Inter-IC,或I2C(数字“2”为上标)。
因为I2C中的两根导线(SDA和SCL)构成了两根Bus,实现了Bus的功能;由于I2C电路能实现Bus的功能,故把I2C 电路称为 I2C-Bus,中文叫I2C总线(I2C总线是一个两线总线)。
4在正式的书面场合,全称写作Inter-Integrated Circuit,简写Inter-IC(IIC)或者I2C(数字“2”书写为上标,,英文读作“I squared C”,中文读作“I平方C”)5I2C总线术语及定义,如表(1)所示:表(1) I2C总线术语及定义6最初,I2C总线的运行速度被限制在100 Kbit /s。
随着技术的发展,对该规范进行了多次补充与更新,现在有五种运行速度模式,如表(2)所示:表(2)I2C总线传输速度模式二、I2C总线协议内容1I2C Bus 只要求两条双向线路:串行数据线(serial data SDA)与串行时钟线SCL(serialclock SCL),两条线都是双向传输的。
每个连接到总线的器件都有唯一的地址,主控制器发出的控制信息分为地址码和控制量两部分,地址码用来选择需要控制的I2C设备,控制量包含类别(写与读)2I2C总线是一种多控制器总线,总线上可以连接多个控制器和多个从机,这些控制器都可以发起对总线的控制,通过仲裁机制,同一个时刻,只能有一个控制器获得控制权,其他控制器轮流获取总线的控制权。
一文了解I2C----总线概述I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
I2C总线产生于在80年代,最初为音频和视频设备开发,如今主要在服务器管理中使用,其中包括单个组件状态的通信。
I2C版本概况:版本1.0-1992l 删除了用软件编程从机地址的内容, 因为实现这个功能相当复杂,而且不被使用.l 删除了”低速模式”,实际上这个模式是整个I2C总线规范的子集,不需要明确的详细说明.l 增加了快速模式,它将位速率增加4倍到达400kbit/s,快速模式器件都向下兼容,即她们可以在0~100kbit/s的I2C总线系统中使用.l 增加了10位寻址,允许1024个额外的从机地址. l 快速模式器件的斜率控制和输入滤波改善了EMC性能.版本2.0-1998l 增加了高速模式(Hs模式),它将位速率增加到3.4Mbit/s,Hs模式的器件可以和I2C总线系统中快速和标准模式器件混合使用,位速率从0~3.4Mbit/s.l 电源电压是2V或更低的器件的低输出电平和滞后调整到符合噪声容限的要求,而且保持和电源电压更高的器件兼容.l 快速模式输出级的0.6V6mA要求被删除. l 新器件的固定输入电平被总线电压相关的电平代替. l 增加了双向电平转换器的应用信息.版本2.1-2000l在Hs模式的重复起始条件后,可以延长始终信号SCLH.l Hs模式中的一些时序参数变得更随意.I2C总线支持任何IC生产过程(NMOS,CMOS,双极性).两线—串行数据(SDA)和串行时钟(SCL)线在连接到总线的器件间传递信息.每个器件都有唯一的地址识别(无论是微控制器,LCD驱动器,存储器或键盘接口),而且都可以作为一个发送机或接收机(由器件的功能决定).I2C总线是一个多主机的总线,可以连接多个能控制总线的器件到总线.。
I2C总线入门1)最近学习51单片机,学到A/D,D/A转换的时候发现我板子上的转换芯片不是书上所讲的ADC0804和DAC0832而是PCF8591T,看了一下它的数据手册,发现它并不是书上所说的并行传输数据,是使用I2C总线传输的。
搞了两天才搞懂,写出来给大家分享一下,不足之处请务必不吝指出。
以上是I2C总线的简单介绍。
就比如说AT24C02存储芯片,和PCF8591数模模数转换芯片都支持I2C端口。
(如下图)2)接下来看如何使用I2C总线进行通信以上是I2C总线通信的格式。
由上图可以看出进行通信需要以下几个步骤a.初始化I2C总线就是把SDA和SCL都变成高电平。
voidinit()ﻩ//初始化{ﻩSDA=1;ﻩdelay();SCL=1;delay();ﻩ}delay()为延时函数voiddelay()ﻩ//延时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 intvoidwrite_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.发送/接受数据(取决于前面地址字的最后一位读/写位)发送数据和上面的发送地址调用同一个函数,只要穿给他数据即可。
接收数据其实和发送数据差不多,只不过要把接收到的数据一位一位拼装成一字节数据,看代码~ucharread_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由低电平变成高电平voidstop()ﻩ//停止信号{ﻩSDA=0;delay();SCL=1;delay();SDA=1;ﻩdelay();}以上就是整个数据传输的过程了为了更好的掌握I2C总线我在此放两个例子,一个是书上(郭天祥的,你们懂的)E PROM存储定时时间的例子,还有就是用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 unsignedintbit write=0; //写24c02的标志sbit SCL=P2^1; //串行时钟输入端sbit SDA=P2^0;ﻩ//串行数据输入端sbitLS138A=P2^2;//138译码器的3位控制数码管的sbit LS138B=P2^3;sbit LS138C=P2^4;ucharcode table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};ﻩ//数显管字模ucharsecond,tempt;ﻩ//second用来计秒数ﻩ,tempt用来临时存放0.05s的次数满20即1s写入void delay()//延时4-5个微秒{;;}voiddelay_1ms(uintz){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();}voidrespons()//应答相当于一个智能的延时函数{ﻩuchari;ﻩSCL=1;delay();ﻩwhile((SDA==1)&&(i<250))//没收到应答,我等!~~ﻩi++;ﻩﻩﻩﻩ//等了250次没收到就不管他了,就当他收到了-_-ﻩ//其实没收到的话可以结束程序的ﻩSCL=0;ﻩdelay();}void init() //初始化{SDA=1;delay();SCL=1;delay();}voidwrite_byte(uchar date) //写一字节数据{uchari,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();}ucharread_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;}void write_add(ucharaddress,uchardate){start();write_byte(0xa0); //10100000 前四位固定接下来三位全部被接地了所以都是0 最后一位是写所以为低电平respons();write_byte(address);ﻩrespons();write_byte(date);respons();ﻩstop();}ucharread_add(ucharaddress){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); ﻩ}}}voidt0()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 ucharunsigned char#define uint unsigned int#define PCF8591 0x90 //PCF8591地址sbitSCL=P2^1;ﻩ//串行时钟输入端sbit SDA=P2^0; //串行数据输入端void delay()ﻩ//延时4-5个微秒{;;}void delay_1ms(uintz){uintx,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();}voidrespons()//应答相当于一个智能的延时函数{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();}voidwrite_add(ucharcontrol,uchar date){start();10010000前四位固定接下来三位全部被接地了所以都是ﻩwrite_byte(PCF8591);ﻩ//0 最后一位是写所以为低电平respons();write_byte(control);respons();ﻩwrite_byte(date);ﻩrespons();stop();}voidmain(){uchar a;ﻩinit();ﻩwhile(1)ﻩ{write_add(0x40,a);ﻩdelay_1ms(5);ﻩa++;ﻩﻩif(a>250)ﻩa=0;ﻩﻩ}}。