全部博文(105)
分类: 嵌入式
2016-07-14 09:13:44
最新在开发OLED屏驱动,需要用到I2C总线,下面大体上讲解一下I2C设备的调试及波形分析,为大家做一些参考,由于刚涉及这部分内容,因此有什么错误的,还请赐教~
一、概要
I2C总线只需要两条线,一条SDA数据线,一条SCL时钟线;根据这两条线的高低电平、上升沿、下降沿就可以实现主机与I2C设备的通讯;其中有:
(1)I2C总线相关
传输开始条件:SCL处于高电平,SDA下降沿时;
传输接收条件:SCL处于高电平,SDA上升沿时;
传输数据:开始传输后,SCL处于高电平时,SDA的数据为所传输的数据;
回应:当传输完一个字节后,I2C设备需要回应一个ACK,这样主机才继续发送;因此回应信号是在传输完8bit后的下一个数据位(SDA值),当SDA为0表示有回应,为1表示没回应;
正常I2C总线的数据是:Start + I2C devece id + R/W + ACK + Data(first byte)+ ACK + ... + Data(n)+ ACK + Stop
(2)I2C设备相关
设备地址:有7位和10位两种,具体见I2C设备芯片的DataSheet,由于目前用到的是7位,因此下面主要针对7位讲述;在讲I2C设备地址是有可能有两种说法,主要是用8位表示还是用7为表示,比如对于我的OLED来说,当用8位表示时则为0x78地址,当用7位时则为0x3c(即0x78右移1为),在驱动中用0x78还是用0x3c要看具体平台的I2C总线驱动,我在AMLOGIC平台上用的是0x78,而在MV平台上用的是0x3c;
寄存器reg:一般的I2C设备芯片都有带reg,一般在传输正式的数据之前需要先传输reg地址,比如我的OLED来说,在传控制命令时需要先发送0x00的reg地址,在传输数据时需要发送0x40的reg地址;
二、调试及波形分析
一般当我们拿到一个I2C设备时,就必须涉及到驱动的编写,就比如对于OLED来说,就要用编写OLED驱动,这样我们才能控制它,对于OLED屏来说,第一步也是最重要的一步就是点亮它;当我们做完这一步,那后面剩下的就只是细节问题了;”万事开头难“,这句话真的不假,对于OLED来说,如何才能点亮,我们该怎么调试呢?当我们写完OLED驱动,但OLED屏还是不亮,可能问题会出现在哪?是硬件问题还是软件问题?;若为软件问题,那会是I2C总线驱动问题,还是我们I2C设备驱动有问题?那么我们该如何判断问题出现位置呢?这就需要我们对I2C总线上的数据进行分析;那么下面我将详细讲述如何获取和分析I2C总线上的数据;
(1)示波器
对于I2C总线的数据,我们要用到示波器,这样我们才能抓取到信号,而且必须同时采集SDA和SCL的数据;该如何抓取呢?我这边的方式是将示波器调成边下降沿触发模式(因为开始信号是SDA下降沿),并且设置成单次模式(这样抓取完一次就会stop,便于我们数据分析);
(2)波形
由于我的OLED设备的地址是0x78(8位),而第一次我必须将OLED设置成off状态,通过命令表可以查到,必须发生0xAE,而刚刚有讲到在发送命令前必须先发送寄存器reg地址,即0x00;于是我发送的数据为0x78+0x00+0xAE;下面是我用示波器抓取到的波形:
分析(其中黄色的为SDA信号,浅蓝色为SCL信号):从上述波形中我们可以读取到数据依次是:01111000 0 00000000 101011100;即:0111100(7位OLED设备地址) + 0( 读写为,0为写,1为读)+0(ACK回应)+00000000(寄存器reg)+ 10101110(0xAE OLED off命令);(这里还有一点我还没弄明白就是reg后没有回应,还望大家不吝赐教)
下面当我来随便发送一个地址时,比如当我发送0x56(8位地址),测到的波形如下:
分析:从波形可看出数据依次为:010101101 即0101011(设备地址)+0(读写位)+1(NACK无应答),由于没有相应的I2C设备因此无应答ACK信号,于是就停止传输;
三、总结
由以上可知,可以通过查看I2C总线数据来确认跟踪I2C设备,已更好地确定是软件问题还是硬件问题;