i2c.h
#ifndef _I2C_H_
#define _I2C_H_
#include<reg51.h>
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
sbit I2C_SCL = P2^1;
sbit I2C_SDA = P2^0;
void I2C_Delay10us();
void I2C_Start();
void I2C_Stop();
uchar I2C_SendByte(uchar da, uchar ack);
uchar I2C_ReadByte();
#endif
i2c.c
#include<i2c.h>
void I2C_Delay10us()
{
uchar a,b;
for(b = 1; b > 0; b--)
for(a = 2; a > 0; a--);
}
/*****************************
数据和时钟在不忙时保持高电平.
在时钟为高电平时,
数据线上的一个由高到低的变化
被定义为开始条件
****************************/
void I2C_Start()
{
I2C_SDA = 1;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();
I2C_SDA = 0;
I2C_Delay10us();
I2C_SCL = 0;
I2C_Delay10us();
}
/*****************************
时钟为高电平时,数据线上的一个
由底到高的变化被定义为停止条件
****************************/
void I2C_Stop()
{
I2C_SDA = 0;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();
I2C_SDA = 1;
I2C_Delay10us();
}
uchar I2C_SendByte(uchar da, uchar ack)
{
uchar a = 0;
uchar b = 0;
for(a = 0; a < 8; a ++)
{
I2C_SDA = da >> 7;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();
I2C_SCL = 0;
I2C_Delay10us();
da = da << 1;
}
/*****************************
数据和时钟在不忙时保持高电平.
在时钟为高电平时,
数据线上的一个由高到低的变化
被定义为开始条件,如果I2C_SDA
在200us内变低那么相当于发送了一个
启动信号,返回发送成功
****************************/
I2C_SDA = 1;
I2C_Delay10us();
I2C_SCL = 1;
while(I2C_SDA && (ack == 1))
{
b ++;
if(b > 200)
{
I2C_SCL = 0;
I2C_Delay10us();
return 0;
}
}
I2C_SCL = 0;
I2C_Delay10us();
return 1;
}
uchar I2C_ReadByte()
{
uchar a = 0,dat = 0;
I2C_SDA = 1; //起始和发送一个字节之后I2C_SCL都是0
I2C_Delay10us();
for(a = 0; a < 8; a++)
{
I2C_SCL = 1;
I2C_Delay10us();
dat = dat << 1;
dat = dat |I2C_SDA;
I2C_Delay10us();
I2C_SCL = 0;
I2C_Delay10us();
}
return dat;
}