天天看點

S5PV210系列 (裸機十六) 之 I2C通信詳解

什麼是I2C通信

實體接口:SCL + SDA

(1)SCL(serial clock):時鐘線,傳輸CLK信号,一般是I2C主裝置向從裝置提供時鐘的通道。

(2)SDA(serial data): 資料線,通信資料都通過SDA線傳輸

通信特征:串行、同步、非差分、低速率

(1) I2C 屬于串行通信,所有的資料以位為機關在 SDA 線上串行傳輸。

(2)同步通信就是通信雙方工作在同一個時鐘下,一般是通信的 A 方通過一根CLK 信号線傳輸 A 自己的時鐘給 B,B 工作在 A 傳輸的時鐘下。是以同步通信的顯著特征就是:通信線中有 CLK

(3)非差分。因為 I2C 通信速率不高,而且通信雙方距離很近,是以使用電平信号通信。

(4)低速率。I2C 一般是用在同一個闆子上的 2 個 IC 之間的通信,而且用來傳輸的資料量不大,是以本身通信速率很低(一般幾百 KHz,不同的 I2C 晶片的通信速率可能不同,具體在程式設計的時候要看自己所使用的裝置允許的 I2C 通信最高速率,不能超過這個速率)

突出特征1:主裝置+從裝置

(1) I2C 通信的時候,通信雙方地位是不對等的,而是分主裝置和從裝置。通信由主裝置發起,由主裝置主導,從裝置隻是按照 I2C 協定被動的接受主裝置的通信,并及時響應。

(2)誰是主裝置、誰是從裝置是由通信雙方來定的( I2C 協定并無規定),一般來說一個晶片可以隻能做主裝置、也可以隻能做從裝置、也可以既能當主裝置又能當從裝置(軟體配置)。

突出特征 2:可以多個裝置挂在一條總線上(從裝置位址)

(1) I2C 通信可以一對一( 1 個主裝置對 1 個從裝置),也可以一對多( 1 個主裝置對多個從裝置)。

(2)主裝置來負責排程總線,決定某一時間和哪個從裝置通信。注意:同一時間内,I2C 的總線上隻能傳輸一對裝置的通信資訊,是以同一時間隻能有一個從裝置和主裝置通信,其他從裝置處于“冬眠”狀态,不能出來搗亂,否則通信就亂套了。

(3)每一個 I2C 從裝置在通信中都有一個 I2C 從裝置位址,這個裝置位址是從裝置本身固有的屬性,然後通信時主裝置需要知道自己将要通信的那個從裝置的位址,然後在通信中通過位址來甄别是不是自己要找的那個從裝置。(這個位址是一個電路闆上唯一的,不是全球唯一的)

主要用途:SoC 和周邊外設之間的通信(典型的如 EEPROM、電容觸摸 IC、各種 sensor 等)

由I2C學通信時序

什麼是時序?

(1)時序:字面意思,時序就是時間順序,實際上在通信中時序就是通信線上按照時間順序發生的電平變化,以及這些變化對通信的意義就叫時序。

I2C 的總線空閑狀态、起始位、結束位

(1)I2C 總線上有 1 個主裝置,n(n >= 1)個從裝置。I2C 總線上有 2 種狀态;空閑态(所有從裝置都未和主裝置通信,此時總線空閑)和忙态(其中一個從裝置在和主裝置通信,此時總線被這一對占用,其他從裝置必須歇着)。

(2)整個通信分為一個周期一個周期的,兩個相鄰的通信周期是空閑态。每一個通信周期由一個起始位開始,一個結束位結束,中間是本周期的通信資料。

(3)起始位并不是一個時間點,起始位是一個時間段,在這段時間内總線狀态變化情況是:SCL 線維持高電平,同時 SDA 線發生一個從高到低的下降沿。

(4)與起始位相似,結束位也是一個時間段。在這段時間内總線狀态變化情況是:SCL 線維持高電平,同時 SDA 線發生一個從低到高的上升沿。

I2C 資料傳輸格式(資料位& ACK )

(1)每一個通信周期的發起和結束都是由主裝置來做的,從裝置隻有被動的響應主裝置,沒法自己自發的去做任何事情。

(2)主裝置在每個通信周期會先發 8 位的從裝置位址(其實 8 位中隻有 7 位是從裝置位址,還有 1 位表示主裝置下面要寫入還是讀出)到總線(主裝置是以廣播的形式發送的,隻要是總線上的所有從裝置其實都能收到這個資訊)。然後總線上的每個從裝置都能收到這個位址,并且收到位址後和自己的裝置位址比較看是否相等。如果相等說明主裝置本次通信就是給我說話,如果不想等說明這次通信與我無關,不用聽了不管了。

(3)發送方發送一段資料後,接收方需要回應一個 ACK。這個響應本身隻有 1 個bit 位,不能攜帶有效資訊,隻能表示 2 個意思(要麼表示收到資料,即有效響應;要麼表示未收到資料,無效響應)

(4)在某一個通信時刻,主裝置和從裝置隻能有一個在發(占用總線,也就是向總線寫),另一個在收(從總線讀)。如果在某個時間主裝置和從裝置都試圖向總線寫那就完蛋了,通信就亂套了。

資料在總線上的傳輸協定

(1) I2C 通信時的基本資料機關也是以位元組為機關的,每次傳輸的有效資料都是1個位元組( 8 位)。

(2)起始位及其後的 8 個 clk 中都是主裝置在發送(這裝置掌控總線),此時從裝置隻能讀取總線,通過讀總線來得知主裝置發給從裝置的資訊;然後到了第 9 周期,按照協定規定從裝置需要發送 ACK 給主裝置,是以此時主裝置必須釋放總線(主裝置把總線置為高電平然後不要動,其實就類似于總線空閑狀态),同時從裝置試圖拉低總線發出 ACK。如果從裝置拉低總線失敗,或者從裝置根本就沒有拉低總線,則主裝置看到的現象就是總線在第 9 周期仍然一直保持高,這對主裝置來說,意味着我沒收到 ACK,主裝置就認為剛才給從裝置發送的 8 位元組不對(接收失敗)

S5PV210 的 I2C 控制器

通信雙方本質上是通過時序在工作,但是時序會比較複雜不利于 SoC 軟體完成,于是乎解決方案是 SoC 内部内置了硬體的控制器來産生通信時序。這樣我們寫軟體時隻需要向控制器的寄存器中寫入配置值即可,控制器會産生适當的時序在通信線上和對方通信。

結構框圖

S5PV210系列 (裸機十六) 之 I2C通信詳解

(1)時鐘部分,時鐘來源是 PCLK_PSYS,經過内部分頻最終得到 I2C 控制器的 CLK,通信中這個 CLK 會通過 SCL 線傳給從裝置。

(2) I2C 總線控制邏輯(前台代表是 I2CCON、I2CSTAT 這兩個寄存器),主要負責産生 I2C 通信時序。實際程式設計中要發送起始位、停止位、接收 ACK 等都是通過這兩個寄存器(背後所代表的電路子產品)實作的。

(3)移位寄存器(shift register),将代碼中要發送的位元組資料,通過移位寄存器變成 1 個位一個位的丢給 SDA 線上去發送/接收。學過數字電路的同學應該對移位寄存器不陌生。

(4)位址寄存器+比較器。本 I2C 控制器做從裝置的時候用。(我沒用過,理論分析)

系統分析 I2C 的時鐘

(1)I2C 時鐘源頭來源于 PCLK(PCLK_PSYS,等于65MHz),經過了 2 級分頻後得到的。

(2)第一級分頻是 I2CCON 的 bit6,可以得到一個中間時鐘 I2CCLK(等于PCLK/16 或者 PCLK/512)

(3)第二級分頻是得到最終 I2C 控制器工作的時鐘,以 I2CCLK 這個中間時鐘為來源,分頻系數為 [1,16]

(4)最終要得到時鐘是 2 級分頻後的時鐘,譬如一個可用的設定是:65000KHz/512/4 = 31KHz

主要寄存器 I2CCON、I2CSTAT、I2CADD、I2CDS

I2CCON + I2CSTAT:主要用來産生通信時序和 I2C 接口配置。

I2CADD:用來寫自己的 slave address

I2CDS:發送/接收的資料都放在這裡

X210 闆載 gsensor 介紹

原理圖查閱

S5PV210系列 (裸機十六) 之 I2C通信詳解

(1)gsensor 的供電由 PWMTOUT3 引腳控制。當 PWMTOUT3 輸出低電平時gsensor 無電不工作;當輸出高電平時 gsensor 才會工作。

(2)gsensor 的 SDA 和 SCL 接的是 S5PV210 的 I2C 端口 0

(3)将來程式設計時在 gsensor_init 函數中要去初始化相關的 GPIO。要把相應的 GPIO 設定為正确的模式和輸入輸出值。

重力加速度傳感器簡介

(1)用在手機、平闆、智能手表等裝置上,用來感受人的手的移動,擷取一些運動的方向性資訊用來給系統作為輸入參量。

(2)可以用來設計智能手表的計步器功能。

(3)重力加速度傳感器、地磁傳感器、陀螺儀等三個傳感器結合起來,都是用來感謝運動的速度、方位等資訊的,是以現在最新的有 9 軸傳感器,就是把三者結合起來,并且用一定的算法進行綜合得出結論,目的是更加準确。

(4)一般傳感器的接口有 2 種:模拟接口和數字接口。模拟接口是用接口電平變化來作為輸出的(譬如模拟接口的壓力傳感器,在壓力不同時輸出電平在 0〜3.3V範圍内變化,每一個電壓對應一個壓力。),SOC 需要用 AD 接口來對接這種傳感器對它輸出的資料進行 AD 轉換,轉換得到數字電壓值,再用數字電壓值去校準得到壓力值;數字接口是後來發展出來的,數字接口的 sensor 是在模拟接口的sensor 基礎上,内部內建了 AD,直接(通過一定的總線接口協定,一般是 I2C )輸出一個數字值的參數,這樣 SoC 直接通過總線接口初始化、讀取傳感器輸出的參數即可(譬如 gsensor、電容觸摸屏 IC)。

I2C從裝置的裝置位址

(1) KXTE9 的 I2C 位址固定為 0b0001111(0x0f)

(2)I2C從裝置位址本身是7位的,但是在 I2C 通信中發送 I2C 從裝置位址時實際發送的是8位,這8位中高7位(bit7-bit1)對應I2C從裝置的7位位址,最低一位(LSB)存放的是R/W資訊(就是說下一個資料是主裝置寫從裝置讀(對應0),還是主裝置讀從裝置寫(對應1))

(3)基于上面講的,對于 KXTE9 來說,主裝置( SoC )發給 gsensor 資訊時,SAD應該是:0b00011110(0x1E)

如果是主裝置讀取 gsensor 資訊時,SAD 應該是:0b00011111( 0x1F )

I2C從裝置的通信速率

(1) I2C 協定本身屬于低速協定,通信速率不能太高。

(2)實際上通信的主裝置和從裝置本身都有最高的通信速率限制(屬于各個晶片本身的參數),實際程式設計時怎麼确定最終的通信速率?隻要小于兩個即可。

(3)一般來說隻能做從裝置的 sensor 晶片本身 i2c 通信速率偏低,像 KXTE9 最高支援 400KHz 的頻率。

I2C總線的通信流程

S5PV210的主發送流程圖

S5PV210系列 (裸機十六) 之 I2C通信詳解

S5PV210的主接收流程圖

S5PV210系列 (裸機十六) 之 I2C通信詳解

gsensor的寫寄存器流程圖

S5PV210系列 (裸機十六) 之 I2C通信詳解

gsensor的讀寄存器流程圖

S5PV210系列 (裸機十六) 之 I2C通信詳解

I2C通信代碼分析

I2C控制器初始化:s3c24xx_i2c_init

(1)初始化做的事情:初始化GPIO,設定IRQEN和ACKEN,初始化I2C時鐘

I2C控制器主模式開始一次讀寫:s3c24xx_i2c_message_start

I2C控制器主模式結束一次讀寫:s3c24xx_i2c_stop

架構分析:

我們最終目的是通過讀寫 gsensor 晶片的内部寄存器來得到一些資訊。為了完成這個目的,我們需要能夠讀寫 gsensor 的寄存器,根據 gsensor 的規定我們需要按照一定的操作流程來讀寫 gsensor 的内部寄存器,這是一個層次(姑且叫做傳輸層、協定層、應用層);我們要按照操作流程去讀寫寄存器,就需要考慮 I2C 接口協定(這就是所謂的實體層,本質就是那些時序)。此時主機 SoC 有或者沒有控制器,有控制器時考慮控制器的寄存器,沒控制器時要自己軟體模拟時序。

協定層的代碼主要取決于 gsensor 晶片;實體層代碼主要取決于主機 SoC。

gsensor寫寄存器:gsensor_i2c_write_reg

gsensor讀寄存器:gsensor_i2c_read_reg

gsensor程式設計:gsensor_initial等

繼續閱讀