EEPROM IC操作说明_第1页
EEPROM IC操作说明_第2页
EEPROM IC操作说明_第3页
EEPROM IC操作说明_第4页
EEPROM IC操作说明_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、I2C协议     2条双向串行线,一条数据线SDA,一条时钟线SCL。   SDA传输数据是大端传输,每次传输8bit,即一字节。   支持多主控(multimastering),任何时间点只能有一个主控。   总线上每个设备都有自己的一个addr,共7个bit,广播地址全0.   系统中可能有多个同种芯片,为此addr分为固定部分和可编程部份,细节视芯片而定,看datasheet。1.1 I2C位传输   数据传输:SCL为高电平时,SDA线若保持稳定

2、,那么SDA上是在传输数据bit;             若SDA发生跳变,则用来表示一个会话的开始或结束(后面讲)   数据改变:SCL为低电平时,SDA线才能改变传输的bit1.2 I2C开始和结束信号      开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。   结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。  

3、1.3 I2C应答信号      Master每发送完8bit数据后等待Slave的ACK。   即在第9个clock,若从IC发ACK,SDA会被拉低。   若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示:1.4 I2C写流程写寄存器的标准流程为:1.    Master发起START2.    Master发送I2C addr(7bit)和w操作0(1bit),等待ACK3.  

4、;  Slave发送ACK4.    Master发送reg addr(8bit),等待ACK5.    Slave发送ACK6.    Master发送data(8bit),即要写入寄存器中的数据,等待ACK7.    Slave发送ACK8.    第6步和第7步可以重复多次,即顺序写多个寄存器9.    Master发起STOP写一个寄存器写多个寄存器1.5 I2C读流程读寄存器的标准流程为:1.&#

5、160;   Master发送I2C addr(7bit)和w操作1(1bit),等待ACK2.    Slave发送ACK3.    Master发送reg addr(8bit),等待ACK4.    Slave发送ACK5.    Master发起START6.    Master发送I2C addr(7bit)和r操作1(1bit),等待ACK7.    Slave发送ACK8. 

6、   Slave发送data(8bit),即寄存器里的值9.    Master发送ACK10.    第8步和第9步可以重复多次,即顺序读多个寄存器读一个寄存器读多个寄存器1.前言    对于大多数工程师而言,I2C永远是一个头疼的问题。相比UART和SPI而言,I2C的时序要复杂一些,I2C组合变化也丰富一些。在这里以AT24C04为例说明I2C使用过程中的一些注意点。2.AT24C04操作示意图图 AT24C04操作示意图示意图说明:示意图分阐述了4种不同的操作方式,例如写单个存储单元,写

7、多个存储单元,读单个存储单元和写单个存储单元。对于单个操作而言,上部为MCU通过I2C输出的相关指令,下部为I2C设备的响应。例如写单个存储单元操作时,MCU发出I2C启动,设备地址,写标志位等,而I2C设备输出多个ACK。3.若干说明3.1 基本操作方式I2C设备的操作可分为写单个存储字节,写多个存储字节,读单个存储字节和读多个存储字节。相对于AT24C04而言,这些读写动作相对于内部的存储单元而言,对于其他的具备I2C接口的AD或传感器而言,存储单元变成了寄存器单元。虽然存在概念上的差别,但是其操作原理确实一样的。3.2 无应答在以上4种情况中,无应答为MCU发出,无应答意为MCU不需要从

8、机输出数据,MCU将会停止本次I2C操作。需要说明的是,无应答并不是一种异常情况。3.3 I2C设备并不只有一个设备地址这一点往往被忽略,一般情况下认为在I2C启动信号之后的字节为I2C从机地址(7位)。对于AT24C04而言,内部具有4Kb存储位,合计512字节。若需要访问512字节内容,总共需要9根地址线(8位宽度),那么上图中的存储地址(8位长度)显然还差了一位,那么就需要从设备地址中“借”1位,这就使得AT24C04具有两个I2C地址,例如0x50和0x51。3.4 存储地址相对于AT24C04而言,存储地址占1个字节。若换成其他I2C设备,例如ADXL345,存储地址被寄存器地址替代

9、即可,其他操作方式相似。但是像AT24C32或AT24C64这样的大容量EEPROM,则存储地址需要2字节描述,也就意味着需要连续发送两个字节地址信息且高字节在前。其他像BH1750这样的光照芯片,存储地址被具体的操作命令替代,使用I2C设备时需要因地制宜,切不可照搬教条。3.5 连续读和连续写限制AT24C04中存在页的概念,一页的大小为8字节,若果在单页的范围内,存储地址累加,若超过该页的最大地址,存储地址回到页开始处。所以对于连续读和连续写而言,最大的操作字节数为8。若需要操作的字节内容超过8字节,则需要进行翻页操作,即写入下一页的起始存储地址。4 总结    I2C

10、设备有很多种,若掌握基本原理,便可见招拆招,那是I2C总线就不那么难了。5.参考资料2. PowerPC的I2C实现Mpc8560的CCSR中控制I2C的寄存器共有6个。2.1 I2CADR 地址寄存器CPU也可以是I2C的Slave,CPU的I2C地址有 I2CADR指定 2.2 I2CFDR 频率设置寄存器The serial bit clock frequency of SCL is equal to the CCB clock divided by the divider.用来设置I2C总线频率2.3 I2CCR 控制寄存器MEN: Module Enable. &

11、#160;  置1时,I2C模块使能MIEN:Module Interrupt Enable. 置1时,I2C中断使能。MSTA:Master/slave mode. 1 Master mode,0 Slave mode.        当1->0时,CPU发起STOP信号        当0->1时,CPU发起START信号MTX:Transmit/receive mode select.0 Receive mode,1 Transmit modeTX

12、AK:Transfer acknowledge. 置1时,CPU在9th clock发送ACK拉低SDARSTA:Repeat START. 置1时,CPU发送REPEAT STARTBCST:置1,CPU接收广播信息(信息的slave addr为7个0)2.4 I2CSR 状态寄存器MCF:0  Byte transfer is in process     1  Byte transfer is completedMAAS:当CPU作为Slave时,若I2CDR与会话中Slaveaddr匹配,此bit被置1MBB:0 I2C bu

13、s idle       1 I2C bus busyMAL:若置1,表示仲裁失败BCSTM:若置1,表示接收到广播信息SRW:When MAAS is set, SRW indicates the value of the R/W command bit of the calling address, which is sent from the master.   0 Slave receive, master writing to slave   1 Slave transmit, mas

14、ter reading from slaveMIF:Module interrupt. The MIF bit is set when an interrupt is pending, causing a processor interrupt request(provided I2CCRMIEN is set)RXAK:若置1,表示收到了ACK2.5 I2CDR 数据寄存器这个寄存器储存CPU将要传输的数据。3. PPC-Linux中I2C的实现   内核代码(linux-)中,通过I2C总线存取寄存器的函数都在文件drivers/i2c/busses/i2c-mpc.c

15、中  最重要的函数是mpc_xfer.  1. static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)2. 3.     struct i2c_msg *pmsg;4.     int i;5.     int ret&#

16、160;= 0;6.     unsigned long orig_jiffies = jiffies;7.     struct mpc_i2c *i2c = i2c_get_adapdata(adap);8.9.     mpc_i2c_start(i2c);    / 设置I2CCRMEN, 使能I2C module 10.11.

17、    /* Allow bus up to 1s to become not busy */12.     /一直读I2CSRMBB,等待I2C总线空闲下来13.     while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) 14.         if (signal_

18、pending(current) 15.             pr_debug("I2C: Interruptedn");16.             writeccr(i2c, 0);17.           

19、  return -EINTR;18.         19.         if (time_after(jiffies, orig_jiffies + HZ) 20.             pr_debug("I2C: t

20、imeoutn");21.             if (readb(i2c->base + MPC_I2C_SR) =22.                 (CSR_MCF | CSR_MBB | CSR_RXAK)2

21、3.                 mpc_i2c_fixup(i2c);24.             return -EIO;25.         26.      

22、60;  schedule();27.     28.29.     for (i = 0; ret >= 0 && i < num; i+) 30.         pmsg = &msgsi;31.    &#

23、160;    pr_debug("Doing %s %d bytes to 0x%02x - %d of %d messagesn",32.              pmsg->flags & I2C_M_RD ? "read" : "write",33.    

24、;          pmsg->len, pmsg->addr, i + 1, num);34.         /根据消息里的flag进行读操作或写操作35.         if (pmsg->flags & I2C_M_RD)

25、 36.             ret = mpc_read(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);37.         else38.           &#

26、160; ret = mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);39.     40.     mpc_i2c_stop(i2c);    /保证为I2CCSRMSTA为0,保证能触发STOP41.     return (ret < 0) ?

27、 ret : num;42. 1. static int mpc_write(struct mpc_i2c *i2c, int target,2.              const u8 * data, int length, int restart)3. 4.    

28、60;int i;5.     unsigned timeout = i2c->adap.timeout;6.     u32 flags = restart ? CCR_RSTA : 0;7.8.     /* Start with MEN */    /以防万一,保证I2C模块使能起来9.    &

29、#160;if (!restart)10.         writeccr(i2c, CCR_MEN);11.     /* Start as master */       /写了I2CCRCCR_MSTA,触发CPU发起START信号12.     writeccr(i2c, CCR_MIEN | CCR_MEN

30、 | CCR_MSTA | CCR_MTX | flags);13.     /* Write target byte */     /CPU发送一个字节,slave I2C addr和0 (写操作bit) 14.     writeb(target << 1), i2c->base + MPC_I2C_DR);15.16. &#

31、160;   if (i2c_wait(i2c, timeout, 1) < 0)    /等待slave 发ACK17.         return -1;18.19.     for (i = 0; i < length; i+) 20.  

32、       /* Write data byte */21.         writeb(datai, i2c->base + MPC_I2C_DR); /CPU接着发数据,包括reg addr和data22.23.         if (i2c_wait(i2c, timeout, 1

33、) < 0)       /等待slave 发ACK24.             return -1;25.     26.27.     return 0;28. 1. static int i2c_wait(struct mpc_i2c 

34、*i2c, unsigned timeout, int writing)2. 3.     unsigned long orig_jiffies = jiffies;4.     u32 x;5.     int result = 0;6.7.     if (i2c->irq = 0)8.

35、        /循环读I2CSR,直到I2CSRMIF置19.         while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF) 10.             schedule();11. &

36、#160;           if (time_after(jiffies, orig_jiffies + timeout) 12.                 pr_debug("I2C: timeoutn");13.   

37、0;             writeccr(i2c, 0);14.                 result = -EIO;15.            

38、0;    break;16.             17.         18.         x = readb(i2c->base + MPC_I2C_SR);19.     

39、60;   writeb(0, i2c->base + MPC_I2C_SR);20.      else 21.         /* Interrupt mode */22.         result = wait_event_interruptible_timeout(i2c->

40、;queue,23.             (i2c->interrupt & CSR_MIF), timeout * HZ);24.25.         if (unlikely(result < 0) 26.       

41、      pr_debug("I2C: wait interruptedn");27.             writeccr(i2c, 0);28.          else if (unlikely(!(i2c->interrupt & 

42、;CSR_MIF) 29.             pr_debug("I2C: wait timeoutn");30.             writeccr(i2c, 0);31.            

43、 result = -ETIMEDOUT;32.         33.34.         x = i2c->interrupt;35.         i2c->interrupt = 0;36.     37.38.  

44、   if (result < 0)39.         return result;40.41.     if (!(x & CSR_MCF) 42.         pr_debug("I2C: unfinishedn");43.  

45、60;      return -EIO;44.     45.46.     if (x & CSR_MAL)     /仲裁失败47.         pr_debug("I2C: MALn");48.     

46、60;   return -EIO;49.     50.51.     if (writing && (x & CSR_RXAK) /写后没收到ACK52.         pr_debug("I2C: No RXAKn");53.      

47、   /* generate stop */54.         writeccr(i2c, CCR_MEN);55.         return -EIO;56.     57.     return 0;58. 1. static int mpc_read(struct&

48、#160;mpc_i2c *i2c, int target,2.             u8 * data, int length, int restart)3. 4.     unsigned timeout = i2c->adap.timeout;5.     int

49、 i;6.     u32 flags = restart ? CCR_RSTA : 0;7.8.     /* Start with MEN */    /以防万一,保证I2C模块使能9.     if (!restart)10.         writeccr(i2c,&#

50、160;CCR_MEN);11.     /* Switch to read - restart */12.     /注意这里,再次把CCR_MSTA置1,再触发 START 13.     writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);14.15.16.    &#

51、160;/* Write target address byte - this time with the read flag set */ 17.     /CPU发送slave I2C addr和读操作118.     writeb(target << 1) | 1, i2c->base + MPC_I2C_DR);        &#

52、160;  /等待Slave发ACK1.     if (i2c_wait(i2c, timeout, 1) < 0)2.         return -1;3.4.     if (length) 5.         if (length = 1)6.             writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);7.        

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论