历史上的今天
返回首页

历史上的今天

今天是:2025年07月15日(星期二)

正在发生

2018年07月15日 | 以AT24C02为例的IIC通信协议

2018-07-15 来源:eefocus

IIC通信协议:

双向二线制同步串行总线,只需要两根线即可在总线上器件之间传送信息,两根线分别是SDA和SCL

SDA:双向数据线,为OD门,与其它任意数量的OD与OC门成"线与"关系。

SCL:上升沿将数据输入到每个EEPROM器件中;下降沿驱动EEPROM器件输出数据。(边沿触发)

(在读写的时候,SCL = 1时,SDA保持数据,不能在获取数据;SCL = 0,SDA 可以改变,可以获取读或者写的一个字节。)

SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,接口电路是开楼输出,需通过上拉电阻接电源VCC,当总线空闲时,两根线都是高电平,连接总线的外同器件都是CMOS器件,输出级也是开漏电路,在总线上消耗的电流很小,因此,总线上扩展的器件数量主要由电容负载来决定,因为每个器件的总线接口都有一定的等效电容.而线路中电容会影响总线传输速度.当电容过大时,有可能造成传输错误.所以,其负载能力为400pF,因此可以估算出总线允许长度和所接器件数量。

特征:
1、在硬件上,I2C总线只需要一根数据线和一根时钟线两根线,总线接口已经集成在芯片内部,而且片上接口电路的滤波器可以滤去总线数据上的毛刺.因此I2C总线简化了硬件电路PCB布线,降低了系统成本,提高了系统可靠性。因为12C芯片除了这两根线和少量中断线,与系统再没有连接的线,用户常用IC可以很容易形成标准化和模块化,便于重复利用。
2、I2C总线是一个真正的多主机总线,如果两个或多个主机同时初始化数据传输,可以通过冲突检测和仲裁防止数据破坏,每个连接到总线上的器件都有唯一的地址,任何器件既可以作为主机也可以作为从机,但同一时刻只允许有一个主机。数据传输和地址设定由软件设定,非常灵活。总线上的器件增加和删除不影响其他器件正常工作。
3、I2C总线可以通过外部连线进行在线检测,便于系统故障诊断和调试,故障可以立即被寻址,软件也利于标准化和模块化,缩短开发时问。
4、连接到相同总线上的IC数量只受总线最大电容的限制,串行的8位双向数据传输位速率在标准模式下可达100Kbit/s,快速模式下可达400Kbit/s,高速模式下可达3.4Mbit/s。
5、)总线具有极低的电流消耗.抗高噪声干扰,增加总线驱动器可以使总线电容扩大10倍,传输距离达到15m;兼容不同电压等级的器件,工作温度范围宽。


1、主设备和从设备

主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件,在总线上主和从、发和收的关系是不恒定的,而取决于此时数据传送方向。

系统中的所有外围器件都具有一个7位的"从器件专用地址码",其中高4位为器件类型(比如说AT24C02就是1010),由生产厂家制定,低3位为器件引脚定义地址,由使用者定义。主控器件通过地址码建立多机通信的机制,因此I2C总线省去了外围器件的片选线,这样无论总线上挂接多少个器件,其系统仍然为简约的二线结构。


2、数据传输

发送到SDA上的每个字节必须的8位,每次传输可以发送的字节数量不受限制。每个字节后面都有一个响应位。

首先传输的是数据的最高位(MSB),如果从机要完成一些其他功能后才能接收或发送下一个完整的数据字节,可以使时钟SCL保持低电平,迫使主机进入等待状态,当从机准备好接收下一个数据字节并释放时钟线SCL后数据传输继续。


3、工作原理

如果从机希望主机降低传送速度可以通过将SCL主动拉低延长其低电平时间的方法来通知主机,当主机在准备下一次传送发现SCL的电平被拉低时就进行等待,直至从机完成操作并释放SCL线的控制控制权。这样以来,主机实际上受到从机的时钟同步控制。可见SCL线上的低电平是由时钟低电平最长的器件决定;高电平的时间由高电平时间最短的器件决定。这就是时钟同步,它解决了I2C总线的速度同步问题。


主机发送数据

1)主机在检测到空闲状态(SDA = 1,SCL = 1)时,发送一个启动信号S,开始第一次通信

2)主机发送一个字节,包含了7位的外围设备地址和1位读写控制位R/W组成,0为写,1位读

3)收到命令的从机返回一个ACK确认字节

4)主机接收到从机反馈的命令之后,发送一个存储地址

5)接受到的从机跳到相应的存储地址,然后返回一个ACK确认字节

6)主机收到应答字节之后,开始发送第一个字节的数据

7)从机收到后返回一个ACK

8)主机收到后在继续发下一个字节的数据

9)当主机发送了最后一个字节并且收到了从机的ACK后,发送一个停止信号P结束本次通信并释放总线,从机接到了P之后也退出与主机之间的通信。


注意:

①主机通过发送地址码与对应的从机建立了通信关系,而挂接在总线上的其它从机虽然同时也收到了地址码,但因为与其自身的地址不相符合,因此提前退出与主机的通信;

②主机的一次发送通信,其发送的数据数量不受限制。主机是通过 P 信号通知发送的结束,从机收到 P 信号后退出本次通信;

③主机的每一次发送后都是通过从机的 ACK 信号了解从机的接收状况,如果应答错误则重发。


主机接收数据的流程

1)主机发送了启动信号之后,接着发送命令字节(R/W)

2)从机收到地址字节后,返回一个应答信号并向主机发送数据

3)主机收到数据后向从机返回一个确认字节

4)从机接受了确认字节之后,再向主机发送数据

5)当主机收到了最后一个数据之后,向从机发送一个“非应答”(ACK = 1),从机收到非应答之后便停止发送

6)主机发送了非应答之后,向从机发送一个停止信号P,释放总线,结束通信



4、起始信号和终止信号

起始信号:当SCL置1,SDA由高到低的转换,启动信号是一种电平跳变时序信号,而不是一个电平信号。

终止信号:当SCL为高,SDA由低到高的跳变,停止信号是一种电平跳变时序信号,而不是一个电平信号。



5、应答信号

发送器每发送一个字节,就砸时钟脉冲9期间释放数据线,由接收器反馈一个应答信号,应答信号为低电平时,规定为有效应答位,表示接收器已经成功的接受了该字节;应答信号为高电平时,规定为非应答位,一般表示接收器接受该字节没有成功。


对于反馈有效应答位ACK的要求是:接收器在第9个时钟脉冲之前的低电平将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。如果接收器是主控器,则在他接受最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送并释放SDA线,以便主控接收器发送一个停止信号P


6、数据的有效性

SCL为高电平时,SDA上的数据保持稳定,SCL为低电平时,SDA数据可以发生变化
数据在SCL上升沿之前就要准备好,数据是在SCL上升沿的时候打入到EEPROM中的


EEPROM:

电可擦除可编程的读写存储器,掉电后数据不丢失的存储芯片,可以在电脑上或者和专用设备上擦著已有的信息,重新编程



AT24C20是一个2k串行的CMOS EEPROM,内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。在单片机上的应用广泛, 可以实现掉电数据不丢失功能。


例程:


#include

#include"./delay/delay.h"

 

#define succ 0

#define err 1

 

 

#define LCDPORT P0

#define LCD_WRITE_DATA 1

#define LCD_WRITE_COM 0

 

sbit RS = P2^4;

sbit RW = P2^5;

sbit E = P2^6;

 

sbit SCL = P2^0;

sbit SDA = P2^1;

bit ack = 0;

/*启示信号*/

void iic_start()

SDA = 1;//保证在SCL=1时有SDA的下降沿,所以先进行SDA =1 

SCL = 1;

delay_us(1);

SDA = 0;

delay_us(1);

SCL = 0;//SCL低电平,使主机处于等待状态

}

 

/*终止信号*/

void iic_stop()

{

SDA = 0;

        SCL = 1;

delay_us(1);

SDA = 1;

delay_us(1);

SCL = 0;

}

/*应答子函数*/

void iic_ack()

{

        SDA = 0;

SCL = 1;

delay_us(1);

SCL = 0;

}

 

void iic_noack()

{

        SDA = 1;

SCL = 1;

delay_us(1);

SCL = 0;

}

bit iic_send_byte(unsigned char byte)

{

        unsigned char i;

for(i = 0; i < 8; i++)

{

   SDA = byte & 0x80;

   SCL = 1;//保持数据不变,将数据打入到EEPROM

   delay_us(1);

   SCL = 0;//数据可变

   byte <<= 1;

}

SCL = 1;//准备接受应答信号,在SCL高电平期间,SDA拉低

SDA = 1;

delay_us(1);

if(0 == SDA)

{

    ack = 1;//数据传输正确,产生应答

}

else

{

   ack = 0;

}

SCL = 0;//SCL等待,SDA等待

return ack;

}

 

 

/*接收字节*/

unsigned char iic_rcv_byte()

{

        unsigned char a;

unsigned char temp = 0;

unsigned char i;

SDA = 1;//在上升沿到来之前,做好准备

for(i = 0; i < 8; i++)

{

   SCL = 0;

   delay_us(1);

   SCL = 1;//上升沿,表示可以接受数据啦

   if(SDA)

   {

a = 0x01;

   }

   else

   {

a = 0x0;//SDA为低电平时,读到的数据为0

   }

   temp |= (a << (7-i));

   delay_us(1);

       }

       SCL = 0;

       return temp;

}

 

unsigned char AT24C02_send_str(unsigned char devaaddr,unsigned char roomaddr,unsigned char *s,unsigned num)

{

unsigned char i;

        iic_start();

iic_send_byte(devaaddr);//EEPROM的地址

if(0 == ack)

{

return err;

}

iic_send_byte(roomaddr);

if(0 == ack)

{

    return err;

}

for(i = 0; i < num ; i++)

{

       iic_send_byte(*s);

if(0 == ack)

{

   return err;

}

s++;

}

iic_stop();

return succ;

}

 

unsigned char AT24C02_rcv_str(unsigned char devaddr,unsigned char roomaddr,unsigned char *s,unsigned num)

{

        unsigned char i;

iic_start();

iic_send_byte(devaddr);

if(0 == ack)

{

return err;

}

iic_send_byte(roomaddr);

if(0 == ack)

{

   return err;

}

iic_start();

iic_send_byte(devaddr+1);

for(i = 0; i < num-1; i++)

{

*s = iic_rcv_byte();

iic_ack();

s++;

}

*s = iic_rcv_byte();

iic_noack();

iic_stop();

return succ;

}

 

void lcd_write(unsigned char byte,unsigned char flag)

{

       if(flag)

       {

   RS = 1;

       }

       else

       {

   RS = 0;

}

RW = 0;

E = 1;

LCDPORT = byte;

delay_us(10);

E = 0;

}

void lcd_init()

{

        delay_ms(15);

lcd_write(0x38,LCD_WRITE_COM);

delay_ms(5);

lcd_write(0x38,LCD_WRITE_COM);

delay_ms(5);

lcd_write(0x38,LCD_WRITE_COM);

delay_ms(5);

lcd_write(0x38,LCD_WRITE_COM);

delay_ms(5);

lcd_write(0x38,LCD_WRITE_COM);

delay_ms(5);

lcd_write(0x08,LCD_WRITE_COM);

delay_ms(5);

lcd_write(0x01,LCD_WRITE_COM);

delay_ms(5);

lcd_write(0x06,LCD_WRITE_COM);

delay_ms(5);

lcd_write(0x0c,LCD_WRITE_COM);

delay_ms(5);

}

void dis_lcd_write(unsigned char x,unsigned char y,unsigned char byte)

{

unsigned char i = 0;

/*byte*/

if(y == 0)

{

lcd_write(0x80+x,LCD_WRITE_COM);

lcd_write(byte,LCD_WRITE_DATA);

}

if(y == 1)

{

lcd_write(0x80+0x40+x,LCD_WRITE_COM);

lcd_write(byte,LCD_WRITE_DATA);

}

}

void dis_lcd_src(unsigned char x,unsigned char y,unsigned char *src) 

{

if(y == 0)

{

lcd_write(0x80+x,LCD_WRITE_COM);

}

if(y == 1)

{

lcd_write(0x80+0x40+x,LCD_WRITE_COM);

}

while(*src != '\0')

{

lcd_write(*src,LCD_WRITE_DATA);

src++;

}

}

 

 

void main()

{

unsigned char temp[10];

        unsigned char test[10] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x40};

lcd_init();

 

AT24C02_send_str(0xae,100,test,3);

delay_s(1);

 

AT24C02_rcv_str(0xae,100,temp,3);

dis_lcd_src(0,0,temp);

while(1);

}


推荐阅读

史海拾趣

COTO TECHNOLOGY公司的发展小趣事

进入上世纪六十年代,COTO TECHNOLOGY迎来了一个重大的转折点。公司开始探索线圈绕组以外的领域,通过引入簧片继电器,成功扩展了产品线。这一创新举措不仅丰富了公司的产品种类,更重要的是,它为公司打开了新的市场领域。到了七十年代,COTO更是凭借开发出的首款获得专利的低热电动势簧片继电器,一跃成为业界领先的干簧继电器制造商。

兵字(BingZi)公司的发展小趣事

随着市场的不断变化和客户需求的日益多样化,兵字公司意识到,要想在市场中保持领先地位,就必须不断进行技术创新。于是,公司投入大量研发资源,成功研发出了小型精密互感器。这一创新产品不仅填补了市场空白,还为公司带来了可观的收益。同时,兵字公司也凭借这一技术突破,进一步巩固了在电子元器件领域的领先地位。

American Electric公司的发展小趣事

随着技术的不断进步和市场的不断变化,American Electric公司意识到技术创新是保持竞争力的关键。因此,公司加大了对研发的投入,引进了一批高端技术人才,不断推出具有创新性的电力产品和服务。同时,公司还积极拓展业务,与多个大型企业建立合作关系,为其提供定制化的电力解决方案。这些举措不仅提高了公司的市场份额,还进一步提升了公司的品牌形象。

Caddock公司的发展小趣事

随着电子行业的不断发展,精度和电阻稳定性的要求越来越高。Caddock公司积极投入研发,成功开发出Tetrinox电阻系统。这一技术具有低温度系数和超高稳定性,使得电阻器和电阻器网络在精密和超精密模拟系统中得到了广泛应用。

ENPIRION公司的发展小趣事

在经历了几年的快速发展后,ENPIRION公司被Altera公司收购。这一收购标志着ENPIRION公司进入了一个新的发展阶段。在Altera公司的支持下,ENPIRION公司得以继续扩大其研发和生产能力,推出更多创新的产品和服务。同时,随着人工智能、物联网和大数据技术的不断发展,ENPIRION公司也积极探索新的应用领域和市场机会,为其未来发展奠定了坚实的基础。

以上五个故事概述了ENPIRION公司在电子行业中的发展历程和关键里程碑。通过这些故事,我们可以看到ENPIRION公司凭借技术创新、市场扩展和合作伙伴关系等关键因素取得了显著的成功。

Harris公司的发展小趣事

二战后,随着全球经济的复苏和电气产品的爆炸性需求,Hammond迎来了前所未有的发展机遇。在1950年代和1960年代,Hammond积极扩展产品线,成为变压器、机架、机柜以及电气和电子行业外壳的领先供应商。同时,公司还进行了多次战略性收购,进一步巩固了其在北美电气OEM市场的地位,成为磁性材料的主要供应商之一。

问答坊 | AI 解惑

RS232/TTL电平转换芯片MAX232的原理及其应用

RS232/TTL电平转换芯片MAX232的原理及其应用…

查看全部问答>

什么是PSoC

PSoC:(power system on a chip)单片片上功率系统。它能把传感器件与电路、信号处理电路、接口电路、功率器件和电路等集成在一个硅芯片上,使其具有按照负载要求精密调节输出和按照过热、过压、过流等情况自我进行保护的智能功能,其优越性不言而 ...…

查看全部问答>

Win CE 5.0 环境下如何编写USB摄像头驱动

跪请高手教,能不能用VS2005写Win CE5.0使用的USB摄像头驱动,应用程序可以用这个驱动捕获图像并通过网络传送。…

查看全部问答>

求16C550芯片 WINCE5.0版本驱动

本人现在正在做毕业设计,很急 啊啊!!十万火急啊 !!! 有哪位大侠可以教小妹一下,感激不禁啊!!! 求16C550芯片 WINCE5.0版本驱动  !!! 还有基于嵌入式的GPRS的资料可以分享的!!万分感谢啊!!…

查看全部问答>

SQLite在Wince中Can't find PInvoke DLL 'SQLite.Interop.065.DLL

我在vs中开发,知道SQLite.Interop.065.DLL需要手动部署 我就在工程中添加了这个和那个SQLite.dll,部署到WM的模拟器上后可以运行 而部署到Wince5.0上则提示Can\'t find PInvoke DLL \'SQLite.Interop.065.DLL 我还把windows目录里放了这俩个dll ...…

查看全部问答>

0

攒分赚人品谢谢清洁工和大兔子…

查看全部问答>

NAND FLASH无法引导UBOOT!向各高手大哥求救!!!

小弟的2440板子一次烧写U-BOOT往K9S1208后,就无法引导了,以前烧写的好好的,这次烧写好后就无法启动了,用超级终端显示乱码,用DNW显示RXTX_THREAD_ERR,重试几次都没用,确保UBOOT.BIN是没问题的,望各位大哥解救!…

查看全部问答>

关于Windows DDK 问题,急!

我安装完 Windows DDK for Windows 2000, Windows XP, Windows Server 2003之后,会提示很多安装错误信息。并且打开Windows XP checked Build Environments时,出现下面的错误:C:\\WINDDK\\3790~1.183\\bin\\setenv.bat 不是内部或者外部命令... ...…

查看全部问答>

寻大虾合作机顶盒开发

http://topic.eeworld.net/u/20071201/18/a2aaf09f-7fa2-419c-93c1-77b51f9713d8.html?seed=1107526537…

查看全部问答>

关于STM32SPI读取DS1302的问题????

前几天想用STM32的SPI接口来读取DS1302,但是调试了两天,读出的数据还是有问题,不是全为0,就全为1。还请各位大虾们帮忙看一下哈。 STM32_DS1302.rar (1.39 MB) 下载次数:202 2010-1-8 16:00 …

查看全部问答>