EEPROMI2C设备操作说明_第1页
EEPROMI2C设备操作说明_第2页
EEPROMI2C设备操作说明_第3页
EEPROMI2C设备操作说明_第4页
EEPROMI2C设备操作说明_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

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

文档简介

...wd......wd......wd...I2C协议2条双向串行线,一条数据线SDA,一条时钟线SCL。SDA传输数据是大端传输,每次传输8bit,即一字节。支持多主控(multimastering),任何时间点只能有一个主控。总线上每个设备都有自己的一个addr,共7个bit,播送地址全0.系统中可能有多个同种芯片,为此addr分为固定局部和可编程部份,细节视芯片而定,看datasheet。1.1I2C位传输数据传输:SCL为高电平时,SDA线假设保持稳定,那么SDA上是在传输数据bit;假设SDA发生跳变,则用来表示一个会话的开场或完毕〔后面讲〕数据改变:SCL为低电平时,SDA线才能改变传输的bit1.2I2C开场和完毕信号开场信号:SCL为高电平时,SDA由高电平向低电平跳变,开场传送数据。完毕信号:SCL为高电平时,SDA由低电平向高电平跳变,完毕传送数据。1.3I2C应答信号Master每发送完8bit数据后等待Slave的ACK。即在第9个clock,假设从IC发ACK,SDA会被拉低。假设没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示:1.4I2C写流程写存放器的标准流程为:1.Master发起START2.Master发送I2Caddr〔7bit〕和w操作0〔1bit〕,等待ACK3.Slave发送ACK4.Master发送regaddr〔8bit〕,等待ACK5.Slave发送ACK6.Master发送data〔8bit〕,即要写入存放器中的数据,等待ACK7.Slave发送ACK8.第6步和第7步可以重复屡次,即顺序写多个存放器9.Master发起STOP写一个存放器写多个存放器1.5I2C读流程读存放器的标准流程为:1.Master发送I2Caddr〔7bit〕和w操作1〔1bit〕,等待ACK2.Slave发送ACK3.Master发送regaddr〔8bit〕,等待ACK4.Slave发送ACK5.Master发起START6.Master发送I2Caddr〔7bit〕和r操作1〔1bit〕,等待ACK7.Slave发送ACK8.Slave发送data〔8bit〕,即存放器里的值9.Master发送ACK10.第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,1TransmitmodeTXAK:Transferacknowledge.置1时,CPU在9thclock发送ACK拉低SDARSTA:RepeatSTART.置1时,CPU发送REPEATSTARTBCST:置1,CPU接收播送信息〔信息的slaveaddr为7个0〕2.4I2CSR状态存放器MCF:0Bytetransferisinprocess1BytetransferiscompletedMAAS:当CPU作为Slave时,假设I2CDR与会话中Slaveaddr匹配,此bit被置1MBB:0I2Cbusidle1I2CbusbusyMAL:假设置1,表示仲裁失败BCSTM:假设置1,表示接收到播送信息SRW:WhenMAASisset,SRWindicatesthevalueoftheR/Wcommandbitofthecallingaddress,whichissentfromthemaster.0Slavereceive,masterwritingtoslave1Slavetransmit,masterreadingfromslaveMIF:Moduleinterrupt.TheMIFbitissetwhenaninterruptispending,causingaprocessorinterruptrequest(providedI2CCR[MIEN]isset)RXAK:假设置1,表示收到了ACK2.5I2CDR数据存放器这个存放器储存CPU将要传输的数据。3.PPC-Linux中I2C的实现内核代码〔linux-2.6.24〕中,通过I2C总线存取存放器的函数都在文件drivers/i2c/busses/i2c-mpc.c中最重要的函数是mpc_xfer.staticintmpc_xfer(structi2c_adapter*adap,structi2c_msg*msgs,intnum){structi2c_msg*pmsg;inti;intret=0;unsignedlongorig_jiffies=jiffies;structmpc_i2c*i2c=i2c_get_adapdata(adap);

mpc_i2c_start(i2c);//设置I2CCR[MEN],使能I2Cmodule/*Allowbusupto1stobecomenotbusy*///一直读I2CSR[MBB],等待I2C总线空闲下来while(readb(i2c->base+MPC_I2C_SR)&CSR_MBB){if(signal_pending(current)){

pr_debug("I2C:Interrupted\n");

writeccr(i2c,0);return-EINTR;}if(time_after(jiffies,orig_jiffies+HZ)){

pr_debug("I2C:timeout\n");if(readb(i2c->base+MPC_I2C_SR)==(CSR_MCF|CSR_MBB|CSR_RXAK))

mpc_i2c_fixup(i2c);return-EIO;}

schedule();}for(i=0;ret>=0&&i<num;i++){

pmsg=&msgs[i];

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

pmsg->flags&I2C_M_RD?"read":"write",

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

ret=mpc_read(i2c,pmsg->addr,pmsg->buf,pmsg->len,i);else

ret=mpc_write(i2c,pmsg->addr,pmsg->buf,pmsg->len,i);}

mpc_i2c_stop(i2c);//保证为I2CCSR[MSTA]为0,保证能触发STOPreturn(ret<0)?ret:num;}staticintmpc_write(structmpc_i2c*i2c,inttarget,constu8*data,intlength,intrestart){inti;unsignedtimeout=i2c->adap.timeout;

u32flags=restart?CCR_RSTA:0;/*StartwithMEN*///以防万一,保证I2C模块使能起来if(!restart)

writeccr(i2c,CCR_MEN);/*Startasmaster*///写了I2CCR[CCR_MSTA],触发CPU发起START信号

writeccr(i2c,CCR_MIEN|CCR_MEN|CCR_MSTA|CCR_MTX|flags);/*Writetargetbyte*///CPU发送一个字节,slaveI2Caddr和0(写操作bit)

writeb((target<<1),i2c->base+MPC_I2C_DR);if(i2c_wait(i2c,timeout,1)<0)//等待slave发ACKreturn-1;for(i=0;i<length;i++){/*Writedatabyte*/

writeb(data[i],i2c->base+MPC_I2C_DR);//CPU接着发数据,包括regaddr和dataif(i2c_wait(i2c,timeout,1)<0)//等待slave发ACKreturn-1;}return0;}staticinti2c_wait(structmpc_i2c*i2c,unsignedtimeout,intwriting){unsignedlongorig_jiffies=jiffies;

u32x;intresult=0;if(i2c->irq==0){//循环读I2CSR,直到I2CSR[MIF]置1while(!(readb(i2c->base+MPC_I2C_SR)&CSR_MIF)){

schedule();if(time_after(jiffies,orig_jiffies+timeout)){

pr_debug("I2C:timeout\n");

writeccr(i2c,0);

result=-EIO;break;}}

x=readb(i2c->base+MPC_I2C_SR);

writeb(0,i2c->base+MPC_I2C_SR);}else{/*Interruptmode*/

result=wait_event_interruptible_timeout(i2c->queue,(i2c->interrupt&CSR_MIF),timeout*HZ);if(unlikely(result<0)){

pr_debug("I2C:waitinterrupted\n");

writeccr(i2c,0);}elseif(unlikely(!(i2c->interrupt&CSR_MIF))){

pr_debug("I2C:waittimeout\n");

writeccr(i2c,0);

result=-ETIMEDOUT;}

x=i2c->interrupt;

i2c->interrupt=0;}if(result<0)returnresult;if(!(x&CSR_MCF)){

pr_debug("I2C:unfinished\n");return-EIO;}if(x&CSR_MAL){//仲裁失败

pr_debug("I2C:MAL\n");return-EIO;}if(writing&&(x&CSR_RXAK)){//写后没收到ACK

pr_debug("I2C:NoRXAK\n");/*generatestop*/

writeccr(i2c,CCR_MEN);return-EIO;}return0;}staticintmpc_read(structmpc_i2c*i2c,inttarget,

u8*data,intlength,intrestart){unsignedtimeout=i2c->adap.timeout;inti;

u32flags=restart?CCR_RSTA:0;/*StartwithMEN*///以防万一,保证I2C模块使能if(!restart)

writeccr(i2c,CCR_MEN);/*Switchtoread-restart*///注意这里,再次把CCR_MSTA置1,再触发START

writeccr(i2c,CCR_MIEN|CCR_MEN|CCR_MSTA|CCR_MTX|flags);/*Writetargetaddressbyte-this

温馨提示

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

评论

0/150

提交评论