为方便移植,采用多文件工程的方式。
void Delay10us()//延时10us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿
void I2cStart()//为方便与其他函数衔接,起始之后SDA和SCL都为0,虽然这与I2C总线空闲状态不符,但并不影响程序运行
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();//建立时间是SDA保持时间>4.7us
SDA=0;
Delay10us();//保持时间是>4us
SCL=0;
Delay10us();
}
终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿
void I2cStop()//结束之后保持SDA和SCL都为1;表示总线空闲
{
SDA=0;
Delay10us();
SCL=1;
Delay10us();//建立时间大于4.7us
SDA=1;
Delay10us();
}
I2cSendByte(unsigned char dat) : 通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定
unsigned char I2cSendByte(unsigned char dat)//发送成功返回1,发送失败返回0
{
unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。
for(a=0;a<8;a++)//要发送8位,从最高位开始
{
SDA=dat>>7; //起始信号之后SCL=0,所以可以直接改变SDA信号
dat=dat<<1;
Delay10us();
SCL=1;
Delay10us();//建立时间>4.7us
SCL=0;
Delay10us();//时间大于4us
}
SDA=1;//¥¥¥
Delay10us();
SCL=1;
while(SDA)//等待应答,也就是等待从设备把SDA拉低
{
b++;
if(b>200) //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
{
SCL=0;
Delay10us();
return 0;
}
}
SCL=0;
Delay10us();
return 1;
}
I2cReadByte() :使用I2c读取一个字节
unsigned char I2cReadByte()
{
unsigned char a=0,dat=0;
SDA=1; //¥¥¥
Delay10us();
for(a=0;a<8;a++)//接收8个字节
{
SCL=1;
Delay10us();
dat<<=1;
dat|=SDA;
Delay10us();
SCL=0;
Delay10us();
}
return dat;
}
在以上两个函数中,在“¥¥¥”处,都将SDA置为1,这是将SDA线释放。原因如下:
I2C的数据和时钟线上都有一个上拉电阻,电阻的另一端接一个高电平。当I2C工作时,SDA上的电平取决于SDA上的数据。当I2C不工作时,因为集成电路的输入端为高阻状态,SDA上的电压就取决于电阻另一端的高电平了,因此I2C在释放总线后,SDA就等于1了。
对于I2C总线的解释:https://blog.csdn.net/cax1165/article/details/86755169
void At24c02Write(unsigned char addr,unsigned char dat) :往24c02的一个地址写入一个数据
void At24c02Write(unsigned char addr,unsigned char dat)
{
I2cStart();
I2cSendByte(0xa0);//发送写器件地址
I2cSendByte(addr);//发送要写入内存地址
I2cSendByte(dat); //发送数据
I2cStop();
}
unsigned char At24c02Read(unsigned char addr) :读取24c02的一个地址的一个数据
unsigned char At24c02Read(unsigned char addr)
{
unsigned char num;
I2cStart();
I2cSendByte(0xa0); //发送写器件地址
I2cSendByte(addr); //发送要读取的地址
I2cStart();
I2cSendByte(0xa1); //发送读器件地址
num=I2cReadByte(); //读取数据
I2cStop();
return num;
}
多文件工程 头文件
#ifndef __I2C_H_
#define __I2C_H_
#include sbit SCL=P2^1; sbit SDA=P2^0; void I2cStart(); void I2cStop(); unsigned char I2cSendByte(unsigned char dat); unsigned char I2cReadByte(); void At24c02Write(unsigned char addr,unsigned char dat); unsigned char At24c02Read(unsigned char addr); #endif
上一篇:51单片机实验18:蜂鸣器
下一篇:51单片机实验1:点亮第一盏led
推荐阅读最新更新时间:2024-11-13 04:48