嵌入式 I2C总线协议
2019-07-13 02:18发布
生成海报
制作嵌入式linux文件系统(ramdisk,cramfs,squashfs)
Linux驱动程序框架
I2C总线详细介绍
2010-10-30 18:26:44| 分类:
面试总结 | 标签:
|字号大中小
订阅
I2C是一种串行总线的外设接口,它采用同步方式串行接收或发送信息,两个设备在同一个时钟下工作。I2C总线只用两根线:串行数据SDA(Serial
Data)、串行时钟SCL(Serial Clock)。
由于I2C只有一根数据线,因此其发送信息和接收信息不能同时进行。信息的发送和接收只能分时进行。I2C串行总线工作时传输速率最高可达400K
bit/s。
I2C总线上的所有器件的SDA线并接在一起,所有器件的SCL线并接在一起,且SDA线和SCL线必须通过上拉电阻连接到正电源。
I2C总线的数据传输协议要比SPI总线复杂一些,因为I2C总线器件没有片选控制线,所以I2C总线数据传输的开始必须由主器件产生通信的开始条件(SCL高电平时,SDA产生负跳变);通信结束时,由主器件产生通信的结束条件(SCL高电平时,SDA产生正跳变)。
SDA线上的数据在SCL高电平期间必须保持稳定,否则会被误认为开始条件或结束条件,只有在SCL低电平期间才能改变SDA线上的数据。I2C总线的数据传输波形图如下图所示。
I2C应用实例
AT24C系列为美国ATMEL公司推出的串行COMS型E2PROM,具有功耗小,宽电压范围等优点。下图为AT24C系列E2PROM的引脚图。图中A0、A1、A2为器件地址引脚,Vss为地,Vcc为正电源,WP为写保护,SCL为串行时钟线,SDA为串行数据线。AT24C系列E2PROM采用I2C总线,I2C总线上可挂接多个接口器件,在I2C总线上的每个器件应有唯一的器件地址,按I2C总线规则,器件地址为7位二进制数,它与一位数据方向位构成一个器件寻址字节。器件寻址字节的最低位(D0)为方向位(读/写),最高4位(D7~D4)为器件型号地址(不同的I2C总线接口器件的型号地址由厂家给定,AT24C系列E2PROM的型号地址都为1010);其余3位(D3~D1)与器件引脚地址A2A1A0相对应。器件地址格式:
1010 A2A1A0。
对于E2PROM的片内地址,AT24C01和AT24C02由于芯片容量可用一个字节表示,故读写某个单元前,先向E2PROM写入一个字节的器件地址,再写入一个字节的片内地址。而AT24C04、AT24C08、AT24C16分别需要9位、10位和11位片内地址,所以AT24C04把器件地址中的A0作为片内地址的最高位,AT24C08把器件地址中的A1A0作为片内地址的最高两位,AT24C16把器件地址中的A2A1A0作为片内地址的最高三位。凡在系统中把器件的引脚地址用作片内地址后,该引脚在电路中不得使用,做悬空处理。AT24C32、AT24C64、AT24C128、AT24C256和AT24C512的片内地址采用两个字节。
AT24C系列E2PROM的读写操作原理
下列读写操作中SDA线上数据传送状态标记注释如下:
Start为启动信号(SCL为高电平,SDA产生负跳变),由主机发送。
Stop为结束信号(SCL为高电平,SDA产生正跳变),由主机发送。
AddressByte、AddreeeByte H、AddreeeByte
L为地址字节,指定片内某单元地址,由主机发送。
data为数据字节,由数据发送方发送。
0
为肯定应答信号,由数据接收方发送。
1
为否定应答信号,由数据接收方发送。
主机控制数据线SDA时,在SCL高电平期间必须保持SDA线上的数据稳定,否则会被误认为对从机的起始条件或结束条件。主机只能在SCL低电平期间改变SDA线上的数据。主机写操作期间,用SCL的上升沿写入数据;主机读操作期间,用SCL的下降沿读出数据。
从AT24C系列AT24C01~AT24C16中读n个字节的数据格式:
从AT24C系列AT24C32~AT24C512中读n个字节的数据格式:
向AT24C系列AT24C01~AT24C16中写n个字节的数据格式(n<=页长,且n个字节不能跨页):
向AT24C系列AT24C32~AT24C512中写n个字节的数据格式(n<=页长,且n个字节不能跨页):
应答信号
I2C总线数据传送时,每成功地传送一个字节数据后,接收器都必须产生一个应答信号。应答的器件在第9个时钟周期时将SDA线拉低,表示其已经收到一个8位数据。
I2C器件在接收到起始信号和从器件地址之后响应一个应答信号,如果器件已选择了写操作,则在每接收一个8位字节之后响应一个应答信号。
I2C器件工作在读模式时,在发送一个8位数据后释放SDA线(SDA置为高电平)并监视一个应答信号,一旦接收到主器件的应答信号,I2C器件则继续发送数据,如果主器件没有发送应答信号(发送非应答信号,即SDA为高电平),器件停止传送数据且等待一个停止信号。
1.I2C协议
2条双向串行线,一条数据线SDA,一条时钟线SCL。
SDA传输数据是大端传输,每次传输8bit,即一字节。
支持多主控(multimastering),任何时间点只能有一个主控。
总线上每个设备都有自己的一个addr,共7个bit,广播地址全0.
系统中可能有多个同种芯片,为此addr分为固定部分和可编程部份,细节视芯片而定,看datasheet。
1.1 I2C位传输
数据传输:SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit;
若SDA发生跳变,则用来表示一个会话的开始或结束(后面讲)
数据改变:SCL为低电平时,SDA线才能改变传输的bit
1.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发起START
2. Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
3. Slave发送ACK
4. Master发送reg addr(8bit),等待ACK
5. Slave发送ACK
6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK
7. Slave发送ACK
8. 第6步和第7步可以重复多次,即顺序写多个寄存器
9. Master发起STOP
写一个寄存器
写多个寄存器
1.5 I2C读流程
读寄存器的标准流程为:
1. Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
2. Slave发送ACK
3. Master发送reg addr(8bit),等待ACK
4. Slave发送ACK
5. Master发起START
6. Master发送I2C addr(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个。
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 START
BCST:置1,CPU接收广播信息(信息的slave addr为7个0)
2.4 I2CSR 状态寄存器
MCF:0 Byte transfer is in process
1 Byte transfer is completed
MAAS:当CPU作为Slave时,若I2CDR与会话中Slaveaddr匹配,此bit被置1
MBB:0 I2C bus idle
1 I2C bus busy
MAL:若置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 slave
1 Slave transmit, master reading from slave
MIF:Module interrupt. The MIF bit is set when an interrupt is pending, causing a processor interrupt request(provided I2CCR[MIEN] is set)
RXAK:若置1,表示收到了ACK
2.5 I2CDR 数据寄存器
这个寄存器储存CPU将要传输的数据。
3. PPC-Linux中I2C的实现
内核代码中,通过I2C总线存取寄存器的函数都在文件drivers/i2c/busses/i2c-mpc.c中
最重要的函数是mpc_xfer.
- static
int
mpc_xfer(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], 使能I2C module
- //一直读I2CSR[MBB],等待I2C总线空闲下来
- while
(readb(i2c->base
+
MPC_I2C_SR)
&
CSR_MBB)
{
- if
(signal_pending(current))
{
- pr_debug("I2C:
Interrupted
");
- writeccr(i2c,
0);
- return
-EINTR;
- }
- if
(time_after(jiffies,
orig_jiffies
+
HZ))
{
- pr_debug("I2C:
timeout
");
- 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
&
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮