-.z.1.I2C协议 2条双向串行线,一条数据线SDA,一条时钟线SCL。 SDA传输数据是大端传输,每次传输8bit,即一字节。支持多主控(multimastering),任何时间点只能有一个主控。总线上每个设备都有自己的一个addr,共7个bit,播送地址全0. 系统中可能有多个同种芯片,为此addr分为固定局部和可编程部份,细节视芯片而定,看datasheet。1.1I2C位传输数据传输:SCL为高电平时,SDA线假设保持稳定,则SDA上是在传输数据bit;假设SDA发生跳变,则用来
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
示一个会话的开场或完毕〔后面讲〕数据改变: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写流程写存放器的
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
流程为: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步可以重复屡次,即顺序读多个存放器读一个存放器读多个存放器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信号MT*:Transmit/receivemodeselect.0Receivemode,1TransmitmodeT*AK:Transferacknowledge.置1时,CPU在9thclock发送ACK拉低SDARSTA:RepeatSTART.置1时,CPU发送REPEATSTARTBCST:置1,CPU接收播送信息〔信息的slaveaddr为7个0〕2.4I2CSR状态存放器MCF:0 Bytetransferisinprocess 1 BytetransferispletedMAAS:当CPU作为Slave时,假设I2CDR与会话中Slaveaddr匹配,此bit被置1MBB:0I2Cbusidle 1I2CbusbusyMAL:假设置1,表示仲裁失败BCSTM:假设置1,表示接收到播送信息SRW:WhenMAASisset,SRWindicatesthevalueoftheR/Wmandbitofthecallingaddress,whichissentfromthemaster. 0Slavereceive,masterwritingtoslave 1Slavetransmit,masterreadingfromslaveMIF:Moduleinterrupt.TheMIFbitissetwhenaninterruptispending,causingaprocessorinterruptrequest(providedI2CCR[MIEN]isset)R*AK:假设置1,表示收到了ACK2.5I2CDR数据存放器这个存放器储存CPU将要传输的数据。3.PPC-Linu*中I2C的实现核代码中,通过I2C总线存取存放器的函数都在文件drivers/i2c/busses/i2c-mpc.c中最重要的函数是mpc_*fer. static int mpc_*fer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num){ struct i2c_msg *pmsg; int i; int ret = 0; unsigned long orig_jiffies = jiffies; struct mpc_i2c *i2c = i2c_get_adapdata(adap); mpc_i2c_start(i2c); //设置I2CCR[MEN],使能I2Cmodule /*Allowbusupto1stobeenotbusy*/ //一直读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_R*AK)) mpc_i2c_fi*up(i2c); return -EIO; } schedule(); } for (i = 0; ret >= 0 && i < num; i++) { pmsg = &msgs[i]; pr_debug("Doing%s%dbytesto0*%02*-%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,保证能触发STOP return (ret < 0) " ret : num;}static int mpc_write(struct mpc_i2c *i2c, int target, const u8 * data, int length, int restart){ int i; unsigned timeout = 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_MT* | flags); /*Writetargetbyte*/ //CPU发送一个字节,slaveI2Caddr和0(写操作bit) writeb((target << 1), i2c->base + MPC_I2C_DR); if (i2c_wait(i2c, timeout, 1) < 0) //等待slave发ACK return -1; for (i = 0; i < length; i++) { /*Writedatabyte*/ writeb(data[i], i2c->base + MPC_I2C_DR); //CPU接着发数据,包括regaddr和data if (i2c_wait(i2c, timeout, 1) < 0) //等待slave发ACK return -1; } return 0;}static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing){ unsigned long orig_jiffies = jiffies; u32*; int result = 0; if (i2c->irq == 0) { //循环读I2CSR,直到I2CSR[MIF]置1 while (!(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; } } * = 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); } else if (unlikely(!(i2c->interrupt & CSR_MIF))) { pr_debug("I2C:waittimeout\n"); writeccr(i2c, 0); result = -ETIMEDOUT; } * = i2c->interrupt; i2c->interrupt = 0; } if (result < 0) return result; if (!(* & CSR_MCF)) { pr_debug("I2C:unfinished\n"); return -EIO; } if (* & CSR_MAL) { //仲裁失败 pr_debug("I2C:MAL\n"); return -EIO; } if (writing && (* & CSR_R*AK)) {//写后没收到ACK pr_debug("I2C:NoR*AK\n"); /*generatestop*/ writeccr(i2c, CCR_MEN); return -EIO; } return 0;}static int mpc_read(struct mpc_i2c *i2c, int target, u8 * data, int length, int restart){ unsigned timeout = i2c->adap.timeout; int i; 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_MT* | flags); /*Writetargetaddressbyte-thistimewiththereadflagset*/ //CPU发送slaveI2Caddr和读操作1 writeb((target << 1) | 1, i2c->base + MPC_I2C_DR); //等待Slave发ACK if (i2c_wait(i2c, timeout, 1) < 0) return -1; if (length) { if (length == 1) writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_T*AK); else //为什么不置T*AK writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA); /*Dummyread*/ readb(i2c->base + MPC_I2C_DR); } for (i = 0; i < length; i++) { if (i2c_wait(i2c, timeout, 0) < 0) return -1; /*Generatet*ackonne*ttolastbyte*/ //注意这里T*AK置1,表示CPU每收到1byte数据后,会发送ACK if (i == length - 2) writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_T*AK); /*Generatestoponlastbyte*/ //注意这里CCR_MSTA[1->0]CPU会触发STOP if (i == length - 1) writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_T*AK); data[i] = readb(i2c->base + MPC_I2C_DR); } return length;}