EEPROM I2C操作说明Word下载.docx

上传人:b****7 文档编号:22151204 上传时间:2023-02-02 格式:DOCX 页数:15 大小:278.79KB
下载 相关 举报
EEPROM I2C操作说明Word下载.docx_第1页
第1页 / 共15页
EEPROM I2C操作说明Word下载.docx_第2页
第2页 / 共15页
EEPROM I2C操作说明Word下载.docx_第3页
第3页 / 共15页
EEPROM I2C操作说明Word下载.docx_第4页
第4页 / 共15页
EEPROM I2C操作说明Word下载.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

EEPROM I2C操作说明Word下载.docx

《EEPROM I2C操作说明Word下载.docx》由会员分享,可在线阅读,更多相关《EEPROM I2C操作说明Word下载.docx(15页珍藏版)》请在冰豆网上搜索。

EEPROM I2C操作说明Word下载.docx

写多个寄存器

1.5I2C读流程

读寄存器的标准流程为:

Master发送I2Caddr(7bit)和w操作1(1bit),等待ACK

Master发送I2Caddr(7bit)和r操作1(1bit),等待ACK

Slave发送data(8bit),即寄存器里的值

Master发送ACK

10. 

第8步和第9步可以重复多次,即顺序读多个寄存器

读一个寄存器

读多个寄存器

1.前言

 

对于大多数工程师而言,I2C永远是一个头疼的问题。

相比UART和SPI而言,I2C的时序要复杂一些,I2C组合变化也丰富一些。

在这里以AT24C04为例说明I2C使用过程中的一些注意点。

2.AT24C04操作示意图

图AT24C04操作示意图

示意图说明:

示意图分阐述了4种不同的操作方式,例如写单个存储单元,写多个存储单元,读单个存储单元和写单个存储单元。

对于单个操作而言,上部为MCU通过I2C输出的相关指令,下部为I2C设备的响应。

例如写单个存储单元操作时,MCU发出I2C启动,设备地址,写标志位等,而I2C设备输出多个ACK。

3.若干说明

3.1基本操作方式

I2C设备的操作可分为写单个存储字节,写多个存储字节,读单个存储字节和读多个存储字节。

相对于AT24C04而言,这些读写动作相对于内部的存储单元而言,对于其他的具备I2C接口的AD或传感器而言,存储单元变成了寄存器单元。

虽然存在概念上的差别,但是其操作原理确实一样的。

3.2无应答

在以上4种情况中,无应答为MCU发出,无应答意为MCU不需要从机输出数据,MCU将会停止本次I2C操作。

需要说明的是,无应答并不是一种异常情况。

3.3I2C设备并不只有一个设备地址

这一点往往被忽略,一般情况下认为在I2C启动信号之后的字节为I2C从机地址(7位)。

对于AT24C04而言,内部具有4Kb存储位,合计512字节。

若需要访问512字节内容,总共需要9根地址线(8位宽度),那么上图中的存储地址(8位长度)显然还差了一位,那么就需要从设备地址中“借”1位,这就使得AT24C04具有两个I2C地址,例如0x50和0x51。

3.4存储地址

相对于AT24C04而言,存储地址占1个字节。

若换成其他I2C设备,例如ADXL345,存储地址被寄存器地址替代即可,其他操作方式相似。

但是像AT24C32或AT24C64这样的大容量EEPROM,则存储地址需要2字节描述,也就意味着需要连续发送两个字节地址信息且高字节在前。

其他像BH1750这样的光照芯片,存储地址被具体的操作命令替代,使用I2C设备时需要因地制宜,切不可照搬教条。

3.5连续读和连续写限制

AT24C04中存在页的概念,一页的大小为8字节,若果在单页的范围内,存储地址累加,若超过该页的最大地址,存储地址回到页开始处。

所以对于连续读和连续写而言,最大的操作字节数为8。

若需要操作的字节内容超过8字节,则需要进行翻页操作,即写入下一页的起始存储地址。

4总结

I2C设备有很多种,若掌握基本原理,便可见招拆招,那是I2C总线就不那么难了。

5.参考资料

2.PowerPC的I2C实现

Mpc8560的CCSR中控制I2C的寄存器共有6个。

2.1I2CADR地址寄存器

CPU也可以是I2C的Slave,CPU的I2C地址有I2CADR指定

2.2I2CFDR频率设置寄存器

TheserialbitclockfrequencyofSCLisequaltotheCCBclockdividedbythedivider.

用来设置I2C总线频率

2.3I2CCR控制寄存器

MEN:

ModuleEnable. 

置1时,I2C模块使能

MIEN:

ModuleInterruptEnable.置1时,I2C中断使能。

MSTA:

Master/slavemode.1Mastermode,0Slavemode.

当1->

0时,CPU发起STOP信号

当0->

1时,CPU发起START信号

MTX:

Transmit/receivemodeselect.0Receivemode,1Transmitmode

TXAK:

Transferacknowledge.置1时,CPU在9thclock发送ACK拉低SDA

RSTA:

RepeatSTART.置1时,CPU发送REPEATSTART

BCST:

置1,CPU接收广播信息(信息的slaveaddr为7个0)

2.4I2CSR状态寄存器

MCF:

Bytetransferisinprocess

Bytetransferiscompleted

MAAS:

当CPU作为Slave时,若I2CDR与会话中Slaveaddr匹配,此bit被置1

MBB:

0I2Cbusidle 

1I2Cbusbusy

MAL:

若置1,表示仲裁失败

BCSTM:

若置1,表示接收到广播信息

SRW:

WhenMAASisset,SRWindicatesthevalueoftheR/Wcommandbitofthecallingaddress,whichissentfromthemaster.

0Slavereceive,masterwritingtoslave

1Slavetransmit,masterreadingfromslave

MIF:

Moduleinterrupt.TheMIFbitissetwhenaninterruptispending,causingaprocessorinterruptrequest(providedI2CCR[MIEN]isset)

RXAK:

若置1,表示收到了ACK

2.5I2CDR数据寄存器

这个寄存器储存CPU将要传输的数据。

3.PPC-Linux中I2C的实现

内核代码(linux-2.6.24)中,通过I2C总线存取寄存器的函数都在文件drivers/i2c/busses/i2c-mpc.c中

最重要的函数是mpc_xfer.

1.static 

int 

mpc_xfer(struct 

i2c_adapter 

*adap, 

struct 

i2c_msg 

*msgs, 

num)

2.{

3. 

*pmsg;

4. 

i;

5. 

ret 

0;

6. 

unsigned 

long 

orig_jiffies 

jiffies;

7. 

mpc_i2c 

*i2c 

i2c_get_adapdata(adap);

8.

9. 

mpc_i2c_start(i2c);

//设置I2CCR[MEN],使能I2Cmodule 

10.

11. 

/*Allowbusupto1stobecomenotbusy*/

12. 

//一直读I2CSR[MBB],等待I2C总线空闲下来

13. 

while 

(readb(i2c->

base 

MPC_I2C_SR) 

&

CSR_MBB) 

{

14. 

if 

(signal_pending(current)) 

15. 

pr_debug("

I2C:

Interrupted\n"

);

16. 

writeccr(i2c, 

0);

17. 

return 

-EINTR;

18. 

}

19. 

(time_after(jiffies, 

HZ)) 

20. 

timeout\n"

21. 

==

22. 

(CSR_MCF 

CSR_MBB 

CSR_RXAK))

23. 

mpc_i2c_fixup(i2c);

24. 

-EIO;

25. 

26. 

schedule();

27. 

28.

29. 

for 

(i 

>

<

num;

i++) 

30. 

pmsg 

msgs[i];

31. 

Doing%s%dbytesto0x%02x-%dof%dmessages\n"

32. 

pmsg->

flags 

I2C_M_RD 

?

"

read"

:

write"

33. 

len, 

addr, 

1, 

num);

34. 

//根据消息里的flag进行读操作或写操作

35. 

(pmsg->

I2C_M_RD) 

36. 

mpc_read(i2c, 

buf, 

i);

37. 

else

38. 

mpc_write(i2c, 

39. 

40. 

mpc_i2c_stop(i2c);

//保证为I2CCSR[MSTA]为0,保证能触发STOP

41. 

(ret 

0) 

42.}

mpc_write(struct 

*i2c, 

target,

2. 

const 

u8 

data, 

length, 

restart)

3.{

timeout 

i2c->

adap.timeout;

u32flags 

restart 

CCR_RSTA 

7.

8. 

/*StartwithMEN*/ 

//以防万一,保证I2C模块使能起来

(!

10. 

CCR_MEN);

/*Startasmaster*/ 

//写了I2CCR[CCR_MSTA],触发CPU发起START信号

CCR_MIEN 

CCR_MEN 

CCR_MSTA 

CCR_MTX 

flags);

/*Writetargetbyte*/ 

//CPU发送一个字节,slaveI2Caddr和0(写操作bit) 

writeb((target 

1), 

MPC_I2C_DR);

15.

(i2c_wait(i2c, 

timeout, 

1) 

//等待slave发ACK

-1;

18.

length;

/*Writedatabyte*/

writeb(data[i], 

//CPU接着发数据,包括regaddr和data

22.

26.

28.}

i2c_wait(struct 

writing)

u32x;

result 

6.

(i2c->

irq 

== 

0)

//循环读I2CSR,直到I2CSR[MIF]置1

CSR_MIF)) 

timeout)) 

break;

readb(i2c->

MPC_I2C_SR);

writeb(0, 

else 

/*Interruptmode*/

wait_event_interruptible_timeout(i2c->

queue,

interrupt 

CSR_MIF), 

HZ);

24.

(unlikely(result 

0)) 

waitinterrupted\n"

28. 

(unlikely(!

CSR_MIF))) 

waittimeout\n"

-ETIMEDOUT;

33.

interrupt;

37.

(result 

result;

40.

(x 

CSR_MCF)) 

42. 

unfinished\n"

43. 

44. 

45.

46. 

CSR_MAL) 

//仲裁失败

47. 

MAL\n"

48. 

49. 

50.

51. 

(writing 

CSR_RXAK)) 

{//写后没收到ACK

52. 

NoRXAK\n"

53. 

/*generatestop*/

54. 

55. 

56. 

57. 

58.}

mpc_read(struct 

//以防万一,保证I2C模块使能

/*Switchtoread-restart*/

//注意这里,再次把CCR_MSTA置1,再触发START 

14.

/*Writetargetaddressbyte-thistimewiththereadflagset*/ 

//CPU发送slaveI2Caddr和读操作1

//等待Slave发ACK

1. 

3.

(length) 

(length 

1)

CCR_TXAK);

//为什么不置TXAK

CCR_MSTA);

/*Dummyread*/

12.

16.

/*Generatetxackonnexttolastbyte*/

//注意这里TXAK置1,表示CPU每收到1byte数据后,会发送ACK

length 

2) 

21.

/*Generatestoponlastbyte*/

//注意这里CCR_MSTA[1->

0]CPU会触发STOP

data[i] 

readb(i2c-

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > IT认证

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1