I2c总线协议.docx
- 文档编号:9107876
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:14
- 大小:262.72KB
I2c总线协议.docx
《I2c总线协议.docx》由会员分享,可在线阅读,更多相关《I2c总线协议.docx(14页珍藏版)》请在冰豆网上搜索。
I2c总线协议
协议
2条双向串行线,一条数据线SDA,一条时钟线SCL。
SDA传输数据是大端传输,每次传输8bit,即一字节。
支持多主控(multimastering),任何时间点只能有一个主控。
总线上每个设备都有自己的一个addr,共7个bit,广播地址全0.
系统中可能有多个同种芯片,为此addr分为固定部分和可编程部份,细节视芯片而定,看datasheet。
I2C位传输
数据传输:
SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit;
若SDA发生跳变,则用来表示一个会话的开始或结束(后面讲)
数据改变:
SCL为低电平时,SDA线才能改变传输的bit
I2C开始和结束信号
开始信号:
SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:
SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
I2C应答信号
Master每发送完8bit数据后等待Slave的ACK。
即在第9个clock,若从IC发ACK,SDA会被拉低。
若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示:
I2C写流程
写寄存器的标准流程为:
1.Master发起START
2.Master发送I2Caddr(7bit)和w操作0(1bit),等待ACK
3.Slave发送ACK
4.Master发送regaddr(8bit),等待ACK
5.Slave发送ACK
6.Master发送data(8bit),即要写入寄存器中的数据,等待ACK
7.Slave发送ACK
8.第6步和第7步可以重复多次,即顺序写多个寄存器
9.Master发起STOP
写一个寄存器
写多个寄存器
I2C读流程
读寄存器的标准流程为:
1.Master发送I2Caddr(7bit)和w操作1(1bit),等待ACK
2.Slave发送ACK
3.Master发送regaddr(8bit),等待ACK
4.Slave发送ACK
5.Master发起START
6.Master发送I2Caddr(7bit)和r操作1(1bit),等待ACK
7.Slave发送ACK
8.Slave发送data(8bit),即寄存器里的值
9.Master发送ACK
10.第8步和第9步可以重复多次,即顺序读多个寄存器
读一个寄存器
读多个寄存器
2.PowerPC的I2C实现
Mpc8560的CCSR中控制I2C的寄存器共有6个。
I2CADR地址寄存器
CPU也可以是I2C的Slave,CPU的I2C地址有I2CADR指定
I2CFDR频率设置寄存器
TheserialbitclockfrequencyofSCLisequaltotheCCBclockdividedbythedivider.
用来设置I2C总线频率
I2CCR控制寄存器
MEN:
ModuleEnable.置1时,I2C模块使能
MIEN:
ModuleInterruptEnable.置1时,I2C中断使能。
MSTA:
Master/slavemode.1Mastermode,0Slavemode.
当1->0时,CPU发起STOP信号
当0->1时,CPU发起START信号
MTX:
Transmit/receivemodeReceivemode,1Transmitmode
TXAK:
Transferacknowledge.置1时,CPU在9thclock发送ACK拉低SDA
RSTA:
RepeatSTART.置1时,CPU发送REPEATSTART
BCST:
置1,CPU接收广播信息(信息的slaveaddr为7个0)
I2CSR状态寄存器
MCF:
0Bytetransferisinprocess
1Bytetransferiscompleted
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
I2CDR数据寄存器
这个寄存器储存CPU将要传输的数据。
3.PPC-Linux中I2C的实现
内核代码中,通过I2C总线存取寄存器的函数都在文件drivers/i2c/busses/中
最重要的函数是mpc_xfer.
1.staticintmpc_xfer(structi2c_adapter*adap,structi2c_msg*msgs,intnum)
2.{
3.structi2c_msg*pmsg;
4.inti;
5.intret=0;
6.unsignedlongorig_jiffies=jiffies;
7.structmpc_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.if(time_after(jiffies,orig_jiffies+HZ)){
20.pr_debug("I2C:
timeout\n");
21.if(readb(i2c->base+MPC_I2C_SR)==
22.(CSR_MCF|CSR_MBB|CSR_RXAK))
23.mpc_i2c_fixup(i2c);
24.return-EIO;
25.}
26.schedule();
27.}
28.
29.for(i=0;ret>=0&&i 30.pmsg=&msgs[i]; 31.pr_debug("Doing%s%dbytesto0x%02x-%dof%dmessages\n", 32.pmsg->flags&I2C_M_RD"read": "write", 33.pmsg->len,pmsg->addr,i+1,num); 34.//根据消息里的flag进行读操作或写操作 35.if(pmsg->flags&I2C_M_RD) 36.ret=mpc_read(i2c,pmsg->addr,pmsg->buf,pmsg->len,i); 37.else 38.ret=mpc_write(i2c,pmsg->addr,pmsg->buf,pmsg->len,i); 39.} 40.mpc_i2c_stop(i2c);//保证为I2CCSR[MSTA]为0,保证能触发STOP 41.return(ret<0)ret: num; 42.} 1.staticintmpc_write(structmpc_i2c*i2c,inttarget, 2.constu8*data,intlength,intrestart) 3.{ 4.inti; 5.unsignedtimeout=i2c->; 6.u32flags=restartCCR_RSTA: 0; 7. 8./*StartwithMEN*///以防万一,保证I2C模块使能起来 9.if(! restart) 10.writeccr(i2c,CCR_MEN); 11./*Startasmaster*///写了I2CCR[CCR_MSTA],触发CPU发起START信号 12.writeccr(i2c,CCR_MIEN|CCR_MEN|CCR_MSTA|CCR_MTX|flags); 13./*Writetargetbyte*///CPU发送一个字节,slaveI2Caddr和0(写操作bit) 14.writeb((target<<1),i2c->base+MPC_I2C_DR); 15. 16.if(i2c_wait(i2c,timeout,1)<0)//等待slave发ACK 17.return-1; 18. 19.for(i=0;i 20./*Writedatabyte*/ 21.writeb(data[i],i2c->base+MPC_I2C_DR);//CPU接着发数据,包括regaddr和data 22. 23.if(i2c_wait(i2c,timeout,1)<0)//等待slave发ACK 24.return-1; 25.} 26. 27.return0; 28.} 1.staticinti2c_wait(structmpc_i2c*i2c,unsignedtimeout,intwriting) 2.{ 3.unsignedlongorig_jiffies=jiffies; 4.u32x; 5.intresult=0; 6. 7.if(i2c->irq==0) 8.{//循环读I2CSR,直到I2CSR[MIF]置1 9.while(! (readb(i2c->base+MPC_I2C_SR)&CSR_MIF)){ 10.schedule(); 11.if(time_after(jiffies,orig_jiffies+timeout)){ 12.pr_debug("I2C: timeout\n"); 13.writeccr(i2c,0); 14.result=-EIO; 15.break; 16.} 17.} 18.x=readb(i2c->base+MPC_I2C_SR); 19.writeb(0,i2c->base+MPC_I2C_SR); 20.}else{ 21./*Interruptmode*/ 22.result=wait_event_interruptible_timeout(i2c->queue, 23.(i2c->interrupt&CSR_MIF),timeout*HZ); 24. 25.if(unlikely(result<0)){ 26.pr_debug("I2C: waitinterrupted\n"); 27.writeccr(i2c,0); 28.}elseif(unlikely(! (i2c->interrupt&CSR_MIF))){ 29.pr_debug("I2C: waittimeout\n"); 30.writeccr(i2c,0); 31.result=-ETIMEDOUT; 32.} 33. 34.x=i2c->interrupt; 35.i2c->interrupt=0; 36.} 37. 38.if(result<0) 39.returnresult; 40. 41.if(! (x&CSR_MCF)){ 42.pr_debug("I2C: unfinished\n"); 43.return-EIO; 44.} 45. 46.if(x&CSR_MAL){//仲裁失败 47.pr_debug("I2C: MAL\n"); 48.return-EIO; 49.} 50. 51.if(writing&&(x&CSR_RXAK)){//写后没收到ACK 52.pr_debug("I2C: NoRXAK\n"); 53./*generatestop*/ 54.writeccr(i2c,CCR_MEN); 55.return-EIO; 56.} 57.return0; 58.} 1.staticintmpc_read(structmpc_i2c*i2c,inttarget, 2.u8*data,intlength,intrestart) 3.{ 4.unsignedtimeout=i2c->; 5.inti; 6.u32flags=restartCCR_RSTA: 0; 7. 8./*StartwithMEN*///以防万一,保证I2C模块使能 9.if(! restart) 10.writeccr(i2c,CCR_MEN); 11./*Switchtoread-restart*/ 12.//注意这里,再次把CCR_MSTA置1,再触发START 13.writeccr(i2c,CCR_MIEN|CCR_MEN|CCR_MSTA|CCR_MTX|flags); 14. 15. 16./*Writetargetaddressbyte-thistimewiththereadflagset*/ 17.//CPU发送slaveI2Caddr和读操作1 18.writeb((target<<1)|1,i2c->base+MPC_I2C_DR); //等待Slave发ACK 1.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.else//为什么不置TXAK 8.writeccr(i2c,CCR_MIEN|CCR_MEN|CCR_MSTA); 9./*Dummyread*/ 10.readb(i2c->base+MPC_I2C_DR); 11.} 12. 13.for(i=0;i 14.if(i2c_wait(i2c,timeout,0)<0) 15.return-1; 16. 17./*Generatetxackonnexttolastbyte*/ 18.//注意这里TXAK置1,表示CPU每收到1byte数据后,会发送ACK 19.if(i==length-2) 20.writeccr(i2c,CCR_MIEN|CCR_MEN|CCR_MSTA|CCR_TXAK); 21. 22./*Generatestoponlastbyte*/ 23.//注意这里CCR_MSTA[1->0]CPU会触发STOP 24.if(i==length-1) 25.writeccr(i2c,CCR_MIEN|CCR_MEN|CCR_TXAK); 26. 27.data[i]=readb(i2c->base+MPC_I2C_DR); 28.} 29. 30.returnlength; 31.}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- I2c 总线 协议
![提示](https://static.bdocx.com/images/bang_tan.gif)