I2C通讯 面面谈(一)

在现在的SOC的系统中,很多控制器都渐渐往MCU里面集成,仅一些简单的外设与MCU通讯,那么这样的通讯中,使用I2C协议是很多外设与MCU通讯协议的选择。在嵌入式设备中常见的TP,BatteryIC Sensor类等器件基本上都是使用I2C通讯协议,所以在平台开发和调试中I2C协议的使用是绕不开的内容。
在这篇文章中,我暂时不分析Linux内核I2C子系统代码的实现,仅结合实际例子讲讲通讯的过程。
1,Prepare
Platform:RK3188
Devices:ISL29023(LightSensor)
Tools:Scoper
2,什么是I2C协议?
网上资料比较多,我不赘述。可以参考: http://www.robot-electronics.co.uk/acatalog/I2C_Tutorial.html
3,ISL29023I2C通讯的规格。
读字节:
写字节:

4,在软件中设置一次读02/03寄存器的操作,读取的结果为0x0001。
根据DataSheet,光感的值是是一个长整型,使用2个寄器来存放,即02/03reg。02reg是低8位,03reg是高8位,组合为Value03reg+Value02reg
这是代码片断:read_reg就是设置为Data reg 0x02寄存器,red_len为2。
这是打印的结果:
5,通讯协议结合波形分析。
图1:
1),Clk为高,Dat由高拉低,这是主控发起的一个开始信号。
2),接下来发送一个7位的I2C从设备地址+读写位,即1000100 0,即从设备地址为0x44,即ISL29023的地址
3),接下来的Clk为低,Dat为高,这是一个ACK信号。请参考DataSheet有说明。
图2:
接下来就是发送一个要操作的寄存器地址0x02,与我们软件操作的相符。
图3:
每次发送完8位之后总需要有一个ACK信号来回答,如上图,第一个红框是发送完REG地址之后的ACK信号,如果有ACK信号,那么主控又会发起一次开始信号,如果没有ACK信号,即从设备没有应答,那么主设备接下来就是改善结束信号。上图很显示是有正常的ACK信号,所以,紧接着是一个开始信号。
图4:
发送完开始信号,紧接着就是发送从设备地址+一个读位,即1000 1001。
图5:
1),接下来首先是发送一个ACK信号,可能注意到了,这个ACK是当Clk为低,Dat为低,这个跟之前的ACK不一样,你可以看DataSheet来Check。
两次ACK信号不一样,这是应该是协议规定的,但,我还需要确认。同时确认了,发送8位之后,就需要有一个ACK信号
2),接下来就是0x02寄器的地址,0x01.
图6:
1),同理,第一个红框是上一个数据的ACK。
2),因为在函数里是两2个寄存器,所以,紧接着是一个0x03寄存器的8位数据,值为0x00。
图7:
1),第一个红框,应该是有一个ACK信息,但这不是一个ACK信息,因为在结束信号之后,就没有ACK信号,合并在一起了。我想我没有信口开河,因为我之前确认过I2C协议,请您帮我确认。
2),第二个红框,完成了通讯,就发送一个结束信号,即当Clk为高时,Dat由低拉高。结束。

到此,0x02REG的值:0x01;0x03REG的值:0x00,组合一起为0x0001,即与我们最开始打印的相符。

下一讲,Linux I2C通讯子系统


Logo

更多推荐