NXP

IIC协议的那些事儿

2019-07-12 12:52发布

IIC是什么? 答:IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司在八十年代初设计出来的,主要是用来连接整体电路(ICS) ,IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。这种方式简化了信号传输总线接口。 以上是百科资料。IIC实际上就是随需求的增长应运而生的一种多机(以下分主机、从机)串行数据传输方式,而IIC被冠以“协议”二字就是说我们共同制定了这种规则,大家必须遵守,以保证数据的正确传输。 那么这种协议是怎么规定的? 答:应用IIC协议的器件一定有时钟总线SCL和数据总线SDA(这么聪明的你一定知道)。协议规定(白话文了哈): 1.SCL在高电平期间,SDA不准变化;SCL在低电平期间,SDA可以变化(数据传输); 2.主机的起始与停止信号控制二者数据传输的节奏(主机就是大佬,让你干什么就必须干什么); 3.主机发出读写数据命令后,如果从机敢不应答,主机就不带你玩了,一个stop信号走机! 以下以AT24C02(外部存储芯片EEPROM)分析: 一、AT24C02器件引脚图:                                                                                                                                                                                     应用IIC协议的器件引脚都相差无几,无非就是SCL时钟总线,SDA数据总线,WP写保护,A0/A1/A2为器件寻址(下面会提到),VCC和GND就不摆了撒。 二、 主机(MCU)与从机(IIC器件)的连接       AT24C02就属于EEPROM,可以只有一个主机和一个从机。 三、数据传输 IIC器件的数据传输:在主机给予start信号后,开始传输数据,主机每传一个字节从机必须要有应答(好比主机去从机家敲门,从机“诶”一声),在主机的stop信号后,数据传输结束。所以,数据完整传输就是四个过程:开始,数据传输,应答,结束。 开始与结束:                                         由上图及IIC协议知: 开始信号:SCL=1时,主机令SDA=0。 somenop为时序要求,一般为4.7us左右即可,这里用4个_nop_()表示。 void IIC_Start(void) { SDA = 1; SCL = 1; somenop; SDA = 0; somenop; SCL = 0; }   结束信号:SCL=1时,SDA=1。 void IIC_Stop(void) { SDA = 0; SCL = 1; somenop; SDA = 1; } 数据传输与应答过程: 数据传输:遵从IIC协议,在SCL=0时SDA变化。一次传输8位数据,即传输一个字节会有八次SCL拉低拉高,SDA则随要传输的数据进行变化。 (1)主机发送数据: void IIC_SendByte(unsigned char byt) { unsigned char i; for(i=0;i<8;i++){ if(byt&0x80){ SDA = 1; } else{ SDA = 0; } somenop; SCL = 1; byt <<= 1; somenop; SCL = 0; } }   (2)主机接受数据: unsigned char IIC_RecByte(void) { unsigned char da; unsigned char i; for(i=0;i<8;i++){ SCL = 1; somenop; da <<= 1; if(SDA) da |= 0x01; SCL = 0; somenop; } return da; }   应答: bit IIC_WaitAck(void) { SDA = 1; somenop; SCL = 1; somenop; if(SDA){ SCL = 0; IIC_Stop(); return 0; } else{ SCL = 0; return 1; } } 至此,各个过程分析完毕。 四、数据的读写 (1)Write 根据上面的分析,我们可以很快得到: void IIC_Write(char address,char data) { IIC_Start(); IIC_SendByte(0xa0); //AT24C02的器件地址为 1010 0000(假设只有一个AT24C02,因为是写操作,所以最后一位为0) IIC_WaitAck(); IIC_SendByte(address); //AT24C02的寄存器位置 IIC_WaitAck(); IIC_SendByte(data); IIC_WaitAck(); IIC_Stop(); }   (2)Read                                                同理: unsigned char IIC_Read(unsigned char address) { unsigned char temp; IIC_Start(); IIC_SendByte(0xa0); IIC_WaitAck(); IIC_SendByte(address); //AT24C02的寄存器位置 IIC_WaitAck(); IIC_Start(); IIC_SendByte(0xa1);//最后一位为1表示主机要读数据了 IIC_WaitAck(); temp=IIC_RecByte(); IIC_Stop(); return temp; }