搜档网
当前位置:搜档网 › I2C总线入门(很详细,很经典)

I2C总线入门(很详细,很经典)

I2C总线入门(很详细,很经典)
I2C总线入门(很详细,很经典)

I2C总线入门

1)最近学习51单片机,学到A/DQ/A转换的时候发现我板子上的转换芯片不是书上所讲的ADC0804和DAC0832而是PCF859仃,看了一下它的数据手册, 发现它并不是书上所说的并行传输数据,是使用I2C总线传输的。搞了两天才搞懂,写出来给大家分享一下,不足之处请务必不吝指出。

! ≡tt f Itiief II R J Ih PHiLlPS

t j ΓC b

FC 口対由

???κΓt r SDA IUB L f W r■I. SeiL閃離找L#參G [?总蠻H件嗣时Mtfl ι?X?tt

StM'QUIA ft

/i CPU 1√ Kf?IC ZlHh IC J J Ie Z糾幣町遊i;I^I IL

W*s

4t∣ι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 PDlP

AOL1 8□ VCC

Al匚?WP

A2匚3

GND匚4£

AJNOIT

U

迴VDD

AINlI 2ISj AOUT

AIN2 3]

回” RE F

AIN3 I 41^I3] AGND

PCF8591P

AO ^5∏^↑2? EXT

At叵TrlOSC

A2 T/

JO)SeL^k

VSS叵(VJ SDA

I

H2引脚图

(Dll

a.初始化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通过发送有效地址封该黠件来激活。该地址包括?l定部分和可编黔分「:璨喘部分理烦处劇也址4 ∣?UAO. Al和A2来设置一一在皿惡线协询:哋址必銀杲起跆条件后作为第一个字节发送.地址字节的最后一?是用于设置吐后数据传输方向的读泻位。(见图

4、16. 17)

(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 (此时芯片就会读取总线上的数据)

F 面是代码

#define UChar UnSigned Char

#define Uint UnSigned int void write_byte(UChar date) {

UChar i,temp; temp=date;

for(i=0;i<8;i++)

{

temp=temp<<1;

SCL=0; delay();

SDA=CY; delay();

SCL=1; delay(); } SCL=0; delay(); SDA=1; delay();

发送地址的时候只需把地址传给该函数即可。

//写一字节数据

//左移一位移出的一位在CY 中

//只有在scl=0时Sda 能变化值

d. 应答(

ACK )

每接受或发送一字节数据后都需要发送一位应答,来表是否收到了前面一个 字节的数据。

7-应答佰号

卩C 总找亦仪规定■晦传送「个字节數据f 含地址及命令字)后,都整有一个应答信号. 以确定

Sfc 据传送足否被对方收算应答信号由接收设备产牛.1?SCL 信号为高电平期何.接 收???SDA t??

紙电平,表示数据传输正确■产生应褂?时序图如图&1.6所示。

Void respo ns()//应答 相当于一个智能的延时函数

{

UChar i; SCL=1; delay();

WhiIe((SDA==1) &&(i<250))// 没收到应答,我等!~~

i++; //等了 250次没收到就不管他了,就当他收到了

〃其实没收到的话可以结束程序的

SCL=0; delay();

e. 发送/接受数据(取决于前面地址字的最后一位读/写位)

发送数据和上面的发送地址调用同一个函数,只要穿给他数据即可。

接收数据其实和发送数据差不多,只不过要把接收到的数据一位一位拼装成 一字节数据,看代码~

UChar read_byte() {

UChar i,k; SCL=O; delay(); SDA=1;

Γ?JΛ-

(M L ?) i 」

fci K↑ffl 4

?

相关主题