您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > IIC总线理解学习笔记
IICIICIICIIC总线理解学习笔记本文系4D'Man-Joe原创,文中图片与程序均转载自网络,如有侵权,望告知。为尊重作者成果,如想复制本文,密码为4D'Man-Joe。谢谢。在学校老师上单片机课程时,把IIC讲解的很复杂,很繁琐。今天,在偶然的学习C语言的过程中再次遇到了IIC,一番接触之下,感觉原来不用记那么多,只要了解关键的协议部分就够了。图1(个人比较喜欢先看图再看文字说明)如图1所示,就是IIC总线连接图了。简单来说,就一根数据SDA,一根时钟SCL。两根线按照一定的协议来传输数据。这样既可以节省IO口和电路板空间,又可以让每个能够发送接受数据的设备成为主控机,当然,前提是,同一时间上只能有一台设备是主控设备。接下来了解一下IICIICIICIIC的信号类型,它共有四种信号:起始信号、停止信号、应答信号、非应答型号。然后我们了解IIC传输数据的规则:图2数据传送的规则首先,我们了解在SCL=1时,SDA上的电平变化决定信号是起始信号还是停止信号。在SCL=0是,SDA上的电平允许变化,变化好了,等SCL=1时,保持到SCL=0,变化下一位数据,这一位的数据就算是传送成功了。当然,判断数据是否为高低电平,需要一个时间,下面会说到。接着,我们了解IICIICIICIIC的四种数据类型:详细说太繁琐,又不好记忆,我简化了一下,大家理解住就很好记了。注意,这四种信号都是在SCL=1时定义的。上面有说到,SCL=1时,SDA的变化是变换数据类型和判断数据高低电平的,SCL=0时,仅是用于SDA安全变化。起始信号:SDA由1→0,定义为起始。停止信号:SDA由0→1,定义为停止。当数据发送一个字节即8位数据后,到第9数据,接收的设备必须输出0做为应答信号。于此同时,发送设备就要释放SDA,用于接受判断接受设备是否应答。应答信号:SDA=0,定义为应答。非应答信号:SDA=1,定义为非应答。这个信号用于,主控设备接收数据时,用在最后一个数据后面,使受控设备释放数据线,以便主控设备产生一个停止信号来终止总线的数据传送。再次总结一下,四种信号中,只有(非)应答信号是接收设备控制的哦,其他的都是发送设备控制的,所以又叫主控设备。这应该很好理解吧。了解了数据传输的规则,接下来就要说协议了。图3总线的完整时序先看了解一下图3,大致理解上面说到的四种信号的使用。图4总线写格式写操作就是主控器件向受控器件发送数据,如图4所示。1.主控器会对总线发送起始信号,2.紧跟应该是第一个字节的8位数据,但是从地址只有7位,所谓从地址就是受控器的地址,而第8位是受控器约定的数据方向位,“0”为写。3.从图3中我们可以清楚地看到发送完一个8位数之后应该是一个受控器的应答信号。4.应答信号过后就是第二个字节的8位数据,这个数多半是受控器件的寄存器地址。5.寄存器地址过后就是要发送的数据,当数据发送完后就是一个应答信号,每启动一次总线,传输的字节数没有限制,一个字节地址或数据过后的第9个脉冲是受控器件应答信号。6.当数据传送完之后由主控器发出停止信号来停止总线。图5总线读格式读操作指受控器件向主控器件发送数据,其总线的操作格式如图5。1.由主控器发出起始信号,前两个传送的字节与写操作相同。2.到了第二个字节之后,就要从新启动总线,改变传送数据的方向,前面两个字节数据方向为写,即“0”;第二次启动总线后数据方向为读,即“1”;之后就是要接收的数据。3.从图5的写格式中我们可以看到有两种的应答信号。一种是受控器的,另一种是主控器的。前面三个字节的数据方向均指向受控器件,所以应答信号就由受控器发后出。但是后面要接收的N个数据则是指向主控器件,所以应答信号应由主控器件发出,当N个数据接收完成之后,主控器件应发出一个非应答信号,告知受控器件数据接收完成,不用再发送。4.最后的停止信号同样也是由主控器发出。下面推荐一段周立功老师公司出版的模拟IICIICIICIIC程序软件包,对照上面长篇大论的理论,希望让大家对IICIICIICIIC的规则协议有个更加直观的了解。/********************************************************************MCS-51单片机模拟I2C软件包(V1.1)文件名:VI2C_C51.C相关文件:VI2C_C51.H,VI2C_C51.LIB功能说明:本模拟I2C软件包包含了I2C操作的底层函数,如发送数据及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的与用户程序连接并扩展.....注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作一定的修改....(本软件包是1us机器周期,即晶振频率要小于12MHZ)总线时序符合I2C标准模式,100Kbit/S。更新时间:2002.06.05********************************************************************/#includereg51.h#includeintrins.h#defineucharunsignedchar/*宏定义*/#defineuintunsignedint#define_Nop()_nop_()/*定义空指令*/sbitSDA=P3^4;/*模拟I2C数据传送位*/sbitSCL=P3^5;/*模拟I2C时钟控制位*/bitack;/*应答标志位*//*******************************************************************起动总线函数函数原型:voidStart_I2c();功能:启动I2C总线,即发送I2C起始条件.********************************************************************/voidStart_I2c(){SDA=1;/*发送起始条件的数据信号*/_Nop();SCL=1;_Nop();/*起始条件建立时间大于4.7us,延时*/_Nop();_Nop();_Nop();_Nop();SDA=0;/*发送起始信号*/_Nop();/*起始条件锁定时间大于4μs*/_Nop();_Nop();_Nop();_Nop();SCL=0;/*钳住I2C总线,准备发送或接收数据*/_Nop();_Nop();}/*******************************************************************结束总线函数函数原型:voidStop_I2c();功能:结束I2C总线,即发送I2C结束条件.********************************************************************/voidStop_I2c(){SDA=0;/*发送结束条件的数据信号*/_Nop();/*发送结束条件的时钟信号*/SCL=1;/*结束条件建立时间大于4μs*/_Nop();_Nop();_Nop();_Nop();_Nop();SDA=1;/*发送I2C总线结束信号*/_Nop();_Nop();_Nop();_Nop();}/*******************************************************************字节数据发送函数函数原型:voidSendByte(ucharc);功能:将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0)发送数据正常,ack=1;ack=0表示被控器无应答或损坏。********************************************************************/voidSendByte(ucharc){ucharBitCnt;for(BitCnt=0;BitCnt8;BitCnt++)/*要传送的数据长度为8位*/{if((cBitCnt)&0x80)SDA=1;/*判断发送位*/elseSDA=0;_Nop();SCL=1;/*置时钟线为高,通知被控器开始接收数据位*/_Nop();_Nop();/*保证时钟高电平周期大于4μs*/_Nop();_Nop();_Nop();SCL=0;}_Nop();_Nop();SDA=1;/*8位发送完后释放数据线,准备接收应答位*/_Nop();_Nop();SCL=1;_Nop();_Nop();_Nop();if(SDA==1)ack=0;elseack=1;/*判断是否接收到应答信号*/SCL=0;_Nop();_Nop();}/*******************************************************************字节数据接收函数函数原型:ucharRcvByte();功能:用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数应答从机。********************************************************************/ucharRcvByte(){ucharretc;ucharBitCnt;retc=0;SDA=1;/*置数据线为输入方式*/for(BitCnt=0;BitCnt8;BitCnt++){_Nop();SCL=0;/*置时钟线为低,准备接收数据位*/_Nop();_Nop();/*时钟低电平周期大于4.7μs*/_Nop();_Nop();_Nop();SCL=1;/*置时钟线为高使数据线上数据有效*/_Nop();_Nop();retc=retc1;if(SDA==1)retc=retc+1;/*读数据位,接收的数据位放入retc中*/_Nop();_Nop();}SCL=0;_Nop();_Nop();return(retc);}/********************************************************************应答子函数函数原型:voidAck_I2c(bita);功能:主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)********************************************************************/voidAck_I2c(bita){if(a==0)SDA=0;/*在此发出应答或非应答信号*/elseSDA=1;_Nop();_Nop();_Nop();SCL=1;_Nop();_Nop();/*时钟低电平周期大于4μs*/_Nop();_Nop();_Nop();SCL=0;/*清时钟线,钳住I2C总线以便继续接收*/_Nop();_Nop();}/*******************************************************************用户接口函数*******************************************************************//*******************************************************************向无子地址器件发送字节数据函数函数原型:bitISendByte(ucharsla,ucahrc);功能:从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.如果返回1表示操作成功,否则操作有误。注意:使用前必须已结束总线。********************************************************************/bitISendByte(ucharsla,ucharc){Sta
本文标题:IIC总线理解学习笔记
链接地址:https://www.777doc.com/doc-1825279 .html