• I2C协议学习笔记


    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/wzt_007/article/details/78622698
    通信分为四大步骤,握手、数据交换、准备结束、正式结束

    如以下场景:


     两个陌生人是进行沟通,为了显得更有主次关系,选取老板和新员工进行沟通的场景,老板一般占有主动权,而且手中有新员工的基本信息,比如姓名,年龄,性别等。沟通开始:

        老板:“XXX,欢迎你加入我们公司,为公司注入新的血液!”伸出握手姿势              —— 主握手

        新员工:“承蒙厚爱,有幸加入我们公司,我觉得是一种光荣!”握手                      —— 握手成功

        老板:“想必已经读过员工手册了吧,说说你对前两条的理解。”                            —— 执行沟通

        新员工:“第一条……,第二条……”                                                                    —— 从应答

        ……

        老板:“回答的很好,确实是我们迫切想招募的人,以后看你的精彩表现了!”        —— 主要求沟通结束

        新员工:“一定不负厚望,必努力工作!”                                                            —— 从做好结束准备

        老板离开                                                                                                             —— 沟通结束

    主从器件

    在通信的时候,总线上必须且只能有要有一个为主器件,其他的都为从器件
    在总线上表现为主控的器件叫做主发送器/接收器(MASTER TRANSMITTER/RECEIVER),主器件只执行发送,不执行接收的,命名为主发送器(MASTER TRANSMITTER)

    在总线上表现为被控的器件叫做从发送器/接收器(SLAVE RECEIVE/RTRANSMITTER),有些从器件只执行接收,不执行发送的,命名为从接受器(SLAVE RECEIVER)

    一条I2C总线最多能挂多少个器件?

    串行数据都是以一个字节一个字节的方式来衡量的,前几位用来表示地址(上述对话中的员工名字),地址的最后一位为读写操作位(READ/WRITTE位,简写为R/W,逻辑1表示读,逻辑0表示写),以最开始的一个字节作为地址来算的话,那么除去字节的最后读写标志位,就剩 8 – 1 = 7bit了,所以理论上以1个字节为地址来算的话,就可以分配2的7次方128个地址,就可以挂上128个器件(极端情况,假设这128个器件都是从机的话,就还需要挂一个主器件,合计就是128 + 1 = 129个器件了)。要是想挂更多的器件,那么就须得将地址位扩展,比如将前两个字节作为地址,去掉最后的一位读写标志位

    以上是理论的算法,在实际的器件中,都是以第一个字节作为地址的,而且大部分的器件的地址高四位已经被根据不同功能的芯片分配了不同的编码(例如,AD/DA转换芯片PCF8591的前四位为1001,E2PROM芯片AT24C02的前四位为1010,具体的芯片就得查查手册了,这里只说明原理),那么同一种功能芯片(地址前4位都相同)最多只有 8 – 4 – 1 = 3位用来分配地址了,也就是最多可以挂2的3次方8个同种功能芯片。用一个问题来深化理解一下。

    握手与结束

     I2C协议有规定,在SCL和SDA均为高电平的前提下,检测到SDA有下降沿信号,则建立I2C的通信开始;同样的,在SCL为高电平,SDA为低电平的前提下,检测到SDA有上升沿信号,则I2C通信正式结束。

    由图中虚线框中引出的:总线闲的时候,两根信号线都是高电平的。不管是通信建立和通信结束阶段,SCL都是高电平,SDA的变化控制着通信的建立与结束;在SCL为高电平的情况下,SDA信号的转变就对通信起着强制性作用,要么通信建立,要么通信正式结束,有且仅有这两种情况!也就是说,在数据交换的过程中,要对SCL这根信号线尤为注意,在数据变化的时候,一定要保证SCL是为低电平!让数据的变化在SCL的“安全”状态下进行,所以需要牢记一点,数据变化,时钟线低电平先行,如下图所示。

    通信

    在每次写数据的时候,每写一个字节数据(不论是必要的从器件地址数据、从器件控制数据,还是需要写到从机里的数据),从器件都有一个ACK(从器件的应答实现是将SDA线拉成低电平,所以在写完第8位数据以后,切记要把SCL的电平拉成低电平,等一小段时间以后,在将数据线拉高去读SDA的数据,原因在握手和结束讲了。读数据时,主器件每接收到从器件的一个字节数据,也都要回复一个ACK,主器件ACK有两种,一种表示收到数据,且准备接收下一次数据(0,ACK),一种是收到数据,但不准备接收下一次数据(1,NO ACK)

    我总结的读写流程,如果有问题,欢迎大家指出

    读:

    start>>(主:地址)>>(从:first_Data)>>(主:ACK)>>(从:second_Data)>>(主:ACK)>>(从:third_Data)>>(主:NO ACK)>>stop

    start>>(主:地址)>>(从:ACK)>>(主:first_Data)>>(从:ACK)>>(主:second_Data)>>(从:ACK)>>(主:third_Data)>>(从:ACK)>>stop
    ————————————————
    版权声明:本文为CSDN博主「wzt_007」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/wzt_007/article/details/78622698

  • 相关阅读:
    32位二进制IP地址与十进制IP地址互相转换
    在安装AndroidStudio时产生的问题
    Java 数列求和
    Java throws Exception、try、catch
    Java 语句循环
    Oracle OEM
    数据泵Expdp和Impdp
    java查询高斯数据库表某个字段值
    安全测试笔记(未更新完)
    工作笔记
  • 原文地址:https://www.cnblogs.com/wy9264/p/11908739.html
Copyright © 2020-2023  润新知