// 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; }下载本文