×
单片机 > 单片机程序设计 > 详情

51单片机——I2C总线驱动程序

发布时间:2024-06-01 发布时间:
|

为方便移植,采用多文件工程的方式。


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总线的解释:/zixunimg/eeworldimg/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(0 );//发送写器件地址

I2cSendByte(addr);//发送要写入内存地址

I2cSendByte(dat); //发送数据

I2cStop();

}

unsigned char At24c02Read(unsigned char addr) :读取24c02的一个地址的一个数据


unsigned char At24c02Read(unsigned char addr)

{

unsigned char num;

I2cStart();

I2cSendByte(0 ); //发送写器件地址

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


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
采用AT89C2051的数字可调稳压电源单片机源程序