2.4I2C总线及其驱动程序目录1I2C简介2决策3软件接口4基本时序代码5外部接口代码6E2PROM读写范例7CAT1024驱动程序8温度的测量I2C简介I微控器外围器件I2C总线2CI2C总线特点I2C总线容易实现总线自检可挂接多个器件通信距离远兼顾高低速率通讯总线兼容性好终端I/O开漏总线电气兼容性好目录1I2C简介2决策3软件接口4基本时序代码5外部接口代码6E2PROM读写范例7CAT1024驱动程序8温度的测量I2C驱动决策标准80C51单片机无硬件I2C接口使用I/O模拟I2C总线时序难以实现完整协议通信模式总线仲裁通信速率地址模式原因实现仅实现主机功能仅支持一条I2C总线只有一个主机—80C51删除I2C主机总线仲裁仅支持7位地址模式通信速率在软件编译前确定不支持高速模式目录1I2C简介2决策3软件接口4基本时序代码5外部接口代码6E2PROM读写范例7CAT1024驱动程序8温度的测量I2C软件接口从机I2C总线主机从机具有I2C地址,内部寄存器均对应具体地址主机对从机的操作即对寄存器的读写操作初始化读操作写操作I2C软件接口/***************************************************************************Functionname:charzyI2cInit(void)**Descriptions:初始化I2C为主模式**inputparameters:无**outputparameters:无**Returnedvalue:0:成功-1:失败*************************************************************************/初始化I2C软件接口/***************************************************************************Functionname:unsignedcharzyI2cWrite(unsignedcharucAddr,unsignedintuiRegAddr,unsignedcharucRegAddrLen,unsignedchar*pucData,unsignedcharucDataLen)**Descriptions:将数据写入I2C从器件**inputparameters:ucAddr:从机地址**uiRegAddr:寄存器地址**ucRegAddrLen:寄存器地址长度(单位为字节)**pucData:要写入的数据**ucDataLen:要写入的数据长度**outputparameters:无**Returnedvalue:已写入的数据字节数*************************************************************************/写数据I2C软件接口/***************************************************************************Functionname:unsignedcharzyI2cRead(unsignedcharucAddr,unsignedintuiRegAddr,unsignedcharucRegAddrLen,unsignedchar*pucData,unsignedcharucDataLen)**Descriptions:从I2C器件读数据**inputparameters:ucAddr:从机地址**uiRegAddr:寄存器地址**ucRegAddrLen:寄存器地址长度(单位为字节)**ucDataLen:要写入的数据长度**outputparameters:pucData:读到的数据**Returnedvalue:已读到的数据字节数*************************************************************************/读数据配置接口#define__ZY_I2C_DELAY()ACC=ACC;//等待1/2个I2C周期#define__ZY_I2C_SDAP1_1;//SDA引脚配置#define__ZY_I2C_SCLP1_0;//SSL引脚配置I2C驱动配置文件(I2C_cfg.h)NOP函数名称函数功能__zyI2cStartSend()启动总线__zyI2cStopSend()停止总线__zyI2cRestartSend()重启总线__zyI2cBitSend()发送一位数据__zyI2cBitReceive()接收一位数据__zyI2cAckSend()发送ACK信号__zyI2cNakSend()发送NAK信号__zyI2cIsAck()接收反馈信号(ACK/NAK)__zyI2cByteSend()发送一个字节数据__zyI2cByteReceive()接收一个字节数据内部协议层函数接口内部协议层函数一览表目录1I2C简介2决策3软件接口4基本时序代码5外部接口代码6E2PROM读写范例7CAT1024驱动程序8温度的测量发送一位数据的时序SCL高电平期间采样SDA信号SDASCLSDASCL此时序禁止在发送数据时出现总线起始或结束控制发送一位数据函数SDA(I/O)SCL(I/O)80C51staticvoid__zyI2cBitSend(unsignedcharucData){if(ucData&0x80){__ZY_I2C_SDA=1;}else{__ZY_I2C_SDA=0;}__ZY_I2C_DELAY();__ZY_I2C_SCL=1;__ZY_I2C_DELAY();__ZY_I2C_SCL=0;}SDASCLI2C从机SDASCLI2C从机接收一位数据函数staticunsignedchar__zyI2cBitReceive(void){unsignedcharucRt;//返回值__ZY_I2C_DELAY();__ZY_I2C_SCL=1;__ZY_I2C_DELAY();ucRt=__ZY_I2C_SDA;__ZY_I2C_SCL=0;returnucRt;}SDA(I/O)SCL(I/O)80C51发送起始信号staticvoid__zyI2cStartSend(void){__ZY_I2C_DELAY();__ZY_I2C_SDA=0;__ZY_I2C_DELAY();__ZY_I2C_SCL=0;}SDA(I/O)SCL(I/O)80C51SDASCLI2C从机忙在SCL处于高电平期间,SDA从高电平向低电平跳变空闲时两线均为高电平……发送停止信号staticvoid__zyI2cStartSend(void){__ZY_I2C_SDA=0;__ZY_I2C_DELAY();__ZY_I2C_SCL=1;__ZY_I2C_DELAY();__ZY_I2C_SDA=1;}SDA(I/O)SCL(I/O)80C51SDASCLI2C从机在SCL处于高电平期间,SDA从低电平向高电平跳变空闲时SDA状态未知,需手动拉低……闲发送重复起始信号staticvoid__zyI2cStartSend(void){__ZY_I2C_SDA=1;__ZY_I2C_DELAY();__ZY_I2C_SCL=1;__ZY_I2C_DELAY();__ZY_I2C_SDA=0;__ZY_I2C_DELAY();__ZY_I2C_SCL=0;}SDA(I/O)SCL(I/O)80C51SDASCLI2C从机在I2C总线忙时,产生起始条件,以改变数据收发方向。忙状态起始信号应答和非应答SDA(I/O)SCL(I/O)80C51SDASCLI2C从机每个字节的传输,都紧跟一个应答状态位,来反映接收端的情况谁接收谁应答应答:ACK(A),应答位为0;非应答:NAK(/A),应答位为1产生非应答后应终止数据的发送数据应答应答原则时钟发送应答和非应答信号staticvoid__zyI2cAckSend(void){__ZY_I2C_SDA=0;__ZY_I2C_DELAY();__ZY_I2C_SCL=1;__ZY_I2C_DELAY();__ZY_I2C_SCL=0;}staticvoid__zyI2cNakSend(void){__ZY_I2C_SDA=1;__ZY_I2C_DELAY();__ZY_I2C_SCL=1;__ZY_I2C_DELAY();__ZY_I2C_SCL=0;}SDASCL12891289起始信号应答信号非应答信号停止信号例应答信号的处理staticvoid__zyI2cIsAck(void){__ZY_I2C_SDA=1;__ZY_I2C_DELAY();__ZY_I2C_SCL=1;__ZY_I2C_DELAY();if(__ZY_I2C_SDA==1){__ZY_I2C_SCL=0;return0;}__ZY_I2C_SCL=0;return1;}//接收应答准备//接收到应答//接收到非应答发送一个字节的数据staticvoid__zyI2cByteSend(unsignedcharucData){unsignedchari;//发送数据i=8;do{__zyI2cBitSend(ucData);ucData=ucData1;}while(--i!=0);}10101010主机MSBLSB从机MSBLSB程序示例接收一个字节的数据staticunsignedchar__zyI2cByteReceive(void){unsignedcharucRt;unsignedchari;//接收数据i=8;do{ucRt=(ucRt1)+__zyI2cBitReceive();}while(--i!=0);}10101010从机MSBLSB主机MSBLSB程序示例从机地址I2C总线从机1从机2从机6从机5从机4从机3各从机地址不能冲突!从机地址D7D6D5D4D3D2D1R/W地址格式MSBLSB从机地址读写标志发送写地址__zyI2cByteSend(ucAddr&0xfe);发送读地址__zyI2cByteSend(ucAddr|0x01);举例CAT24C021010A2A1A0R/W读写标志器件类型码器件地址选择E2PROM存储器带7位地址的完整数据传输SDASCLR/WACKACKACK产生起始信号发送7位地址和读写位接收ACK信号读取或者写一个字节的数据接收或者发送ACK信号产生结束信号应答信号7位地址+读写位起始信号8位数据位结束信号应答信号N-1个数据在I2C总线上被主机寻址的地址寄存器地址作用长度是否必须从机地址用于区分不同器件7位或10位是寄存器地址(子地址)用于区分器件内不同部件或存储单元长度不确定否从机地址用来区分器件内部不同单元的地址寄存器地址目录1I2C简介2决策3软件接口4基本时序代码5外部接口代码6E2PROM读写范例7CAT1024驱动程序8温度的测量总线初始化函数源代码char__zyI2cInit(void){__ZY_I2C_SCL=0;__zyI2cStopSend();return0;}I2C总线初始化=置I2C总线空闲=停止后的总线状态unsignedcharzyI2cWrite(unsignedcharucAddr,unsignedintuiRegAddr,unsignedcharucRegAddrLen,unsignedchar*pucData,unsignedcharucDataLen){unsignedchari;if(ucDataLen==0||pucData==0){return0;}i=ucDataLen;__zyI2cStartSend();__zyI2cByteSend(ucAddr&0xfe);if(__zyI2cIsAck