51单片机I2C总线驱动程序
扫描二维码
随时随地手机看文章
SI2I2C总线是PHLIPS公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。
I2C总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。
一.I2C系统结构
每个接到I2C总线上的器件都有唯一的地址。主机与其它器件间的数据传送可以是由主机发送数据到其它器件,这时主机即为发送器。由总线上接收数据的器件则为接收器。
二.数据位的有效性规定
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
三.字节传送与应答
每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。
四.驱动程序
#define uchar unsigned char
#define uint unsigned int
#define somenop() _nop_(),_nop_(),_nop_(),_nop_(),_nop_(),_nop_()
sbit SCL=P2^1;
sbit SDA=P2^0;
1
2
3
4
5
1.起始信号和终止信号
SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;
SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态
void I2C_Start() //起始
{
SCL=1;
somenop();
SDA=1;
somenop();
SDA=0;
somenop();
SCL=0;
somenop();
}
void I2C_Stop() //终止
{
SDA=0;
somenop();
SCL=1;
somenop();
SDA=1;
somenop();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2.发送数据
void I2C_SendByte(uchar dat, uchar ack) //发送一个字节
{
uchar i,j,b=0;
for(i=0;i<8;i++)
{
SCL=0;
somenop();
SDA=(bit)(dat&0x80); //每次取最高位进行发送
dat<<=1; //从最高位开始发送,左移使每一位逐渐成为最高位
SCL=1; //上升沿时发送数据
somenop();
}
SCL=0;
somenop();
SDA=1;
somenop();
SCL=1;
_nop_();
while((SDA==1)&&(j<250)) j++; //等待应答,也就是等待从设备把SDA拉低
SCL=0;
_nop_();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
3.读取数据
uchar I2C_ReadByte() //读一个字节
{
uchar i,dat=0;
SCL=0; //此处也可以不置低,因为起始和发送一个字节之后SCL都是0
somenop();
SDA=1; //拉高准备数据读取
_nop_();
for(i=0;i<8;i++) //读取8位数据
{
SCL=1;
somenop();
dat<<=1;
if(SDA==1)
dat=dat|0x01;
somenop();
SCL=0; //下降沿时读取数据
somenop();
}
return dat;
}