I2c总线协议
I2C总线协议及工作原理

I2C总线协议及工作原理I2C总线协议及工作原理之巴公井开创作一、概述1、I2C总线只有两根双向信号线。
一根是数据线SDA,另一根是时钟线SCL。
SCL:上升沿将数据输入到每个EEPROM器件中;下降沿驱动EEPROM器件输出数据。
(边沿触发)SDA:双向数据线,为OD门,与其它任意数量的OD与OC门成"线与"关系。
I2C总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平(SDL=1;SCL=1)。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。
2、主设备与从设备系统中的所有外围器件都具有一个7位的"从器件专用地址码",其中高4位为器件类型,由生产厂家制定,低3位为器件引脚定义地址,由使用者定义。
主控器件通过地址码建立多机通信的机制,因此I2C总线省去了外围器件的片选线,这样无论总线上挂接多少个器件,其系统仍然为简约的二线结构。
终端挂载在总线上,有主端和从端之分,主端必须是带有CPU的逻辑模块,在同一总线上同一时刻使能有一个主端,可以有多个从端,从端的数量受地址空间和总线的最大电容 400pF的限制。
主端主要用来驱动SCL line;从设备对主设备发生响应;二者都可以传输数据,但是从设备不克不及发起传输,且传输是受到主设备控制的。
二、协议1.空闲状态I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。
此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。
2.起始位与停止位的定义:起始信号:当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。
停止信号:当SCL为高期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。
起始和终止信号都是由主机发出的,在起始信号发生后,总线就处于被占用的状态;在终止信号发生后,总线就处于空闲状态。
i2c协议详解

i2c协议详解
I2C(Inter-Integrated Circuit)协议是一种双向串行总线,也称作IIC、TWI(Two-Wire Interface)或SMBus(System Management Bus),由Philips公司于1982年开发,用来连接多个微处理器和其它通信芯片。
I2C协议有两根线,分别是SCL(时钟线)和SDA(数据线),使用双线的好处就是只要两根线就可以完成数据传输,而不需要增加额外的线路,能够大大减少系统所需要的线路,减少系统的复杂度和成本。
I2C协议需要一个主控制器来控制整个系统,主控制器通过SCL线来发送时钟,并通过SDA线来发送和接收数据,从控制器则只负责接收数据。
I2C协议有7个基本信号,START、STOP、ACK、NACK、READ、WRITE和REPEAT START,START在传输数据前发出,STOP则在传输结束后发出,ACK和NACK则用来表示接收方是否正确接收到数据,READ和WRITE则用来指示当前传输的数据是读数据还是写数据,REPEAT START则用来重新开始新一轮的传输。
I2C协议的最大优点是简单、易用,而且可以支持多个从控制器,不过它的缺点也是显而易见的,它的传输速度相对较慢,而且它的传输距离也有限,约在50cm左右。
I2C通讯协议

I2C通讯协议协议名称:I2C通讯协议一、引言I2C(Inter-Integrated Circuit)通讯协议是一种串行通讯协议,用于在集成电路(IC)之间进行数据传输。
本协议旨在定义I2C通讯的标准格式和规范,以确保不同设备之间的互操作性和数据传输的可靠性。
二、定义和缩写词1. I2C总线:用于连接不同设备的双线制串行通讯总线。
2. 主设备(Master):控制I2C总线并发起数据传输的设备。
3. 从设备(Slave):响应主设备请求并进行数据传输的设备。
4. SDA:串行数据线,用于传输数据。
5. SCL:串行时钟线,用于同步数据传输。
6. START:主设备发起数据传输的起始信号。
7. STOP:主设备结束数据传输的终止信号。
8. ACK:从设备发送的应答信号,表示数据传输成功。
9. NACK:从设备发送的非应答信号,表示数据传输失败。
三、协议规范1. 物理连接a. I2C总线由一对双向线路组成:SDA和SCL。
b. SDA和SCL线由上拉电阻连接到VCC电源线。
c. 主设备和从设备通过SDA和SCL线连接。
2. 信号传输a. 通信始于主设备发送START信号,结束于主设备发送STOP信号。
b. 数据传输以字节为单位进行,每个字节由8位数据组成。
c. 数据传输的起始和终止由START和STOP信号标识。
d. 数据传输的时钟由SCL线上的脉冲控制。
e. 数据传输过程中,SDA线上的数据在SCL上升沿之前稳定。
3. 寻址a. 主设备发送设备地址和读/写位来选择要通信的从设备。
b. 设备地址由7位二进制数表示,最高位为0表示写操作,为1表示读操作。
4. 数据传输a. 主设备发送数据时,数据位由高位到低位依次发送。
b. 从设备接收数据时,数据位由高位到低位依次接收。
c. 主设备和从设备在每个字节传输后都会发送ACK信号。
d. 数据传输完毕后,从设备发送ACK信号表示数据接收成功。
5. 错误处理a. 如果主设备在发送数据位后未接收到ACK信号,则表示数据传输失败。
i2c协议

i2c协议1. 简介I2C(Inter-Integrated Circuit)是一种串行通信协议,最初由Philips公司开发,用于在低速设备之间进行通信。
它是一种简单而又有效的通信协议,常被用于连接各种外设,如传感器、显示屏、存储器等。
2. 基本原理I2C协议基于两根总线线路:SDA(Serial Data Line)和SCL(Serial Clock Line)。
SDA线用于数据传输,SCL线用于时钟同步。
在I2C总线上,可以同时连接多个设备,每个设备都有一个唯一的地址。
数据传输是以字节为单位进行的,每个字节都由8个位表示。
在I2C通信中,主设备(master)和从设备(slave)的角色是固定的。
主设备负责发起通信,并控制总线上的时钟信号。
从设备则根据主设备的指令进行响应。
3. 信号传输I2C协议中的信号传输主要分为两种类型:地址传输和数据传输。
3.1 地址传输地址传输用于确定通信的目标设备。
在开始一次通信时,主设备首先发送一个起始信号(Start),然后发送包含目标设备地址和读写方向的字节。
目标设备根据其地址来判断是否需要响应当前通信。
如果地址匹配成功,目标设备会发送一个应答信号(Acknowledge,简称ACK),表示准备好进行数据传输。
如果地址匹配失败或目标设备忙碌,目标设备会发送一个非应答信号(Not Acknowledge,简称NACK)。
3.2 数据传输数据传输是在地址传输成功后进行的。
主设备发送数据或指令时,目标设备必须发送一个应答信号(ACK)作为确认;而当目标设备向主设备传输数据时,主设备则需要发送一个应答信号(ACK)。
数据传输时,每个数据字节都会在时钟的边沿进行传输。
主设备发送数据时,每个数据位都会在时钟的下降沿稳定,目标设备则在时钟的上升沿开始读取数据。
数据传输完成后,主设备会发送一个停止信号(Stop)来结束本次通信。
4. 速度和模式I2C协议支持不同的速度和模式,这取决于设备的类型和要求。
I2C协议

SancyI2C 协议规范I2C 协议规范一. I2C 协议I2C协议是有PHILIPS公司在1992年最先提出,乃PHILIPS公司专利。
只 要购买Philips的I2C元件同时传递了一个在Philips的I2C 专利下, 在I2C 系统 使用元件使系统符合由Philips定义的I2C规范的许可证。
任何使用I2C的元件 都必须得到PHILIPS公司的授权。
二. I2C总线的特征1. 只要求两条总线线路一条串行数据线 (SDA) 一条串行时钟线 (SCL) 。
同时SDL和SCL都是双向线路,分别通过上拉电阻连接到正的电源电压。
2 .每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主 机/从机关系软件设定地址;主机可以作为主机发送器或主机接收器。
3.它是一个真正的多主机总线,如果两个或更多主机同时初始化数据传输 可以通过冲突检测和仲裁防止数据被破坏。
4. 串行的8 位双向数据传输位速率在标准模式下可达100kbit/s。
快速模 式下可达400kbit/s。
高速模式下可达3.4Mbit/s。
5.片上的滤波器可以滤去总线数据线上的毛刺波,保证数据完整。
6.连接到相同总线的IC 数量只受到总线的最大电容400pF 限制。
三. I2C总线的概念I2C两线――串行数据SDA 和串行时钟SCL 线在连接到总线的器件 间传递信息。
每个器件都有一个唯一的地址识别。
无论是微控制器,LCD 驱动器,存储器或键盘接口,都可以作为一个发送器或接收器,由器件的 功能决定。
很明显LCD驱动器只是一个接收器,而存储器则既可以接收又 可以发送数据。
除了发送器和接收器外,器件在执行数据传输时也可以被 看作是主机或从机。
主机是初始化总线的数据传输并产生允许传输的时钟 信号的器件。
此时任何被寻址的器件都被认为是从机。
在I2C总线上,无 论主机是接受方还是发送方,时钟信号永远是主机控制。
四. 总线数据有效性SDA 线上的数据必须在时钟的高电平周期保持稳定。
i2c协议参数

i2c协议参数I2C协议参数I2C总线是一种串行通信协议,由飞利浦公司(现在的恩智浦半导体公司)开发。
它被广泛应用于各种电子设备中,例如传感器、存储器、数字转换器等。
本文将详细介绍I2C协议的各种参数。
一、物理层参数1. 电压:I2C总线标准电平为5V,但也有3.3V和1.8V版本。
不同版本的电压对应着不同的速率和距离限制。
2. 速率:I2C总线有多种速率可供选择,最高达到400kHz。
速率越高,数据传输越快,但同时也会增加误差和干扰。
3. 距离限制:I2C总线的距离限制取决于电压和速率。
在5V电平下,最大距离约为10米;在3.3V电平下,最大距离约为5米。
二、数据帧格式1. 起始位:一个高电平到低电平的转换表示开始一个传输周期。
2. 地址位:7位或10位地址码表示要访问的设备地址。
3. 读写位:一个读写位指示主机是要读取还是写入数据。
4. 应答位:设备在接收到地址位后需要发送一个应答位,表示它已经准备好接收数据。
5. 数据位:8位数据表示要传输的数据。
6. 停止位:一个低电平到高电平的转换表示传输周期结束。
三、时序参数1. SCL时钟频率:SCL时钟频率是I2C总线的主要参数之一,它决定了数据传输速率。
标准模式下,SCL频率为100kHz;快速模式下,SCL频率为400kHz;高速模式下,SCL频率可达到3.4MHz。
2. 数据保持时间(tHD;DAT):数据保持时间是指从SCL时钟的最后一个上升沿到SDA线上数据变化的最小时间间隔。
标准模式下,tHD;DAT为0.1μs;快速模式下,tHD;DAT为0.9μs;高速模式下,tHD;DAT为0.45μs。
3. 数据建立时间(tSU;DAT):数据建立时间是指从SCL时钟的第一个上升沿到SDA线上数据变化的最小时间间隔。
标准模式下,tSU;DAT为0.1μs;快速模式下,tSU;DAT为0.6μs;高速模式下,tSU;DAT为0.25μs。
4. 停止条件保持时间(tSP):停止条件保持时间是指从SCL时钟的最后一个下降沿到SDA线上数据变化的最小时间间隔。
i2c总线协议中文版

i2c总线协议中文版i2c总线协议(中文版)双方基本信息:甲方:________(本协议中简称“甲方”)乙方:________(本协议中简称“乙方”)甲乙双方在平等自愿、公平诚信的基础上,达成以下协议:第一条:各方身份及权利义务1. 甲方:具有独立法人资格的企业/机构/个人,有权利利用i2c总线协议的技术进行数据传输。
2. 乙方:具有独立法人资格的企业/机构/个人,需经甲方授权并遵守本协议规定,方可使用i2c总线协议进行数据传输。
3. 甲方的权利和义务:(1)甲方有权利根据自身业务需求授权乙方使用i2c总线协议。
(2)甲方有义务提供符合要求的i2c总线协议技术使用授权,并提供技术支持、服务维护等后续工作。
(3)甲方需遵守国家相关法律法规,确保i2c总线协议技术的合法性和安全性。
(4)甲方需确保i2c总线协议技术的稳定性,同时积极处理技术问题,保障乙方的正常使用。
4. 乙方的权利和义务:(1)乙方有权利使用甲方授权的i2c总线协议技术进行数据传输。
(2)乙方有义务确保使用i2c总线协议技术时严格遵守本协议及国家、地方的相关法律法规。
(3)乙方须按照甲方要求缴纳使用费用或提供合理的使用补偿。
(4)乙方有义务根据i2c总线协议技术规范进行合法使用、正确操作,同时承担因非法操作而造成的损失和所有法律责任。
第二条:履行方式及期限1. 甲乙双方应在协议签署后尽快履行自身的权利和义务,确保i2c总线协议技术的顺利实施。
2. 甲方应根据乙方需求及使用情况,提供技术支持和维护服务,保障i2c总线协议技术的功能和稳定性。
3. 乙方应在使用i2c总线协议技术前,审慎阅读本协议,了解相关规定和责任,并按照要求进行支付或补偿等合法操作。
第三条:违约责任1. 甲乙双方如有违反合同约定的行为,将承担相应的违约责任。
2. 若甲方未按照协议规定向乙方提供技术支持和维护服务,或因技术问题造成乙方无法正常使用,甲方应承担相应的赔偿责任。
I2C通讯协议介绍

I2C通讯协议介绍I2C(Inter-Integrated Circuit)是一种串行通信协议,由意法半导体(ST Microelectronics)于1980年代提出,用于连接集成电路(IC)之间的通信。
它采用两根线(SDA和SCL)进行数据传输,支持多个设备在同一总线上通信,并且可以实现主从设备之间的通信。
I2C通信协议的特点有以下几个方面:1. 硬件简单:I2C只需要两根信号线,即SDA(数据线)和SCL(时钟线)。
这两根线采用开漏输出(open-drain)方式,可以通过外部上拉电阻连接到正电压,也可以通过外部器件连接到负电压,使得总线上的多个设备可以共享,减少硬件的复杂性。
2.通信方式灵活:I2C支持两种通信方式,即主机模式和从机模式。
在主机模式下,I2C总线由一个主设备进行控制,负责发起通信并传输数据。
从机模式下,I2C总线上的设备可以作为从设备等待主设备的数据传输请求。
这种灵活的通信方式使得I2C协议适用于各种应用场景。
3.多设备共享总线:I2C总线上可以连接多个设备,并且每个设备都有一个唯一的7位地址。
主设备通过发送地址来选择要和之通信的从设备,其他设备会忽略该通信。
这种多设备共享总线的特性使得系统扩展性更强,可以方便地增加更多的设备。
4. 传输速率适中:I2C协议可以支持多种传输速率,包括标准模式(100 kbit/s),快速模式(400 kbit/s),高速模式(3.4 Mbit/s)和超高速模式(5 Mbit/s)。
根据具体应用需求,可以选择合适的传输速率,既能满足通信需求,又能保持传输可靠性。
I2C通信协议的基本传输过程如下:1. 主设备发送起始信号(start):主设备通过将SCL线保持高电平,然后将SDA线从高电平切换到低电平,发送起始信号。
2.主设备发送地址和读/写位:主设备在发送起始信号后,紧接着发送7位从设备地址,最高位指示读还是写操作。
从设备接收到地址后,会进行地址匹配,如果地址匹配成功则进入相应的读或写操作状态。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.I2C协议2条双向串行线,一条数据线SDA,一条时钟线SCL。
SDA传输数据是大端传输,每次传输8bit,即一字节。
支持多主控(multimastering),任何时间点只能有一个主控。
总线上每个设备都有自己的一个addr,共7个bit,广播地址全0.系统中可能有多个同种芯片,为此addr分为固定部分和可编程部份,细节视芯片而定,看datasheet。
1.1 I2C位传输数据传输:SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit;若SDA发生跳变,则用来表示一个会话的开始或结束(后面讲)数据改变:SCL为低电平时,SDA线才能改变传输的bit1.2 I2C开始和结束信号开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
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. Slave发送ACK4. Master发送reg addr(8bit),等待ACK5. Slave发送ACK6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK7. Slave发送ACK8. 第6步和第7步可以重复多次,即顺序写多个寄存器9. Master发起STOP写一个寄存器写多个寄存器1.5 I2C读流程读寄存器的标准流程为:1. 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. Slave发送data(8bit),即寄存器里的值9. Master发送ACK10. 第8步和第9步可以重复多次,即顺序读多个寄存器读一个寄存器读多个寄存器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. 置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 mode TXAK:Transfer acknowledge. 置1时,CPU在9th clock发送ACK拉低SDA RSTA:Repeat START. 置1时,CPU发送REPEAT STARTBCST:置1,CPU接收广播信息(信息的slave addr为7个0)2.4 I2CSR 状态寄存器MCF:0 Byte transfer is in process1 Byte transfer is completedMAAS:当CPU作为Slave时,若I2CDR与会话中Slaveaddr匹配,此bit 被置1MBB:0 I2C bus idle1 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 slave1 Slave transmit, master reading from slaveMIF:Module interrupt. The MIF bit is set when an interrupt is pending,causing a processor interrupt request(provided I2CCR[MIEN] is set) RXAK:若置1,表示收到了ACK2.5 I2CDR 数据寄存器这个寄存器储存CPU将要传输的数据。
3. PPC-Linux中I2C的实现内核代码中,通过I2C总线存取寄存器的函数都在文件drivers/i2c/busses/i2c-mpc.c中最重要的函数是mpc_xfer.1. static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, intnum)2. {3. struct i2c_msg *pmsg;4. int i;5. int ret = 0;6. unsigned long orig_jiffies = jiffies;7. struct mpc_i2c *i2c = i2c_get_adapdata(adap);8.9. mpc_i2c_start(i2c); // 设置I2CCR[MEN], 使能I2C module10.11. /* Allow bus up to 1s to become not busy */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 < num; i++) {30. pmsg = &msgs[i];31. pr_debug("Doing %s %d bytes to 0x%02x - %d of %d messages\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. else38. ret = mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);39. }40. mpc_i2c_stop(i2c); //保证为I2CCSR[MSTA]为0,保证能触发STOP41. return (ret < 0) ? ret : num;42. }1. static int mpc_write(struct mpc_i2c *i2c, int target,2. const u8 * data, int length, int restart)3. {4. int i;5. unsigned timeout = i2c->adap.timeout;6. u32 flags = restart ? CCR_RSTA : 0;7.8. /* Start with MEN */ //以防万一,保证I2C模块使能起来9. if (!restart)10. writeccr(i2c, CCR_MEN);11. /* Start as master */ //写了I2CCR[CCR_MSTA],触发CPU发起START信号12. writeccr(i2c, CCR_MIEN | CCR_MEN | 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. if (i2c_wait(i2c, timeout, 1) < 0) //等待slave 发ACK17. return -1;18.19. for (i = 0; i < length; i++) {20. /* Write data byte */21. writeb(data[i], i2c->base + MPC_I2C_DR); //CPU接着发数据,包括regaddr和data22.23. if (i2c_wait(i2c, timeout, 1) < 0) //等待slave 发ACK24. return -1;25. }26.27. return 0;28. }1. static int i2c_wait(struct mpc_i2c *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. { //循环读I2CSR,直到I2CSR[MIF]置19. 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. /* Interrupt mode */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: wait interrupted\n");27. writeccr(i2c, 0);28. } else if (unlikely(!(i2c->interrupt & CSR_MIF))) {29. pr_debug("I2C: wait timeout\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. return result;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)) {//写后没收到ACK52. pr_debug("I2C: No RXAK\n");53. /* generate stop */54. writeccr(i2c, CCR_MEN);55. return -EIO;56. }57. return 0;58. }1. static int mpc_read(struct mpc_i2c *i2c, int target,2. u8 * data, int length, int restart)3. {4. unsigned timeout = i2c->adap.timeout;5. int i;6. u32 flags = restart ? CCR_RSTA : 0;7.8. /* Start with MEN */ //以防万一,保证I2C模块使能9. if (!restart)10. writeccr(i2c, CCR_MEN);11. /* Switch to read - restart */12. //注意这里,再次把CCR_MSTA置1,再触发START13. writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);14.15.16. /* 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);//等待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. else //为什么不置TXAK8. writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA);9. /* Dummy read */10. readb(i2c->base + MPC_I2C_DR);11. }12.13. for (i = 0; i < length; i++) {14. if (i2c_wait(i2c, timeout, 0) < 0)15. return -1;16.17. /* Generate txack on next to last byte */18. //注意这里TXAK置1,表示CPU每收到1byte数据后,会发送ACK19. if (i == length - 2)20. writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);21.22. /* Generate stop on last byte */23. //注意这里CCR_MSTA [1->0] CPU会触发STOP24. 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. return length;31. }。