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
?