2021-05-12 14:32:11
I2C 協定圖文詳解
i2c協定注意幾點就很好的使用它:
1)由一個主裝置,一個或多個從裝置組成,所有的信號發起都是由主裝置發起,從裝置根據這些信號做一些應答。
2)i2c傳送時序是先發高位再發低位。
3) 本文以發8位元信號為例, 主裝置會先發一個7位地址,和一位讀寫位,從裝置匹配自己的地址,如果匹配上,就做應答,否則不做操作
4)開始位:主裝置發起,clk為高電平時,sda從高到低; 從裝置發現這樣一組信號,就認為主裝置要開始操作自己了,做好接收的準備工作。
5) 從裝置收資料:主裝置傳送了開始位後,把clk拉低,只有clk拉低,sda才可以做高低變化; 當clk被拉高時,從裝置就會去讀取sda的高低電平值;clk再次被拉低時,從裝置認為此位已讀取完畢,認為是有效位,等待clk再次拉高,讀取下一位。
6)校驗位:主裝置傳送完8位元後,第9位是校驗位, 讀取到低電平為有效;主裝置把clk拉低,sda io換成輸入模式(上拉電阻,預設高電平)讀取第9位,clk再次拉高,讀取從裝置發來的校驗位。
分兩種情況:
1.寫操作:主裝置把clk拉高,等待讀取校驗位,從裝置發現clk拉高後,就把sda拉低,告訴主裝置,成功接收前8位元資料。
2.讀操作:主裝置傳送IC地址和暫存器地址,這兩個位元組的校驗位都是由從裝置來拉低; 從裝置開始向從裝置傳送資料,clk為低時,sda變化,主裝置clk拉高時讀取sda, 校驗位由主裝置拉低; 當從裝置傳送完最後一個位元組後,主裝置強制把校驗位拉高,告訴從裝置不要需要再發了, 從裝置發現這個校驗位沒有被拉低,認為主裝置接收錯誤,也就結束傳送了,當然了,從裝置自己知道是最後一個位元組。
7)結束位:主裝置發起,clk為高電平時,sda從低到高。
另外:linux 設定IO方向操作瞬間時, 設定輸入時:IO電平預設為高; 設定輸出時:IO電平預設為低。
通道1為sda, 通道2為clk
主裝置傳送0x00(寫操作)
這個是模擬IO的波形時序,前兩個下去又上去的波形為linux 設定IO為輸出時,為低電平,後又初始化為高電平。clk一直為高時,sda拉低又拉高,其實已經產生了開始位和結束位,開始後馬上又結束了,之後clk拉低又拉高,從裝置不做事情,因為已經結束了。後面的波形才是從裝置可以識別的,資料在開始位和結束位之間。
通道1為sda, 通道2為clk
主裝置傳送0xC8地址,(讀操作)
實際資料為0xC9 0x04 0x11 0x33 0x43
傳送地址0xC8, 讀取0x04 0x11 0x33 0x43
這個是標準I2C的波形時序
上圖圖解:
1,2,3,4,5都 是校驗位。5號是被主裝置主動拉高,告訴從裝置要結束了,因為讀完最後一個位元組。
C為開始位
D 為停止位
A 為讀寫位
B :我們重點說說B, 為什麼會sda在clk為低時時被拉高,是因為主裝置讀完0x04這個位元組後,由從裝置去拉高校驗位,主裝置拉低校驗位,告訴從裝置已成功讀取。其實讀完其它0x11,0x33,0x43校驗位也會被從裝置拉高,只不過是由於這三個位元組的第0位是1,所以看起來沒有被拉高。
本文永久更新連結地址:http://www.linuxidc.com/Linux/2017-10/147673.htm
相關文章