I2C,又叫IIC。標準寫法應當是I2C,讀作“I方C”。
兩根線、雙向傳輸數據、一對多傳輸數據、速度不快、通用性很強。
適用場景:各種傳感器、小IC、小MCU等。控制指令和小數據量的傳輸
說到兩根線的數據傳輸方式,大家可能會對串口(UART)最熟悉,TX、RX兩根線即可傳輸數據,常用的跑到115200bps的速度毫無問題。
那么為什么還需要I2C這樣的同樣是兩根線的傳輸方式呢?
I2C能夠1對多,UART只能1對1。因此I2C又叫I2C總線。
I2C接口能夠用軟件模擬來擴充接口,UART則不行。
I2C接口帶有同步時鐘,對時鐘穩定性要求遠沒有UART那么高。
由此可見,I2C存在的最大原因在于簡單且靈活性高。
例如一個主控要接5個外設,但是通常的主控都不可能有5個UART口。如果用UART就需要硬件擴展。
但是用I2C的話,只需要1組I2C接口即可。即使沒有硬件I2C接口,也可以有軟件模擬I2C的源代碼可以調用。(I2C源碼網上隨便就可以搜到很多)。嵌入式開發初學者都可以在一周之內自己獨立寫一套出來。
I2C使用范例
單獨輸出傳輸
這個沒什么好講的,硬件連好了,軟件配置好了,數據就可以順利傳輸了。
這種連接方式,僅限于CPU需要控制外設,而外設永遠不會自己主動發數據給CPU的情況。如果外設需要主動要求發數據個CPU,需要采用下面一種方式。
帶中斷的數據傳輸
為什么要加中斷?
I2C只能由CPU(主機)去找外設(從機)索取數據,外設不能主動發送數據給CPU。
但是CPU不能定期去問外設“你有沒有數據要發給我?”,這樣耗CPU的計算資源,也耗電,且無法進入睡眠狀態。
因此需要外設有辦法通知CPU,“我有數據要發了”。I2C配合的中斷信號就是這個作用。外設有數據要發了,先發個中斷給CPU,CPU再來通過I2C讀取外設想要發過來的數據。
對于低功耗應用的場景、能夠觸發的外設場景,都需要這么來設計。例如電容觸摸屏,平時CPU是休眠的,點擊一下就喚醒系統。再例如G-Sensor運動傳感器,一旦被晃動了就喚醒CPU。
一個控制多個設備:
如何一對多?
一根I2C總線上掛載多個設備,那么豈不是CPU發個什么數據,所有的外設都可以看得到?
是的,就這樣子的。只不過CPU先會發一個地址,所有的外設都會收到這個地址。這個地址就好比外設的名字。叫了你了,你就答應,沒叫你就別答應。
地址總共能有127個,不同的I2C接口的外設的地址通常是不會重復的。
對于如果我需要在一根I2C總線上掛載多個相同的外設呢?例如上面的一組I2C控制幾個燈控IC。這種情況下,IC廠家通常都會未卜先知,知道大家可能會一口氣用好幾個,在IC上預留地址腳,通過不同的拉高和拉低的狀態,把設備的I2C的地址配置成不同的值。
通過地址選擇腳,選擇不同的I2C地址
I2C協議簡單介紹
講了,這么多,硬件工程師們知道什么是I2C以及怎么使用了,但是還是不能愉快的和軟件工程師交流,因為還不知道傳輸的詳情。
I2C時序圖
具體的I2C工作時序,記住這么幾條就可以理解了:
只能由主機(Master)發起數據傳輸請求,從機(Slave)只能被動響應。
通常MCU是主機,外圍設備是從機。
主機和從機都不說話的時候,兩根線都是高電平。(被外部上拉電阻拉高的)
主機先發送地址(Address),I2C上掛載的所有的設備都會收到這個地址,只有這個地址和自己的地址一致,才會響應(ACK)。
主機發送地址的時候順帶還會說本次操作是讀還是寫(RW)。從機收到這個讀寫信號,如果是讀,從機就準備好要被讀取的數據等著主機來讀,如果是寫,從機就做好接收數據的準備。
從機響應了,主機才會繼續發數據。如果沒有人響應,要么是從設備都掛了,要么是地址不對,總之就是有問題。
如果上面的都ok了,接下來就是按部就班的傳輸數據了。