【Day21】I2C的介绍

I2C是什麽?

I2C,又称 I²C(Inter-Interated Circuit),在 I2C 的通讯协定中,收发资料只单纯靠两条线就能完成,分别为 SCL(serial clock) 以及 SDA(serial data),但比较特别的是 I2C bus 上所连接的装置都是 open-drain 的方式来驱动信号的,那跟一般的数位逻辑输出电路有着甚麽样的差异呢?

一般的数位逻辑输出电路会有分别把电位拉到 high 及 low 的两颗电晶体,但是 open-drain 驱动的电路则是只有负责把电位拉到 low 的电晶体,而高电位则是由外部的上拉电阻负责输出。

那这样一条 clk 一条 data 要如何沟通呢?就是因为只有一条资料线,所以每个装置端的 SDA 都可以是双向沟通的,它既可以当输入也可以当输出,需要 "0" 时把电位拉到 "0",需要 "1" 时输出高阻抗,此时装置与 BUS 端有如断路,让上拉电阻到 Vcc 来提供 "1"。

图片来源


I2C 的 Timing Diagram

图片来源

I2C bus 上的逻辑讯号有几个原则:

  • 当未传输时(IDLE 状态) ,SCL 和 SDA 都会维持在 high 电位。
  • SCL 为 high 时,表示 SDA 上的资料为有效,此时 SDA 的值不能改变,以确保可以收到到正确的 SDA 状态
  • SCL 为 low 时,SDA 的状态可以改变
  • 当 SCL 为 high 时,如果 SDA 变动,只有两种情况:
    • SDA由 "1" 变 "0" ---> START
    • SDA由 "0" 变 "1" ---> STOP

Acknowledge

当每 8 bit 资料传输完後,会跟随着 1 bit 的 ACK,这是在确保两端的接收状况是否正常。

  • 如果是 master 传资料给 slave :此时 ACK 会来自 slave 端,以此告诉 master 端它有收到资料(通常用於对 slave 下 instructions)。
  • 如果是 master 想要向 slave 端索取资料时,举个例子,例如读取记忆体资料:master 会先 slave 传送想读取的记忆体"位址",接着 slave 端会先 ack 回去表示有收到此位址,接着传出记忆体位址上的 data 给 master,那麽传了 8 bit 後,master 会 ACK 回去,以表示有收到资料,可以继续传,那麽 slave 端就会继续传,再过了 8 bit,此时如果传输要结束的话则 master 不会 ACK 回去,而这个动作也称 non-ACK,以此告诉 slave 端这次的传输到此为止结束了,完成这次通讯。

I2C如何选择晶片的呢?

在 master 要与 BUS 上的其中一个 slave 沟通时,会先将要沟通 chip 的 address 透过 SDA 传输到 BUS 上,此时如果 address 没错的话,那麽该 slave 会在第八个 SCL 周期结束後把 SDA 拉下来,而 master 端会在 SCL 进入第九个周期前去读取 SDA 是否为 low ,为 low 的话就会开始一连串 handshake 式的传输动作,若没有拉为 low(non-ACK),则出现问题,可能 slave 根本不在 BUS 上或是 slave 端的 address 打错了都有可能。

因为 I2C 这个通讯协定比较复杂一点点,提前要知道的观念比较多,程序也比较复杂,所以这次的 I2C 实作分成了四天~~


<<:  Android Studio初学笔记-Day21-AlertDialog(2)

>>:  EP 28: Shell Routing for TopStore App

【第二十八天 - 系统设计 介绍】

Q1. 系统设计 是什麽 在业界基本上都是团队开发专案,每个人负责实作部分功能,而 Leetcode...

中阶魔法 - 提升 Hoisting

前情提要 艾草:「我们今天来提升一下吧!」 「不是每天都在提升魔力总量了吗?」 艾草:「不一样唷,今...

Day 1 前言

刚转职成功的前端菜鸡第一次参赛,原本想简单开心的每天写一个小小的专案练习 JavaScript, C...

Day 16 - 设定 PBR

我们今天要来设定 PBR,我们以 Juniper MX 为例 首先,我们要先决定一个 routing...

[Day 11] Leetcode 152. Maximum Product Subarray (C++)

前言 先来个之前写过觉得还算值得练习的DP题目~152. Maximum Product Subar...