IIC 之深入理解原理

来源:互联网 发布:学霸精软件下载 编辑:程序博客网 时间:2024/06/06 05:51
//  秉着  授人之鱼 不如授人之渔的态度。 本人决定 在以后的日子里,着重讲思想。   
/*通过写iic ,得出以后调协议类 程序的方法。
1: 如果该协议不能够工作 ,首先需要一台示波器,将其两个通道分别挂在 时钟线和数据线上。注意:在挂示波器的同时 
也要讲你的从机挂载上,便于从机的应答信号和数据可以在示波器上显示出来 。(如果io口输出不接任何设备,只接了示波器,则从示波器中只能检测到发射数据)
2: 先从最简单的函数开始, 就拿模拟iic 来说, 将 I2c_Start() 放入主函数中, 主函数 除了 喂狗(防止单片机重复复位)
 以外,再加一个 delay延时函数(为了方便示波器观察数据)
3: 将起始信号的时序图找出来(网上iic协议介绍里边都有),对比示波器上的 波形,如果完全吻合,ok,这个函数没有问题,然后依次对比以后的函数。
4: 一般情况下,在测试的过程中,时钟线上  不管发射信号还是接收信号还是应答信号 都能够在示波器上显示出来(前提是你的硬件接法没有错误)
5:  修正上述测试出现的问题后。 从新运行程序,读取 从设备的 地址位(一般该位 为一个定值,如mpu6050的默认地址为0x68)。如果能够读出数据,则说明iic
已经正常工作了。 
6:另外: 由于本人之前的粗心,将读字节 函数中检测的io口误写成了 别的管脚,导致示波器看抓取的波形是正常的,但单片机io口捕获不到数据,后来经过推理找到了

问题的源头, 以后写程序一定要小心。。


以上是我在半年前写mpu6050驱动时用iic 的调试感悟 。  但是 在半年后的今天, 在另一块单片机上又要用到iic 需要自己写(用另一种语言)的时候又出现问题 通信不成功的现象 ,我 用示波器看了下波形,波形是正常的,但是SDA 的 高电平脉冲在2V左右 (被6050拉低了)。而且也读取不出来信号 如左图所示。当前示波器一格为2V  ,蓝色的线为 SDA ,黄色的线为SCL,从上图看出,按照时序检查跳变沿,发现 时钟数据 都是正确的,但就是读不出数据 (如上图所示,如果画圈部分的电平拉高到正常就读取正常了)。(用的是mpu6050模块 ,iic的上拉电阻为4.7K。 把sda线跟6050断开 ,电平又能回到3.3V) 。刚开始一直以为是因为软件的原因 。 然后就一直再看协议,在改时序 。。到最后还是不能通信 。最后 感觉真没办法了,就又弄了一个mpu6050换上试了下,正常工作了。。 从而得出结论:SDA线被拉低到2V,明显是 硬件原因 。 说明之前的mpu6050 已坏。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

iic协议知识讲解

注意 :iic  协议的 时序即器件地址+应答信号 +。。。。。+停止码  , 这是iic的物理协议,即 只要用iic 都要遵循 该时序要求。

1:iic的开始和结束信号

单片机与24C02的通讯

2:IIC的应答信号:无论主从,每接收1个字节都要给出1个应答信号

单片机与24C02的通讯


3:IIc的读写:只有在SCL置低时,方可改变SDA的值,在SCL高电平期间,SDA需保持不变

 A.写入单个字节

单片机与24C02的通讯

 

B.连续写入字节,当写入到该页最后一个地址单元时,再从该页的起始单元写入,如此反复。

单片机与24C02的通讯 

C.AT24C02当前指针地址读一个字节

单片机与24C02的通讯

 

D.指定iic的内存地址读取一个字节

单片机与24C02的通讯

 

E.在当前iic的地址指针位置开始,顺序读取多个字节,读取到该页最后一个字节时,再从该页的第一个字节循环读取

单片机与24C02的通讯

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以下内容为转载。讲的很详细。波形很完整


1.首先是起始操作(图中红色线条处)
2.接下来是设备地址,共9个时钟,前面7个是地址,然后是读写标志,最后是MPU6050/MPU9150应答标志。我们看到,前面7个数是:1101000,换算成16进制,就是0x68。第8个是0,表明是写传输(前八个数0xd0 ),第9个是0,是由MPU6050/MPU9150芯片驱动的,表明MPU6050/MPU9150芯片应答了这个地址。如果MPU6050/MPU9150芯片没有应答这个0x68地址信号,那么第9个数会显示1。
3.接下来是STM32发送要读的MPU6050/MPU9150芯片寄存器地址,共9个时钟。前面8个依次是:01110101,换算成16进制,就是0x75(该寄存器为 地址识别码who am i ,读出来的数据 为 0x68)。第9个是0,是由MPU6050/MPU9150芯片驱动的,表明MPU6050/MPU9150芯片应答了这个操作。
4.前面STM32发送完MPU6050/MPU9150芯片设备地址0x68,,寄存器地址0x75后,要告诉MPU6050/MPU9150芯片,接下来STM32要读数据了。所以STM32重新发送了一个起始操作,表示在上图中的一个时钟。
5.接下来,STM32重复发送MPU6050/MPU9150芯片地址,在图中,我们看到9个数据位,前面7个依次是1101000,即0x68,第8个数据位变成了1,表明接下来的是读操作。第9个是0,表明MPU6050/MPU9150芯片应答了这个地址。
6.接下来总线上出现了9个时钟,前面8个时钟对应的数据01101000,换算成16进制,就是0x68。这个刚好是MPU6050/MPU9150芯片的ID.即MPU6050/MPU9150芯片的WHOAMI寄存器。第9个时钟对应的数据是1,表明STM32不再需要读数据,即I2C总线中的NACK.(注意,该位一定要加上)
7.由于数据读取结束,STM32发送结束标志。至此,通讯完成

注意 1:在使用24c02的时候 ,在写完一帧数据 要等10ms 才能读取 ,否则 读取不到数据 。详情见手册,如下:


(之前没有注意这个浪费了好长时间)

注意 2:在使用24c02进行页写的时候,假设起始地址为0,写入8个字节,则占用了0-7的地址 ,然后 停止 。延时 10ms,再次从地址8开始写起 。。以此类推。


1 0
原创粉丝点击