视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
I2C通信协议
2025-10-08 02:19:05 责编:小OO
文档
//归一化模拟I2C总线软件包(C51)/******************************************************************************

// I2C.H

标准80C51模拟I2C总线程序头文件

//******************************************************************************/

#ifndef I2C_H

#define I2C_H

//定义I2C操作模式

#define I2C_RECV 0 /* 接收模式 */

#define I2C_SEND 1 /* 发送模式 */

#define I2C_SrRECV 2 /* 带Sr接收 */

//I2C总线初始化

void I2C_Init();

/******************************************************************************

函数:void I2C_On()

功能:启动I2C总线收发数据

返回:0-正常,1-异常(无应答)

说明:参数Mode是操作模式,决定I2C总线收发格式。常见的收发格式有3种,具体如下:

0-接收模式,格式:S | SLA+R | Data... | P

1-发送模式,格式:S | SLA+W | Addr | Data... | P

2-带Sr接收,格式:S | SLA+W | Addr | Sr | SLA+R | Data... | P

******************************************************************************/

bit I2C_On

(

unsigned char Mode, //操作模式

unsigned char SLA, //从机地址

unsigned char Addr, //子地址

unsigned char *Buf, //数据缓冲区

unsigned char Size //数据长度

);

#endif //I2C_H/******************************************************************************

I2C.C

标准80C51模拟I2C总线程序(主模式,通用)

******************************************************************************/

#i nclude

#i nclude "I2C.H"

//模拟I2C总线的管脚定义

sbit I2C_SCL = P1^6; //定义I2C总线时钟信号

sbit I2C_SDA = P1^7; //定义I2C总线数据信号

/******************************************************************************

函数:I2C_Delay()

功能:模拟I2C总线延时

说明:请根据具体情况调整延时值

******************************************************************************/

void I2C_Delay()

{

unsigned char t;

t = 10;

while ( --t != 0 ); //延时2*t个机器周期

}

/******************************************************************************

函数:I2C_Init()

功能:I2C总线初始化,使总线处于空闲状态

说明:在main()函数的开始处,应当执行一次本函数

******************************************************************************/

void I2C_Init()

{

I2C_SCL = 1; I2C_Delay();

I2C_SDA = 1; I2C_Delay();

}

/******************************************************************************

函数:I2C_Start()

功能:产生I2C总线的起始条件

说明:SCL处于高电平期间,当SDA出现下降沿时启动I2C总线

本函数也用来产生重复起始条件

******************************************************************************/

void I2C_Start()

{

I2C_SDA = 1; I2C_Delay();

I2C_SCL = 1;

I2C_Delay();

I2C_SDA = 0; I2C_Delay();

I2C_SCL = 0; I2C_Delay();

}

/******************************************************************************

函数:I2C_Write()

功能:向I2C总线写1个字节的数据

参数:dat是要写到总线上的数据

******************************************************************************/

void I2C_Write(unsigned char dat)

{

unsigned char t = 8;

do

{

I2C_SDA = (bit)(dat & 0x80);

dat <<= 1;

I2C_SCL = 1; I2C_Delay();

I2C_SCL = 0; I2C_Delay();

} while ( --t != 0 );

}

/******************************************************************************

函数:I2C_Read()

功能:从从机读取1个字节的数据

返回:读取的1个字节数据

******************************************************************************/

unsigned char I2C_Read()

{

unsigned char dat;

unsigned char t = 8;

I2C_SDA = 1; //在读取数据之前,要把SDA拉高,使之处于输入状态

do

{

I2C_SCL = 1; I2C_Delay();

dat <<= 1;

if ( I2C_SDA ) dat++;

I2C_SCL = 0; I2C_Delay();

} while ( --t != 0 );

return dat;

}

/******************************************************************************

函数:I2C_GetAck()

功能:读取从机应答位(应答或非应答),用于判断:从机是否成功接收主机数据

返回:0-从机应答

1-从机非应答

说明:从机在收到每一个字节后都要产生应答位,主机如果收到非应答则应当终止传输

******************************************************************************/

bit I2C_GetAck()

{

bit Ack;

I2C_SDA = 1; I2C_Delay();

I2C_SCL = 1; I2C_Delay();

Ack = I2C_SDA;

I2C_SCL = 0; I2C_Delay();

return Ack;

}

/******************************************************************************

函数:I2C_PutAck()

功能:主机产生应答位(应答或非应答),用于通知从机:主机是否成功接收从机数据

参数:Ack = 0:主机应答

Ack = 1:主机非应答

说明:主机在收到每一个字节后都要产生应答,在收到最后一个字节时,应当产生非应答

******************************************************************************/

void I2C_PutAck(bit Ack)

{

I2C_SDA = Ack; I2C_Delay();

I2C_SCL = 1; I2C_Delay();

I2C_SCL = 0; I2C_Delay();

}

/******************************************************************************

函数:I2C_Stop()

功能:产生I2C总线的停止条件

说明:SCL处于高电平期间,当SDA出现上升沿时停止I2C总线

******************************************************************************/

void I2C_Stop()

{

I2C_SDA = 0; I2C_Delay();

I2C_SCL = 1; I2C_Delay();

I2C_SDA = 1; I2C_Delay();

}

/*********************************

*********************************************

函数:void I2C_On()

功能:启动I2C总线收发数据

返回:0-正常,1-异常(无应答)

说明:参数Mode是操作模式,决定I2C总线收发格式。常见的收发格式有3种,具体如下:

0-接收模式,格式:S | SLA+R | Data... | P

1-发送模式,格式:S | SLA+W | Addr | Data... | P

2-带Sr接收,格式:S | SLA+W | Addr | Sr | SLA+R | Data... | P

******************************************************************************/

bit I2C_On

(

unsigned char Mode, //操作模式

unsigned char SLA, //从机地址

unsigned char Addr, //子地址

unsigned char *Buf, //数据缓冲区

unsigned char Size //数据长度

)

{

//启动I2C总线

I2C_Start();

if ( Mode != I2C_RECV )

{

//发送SLA+W

I2C_Write(SLA & 0xFE);

if ( I2C_GetAck() )

{

I2C_Stop();

return 1;

}

//发送子地址

I2C_Write(Addr);

if ( I2C_GetAck() )

{

I2C_Stop();

return 1;

}

if ( Mode == I2C_SEND )

{

//发送数据

do

{

I2C_Write(*Buf++);

if ( I2C_GetAck() )

{

I2C_Stop();

return 1;

}

} while ( --Size != 0 );

//发送完毕

I2C_Stop();

return 0;

}

else

{

I2C_Start(); //发送重复起始条件

}

}

//发送SLA+R

I2C_Write(SLA | 0x01);

if ( I2C_GetAck() )

{

I2C_Stop();

return 1;

}

//接收数据

for (;;)

{

*Buf++ = I2C_Read();

if ( --Size == 0 )

{

I2C_PutAck(1); //接收完最后一个数据时发送NACK

break;

}

I2C_PutAck(0);

}

//接收完毕

I2C_Stop();

return 0;

}下载本文

显示全文
专题