用vue做的網(wǎng)站模板seo網(wǎng)站推廣如何做
一、簡介
I2C(Inter IC Bus)是有飛利浦公司開發(fā)的一種通用數(shù)據(jù)總線,主要通過兩個通信線SCL和SDA進行通信,其中SCL(Serial Clock)是時鐘線,用于收發(fā)雙方同步數(shù)據(jù),SDA(Serial Data)是數(shù)據(jù)線,用于傳輸數(shù)據(jù)。是一種同步半雙工的數(shù)據(jù)總線,其有數(shù)據(jù)應答功能,支持在總線上掛載多個設備。 不少的設備,比如說常用的0.42寸的OLED顯示器,MPU6050加速度傳感器,AT24C02存儲器模塊,DS3231實時時鐘模塊等,都是用I2C協(xié)議
二、硬件電路分析
I2C典型電路如下:
- 所有I2C設備的SCL連在一起,SDA連在一起
- 設備的SCL和SDA都需要設置為開漏輸出模式
- SCL和SDA各配置一個上拉電阻,阻值一般為4.7k歐姆
在I2C中,支持總線掛載多設備,主要有一主多從,多主多從兩個模式。在主從控制中,CPU作為總線的主機的權(quán)利很大,一般掌握著SCL和SDA的控制,而從機只有在申請發(fā)送數(shù)據(jù)或做出應答的時候,才能從主機中獲取到SDA的控制權(quán),而SCL的控制權(quán)任何時刻都是在主機手里的。
由于主機擁有SCL的絕對控制權(quán),主機的SC應該L配置成推挽輸出,而從機的SCL設置為浮空輸入或者上拉輸入,時鐘信號由主機發(fā)送,所有從機負責接收并且對齊時鐘信號。 對于SDA,主機和從機都可能會在輸入和輸出之間切換,而如果時鐘同步?jīng)]做好,可能會出現(xiàn)兩個設備同時對SDA進行操作的情況,如果其中一個輸出高電平,另外一個輸出低電平,則會導致線路短路,另外,協(xié)調(diào)電路中各個設備,使得只有一個設備在發(fā)送信息,是一件很麻煩的事情。為了避免這種情況,I2C禁止所有設備輸出強上拉的高電平,采用外置的弱上拉電阻加開漏輸出的電路結(jié)構(gòu),這也是上述典型電路中的1、2點。
對于開漏輸出,實際上的引腳的內(nèi)部結(jié)構(gòu)是只有下拉接負極的開關(guān)管,而沒有接正極的上拉開關(guān)管,因此引腳只能輸出0電平或者浮空,而由于外置了上拉電阻,則在浮空的時候,SDA會被外置電阻弱上拉為高電平,從而避免了同時有強下拉和強上拉的情況。這樣子就杜絕了電源短路的情況。
并且這個設計開漏加弱上拉的模式,同時兼具了輸入和輸出的功能:如果需要輸出,則直接使用開漏輸出進行操作,而想要輸入的時候,則不做操作,直接觀察電平高低。另外,這個設計還有一個“線與”的性質(zhì),也就是只要有任意電路輸出低電平,SDA總線就會處于低電平,這可以讓CPU執(zhí)行多主機模式下的時鐘同步和總線仲裁,這是多主多從模式的基礎。同時,如果發(fā)送SDA總線處于低電平狀態(tài),則表明有人正在占用SDA
總之,這個設計有三個優(yōu)點:
- 避免線路短路
- 兼顧輸入和輸出
- 可實現(xiàn)多主多從
三、I2C時序基本單元
3.1 發(fā)送和接收數(shù)據(jù)
I2C規(guī)定,I2C的起始條件和終止條件如下:
起始和終止都是由主機控制,空閑的時候所有從設備都需要保持端口浮空。
發(fā)送一個字節(jié):
SCL低電平期間,主機將數(shù)據(jù)一次放在SDA總線上,然后釋放SCL,從機將在SCL高電平期間讀取數(shù)據(jù)位,所以SCL高電平期間SDA不允許有數(shù)據(jù)變化,依次重復八次,則發(fā)送一個字節(jié)。比如說首先主機拉低SCL,然后將SDA也拉低,表示發(fā)送一個0,然后保持SDA低電平,釋放SCL,此時各個從設備負責讀取SDA電平狀態(tài)0,以此往復。如果主機進中斷了,停止操作SCL和SDA,那么SCL和SDA則會保持當前狀態(tài),傳輸暫停,不會導致傳輸丟失的情況,這是同步時序的好處。
接收一個字節(jié):
SCL低電平期間,從機將數(shù)據(jù)一次放在SDA線上,然后主機釋放SCL,主機會在SCL高電平期間讀取數(shù)據(jù)。所以SCL高電平期間SDA不允許有數(shù)據(jù)變化,依次重復八次,則主機接收一個字節(jié)
主機接收和發(fā)送的區(qū)別是,主機接受之前需要釋放SDA,而發(fā)送之前需要拉低SDA
3.2 發(fā)送和接收應答
發(fā)送應答:主機接受完一個字節(jié)之后,在下一個時鐘發(fā)送一位數(shù)據(jù),數(shù)據(jù)0表示應答,1表示非應答
接收應答:主機在發(fā)送完一個字節(jié)之后,在下一個時鐘接收一位數(shù)據(jù),判斷從機是否應答,數(shù)據(jù)0表示應答,數(shù)據(jù)1表示非應答。主機在接受前需要釋放SDA
3.3 數(shù)據(jù)幀分析
有了上面六個切片,我們就可以將它們組成一個完整的數(shù)據(jù)幀了。
指定地址寫
主機首先需要發(fā)送一個字節(jié)確定發(fā)送的對象,該字節(jié)是從機的地址。從機地址分為7位地址和10位地址,其中7位地址是廠商按芯片型號賦值的,而后三位則是可變地址,使得在掛載多個相同型號的芯片的時候可以做出區(qū)分。這個就是指定從機步驟。而一個字節(jié)有8個位,其中7位用于標識從機,另外一位是讀寫位,用于表示主機要進行讀操作還是寫操作。
主機發(fā)送指定從機字節(jié)后,目標從機會立馬對主機進行應答,也就是主機發(fā)送完指定從機字節(jié)之后,主機會釋放SDA,此時目標從機立馬下拉SDA,表示應答,而主機在下一個SCL高電平的時候讀SDA,發(fā)現(xiàn)自己釋放SDA后,SDA仍是低電平,根據(jù)線與設計,證明電路中有設備對SDA進行了下拉操作,也就是有設備做出了應答。
一般來說,指定地址寫在從機應答后,主機寫的第一個字節(jié)是指定寫入從機的哪一個寄存器,接著再下一個字節(jié)是寫入的值
指定地址讀
接下來,則根據(jù)讀寫位,進行主機的讀寫操作。如果主機發(fā)送主機讀命令,那么在指定從機之后,會立馬進入主機讀狀態(tài),但是此時還不知道主機需要讀的是從機哪一個寄存器中的值,這怎么辦呢?在支持I2C的設備中,寄存器地址一般都是線性緊挨排布的。而其中會有一個地址指針(假設位于0x19),用于指向寄存器,每次讀一次,指針就會自增一次。因此比如要讀取0xAA的寄存器,那么首先對指定從機發(fā)送一個寫請求,將0x19的內(nèi)存單元寫為0xA9,然后終止。再發(fā)起一次主機讀,然后指定從機接收到請求后,0x19自增1,變成0xAA,然后讀出0xAA寄存器中的值。這個操作被稱為**“指定地址讀”**