(摘要:空閑時,時鐘線數據線都是高電平,主機發送數據前,要在時鐘為高電平時,把數據線從高電平拉低,數據發送采取高位先行,時鐘線低電平時可以修改數據線,時鐘線高電平時要求數據線穩定,數據為8bit,發到第九個bit時,是應答位,另一個設備應答為低電平為ack,高電平為nack,結束通信,時鐘線高電平時,把數據線從低電平拉高。)
(主設備發送完起始信號,第一個字節是設備地址8bit,最后一位為0表示主機發數據,從機收數據,反之主收從發,所以設備可以有2^7個)
?e2prom芯片
IIC(Inter-Integrated Circuit)又稱I2C,是是IICBus簡稱,所以中文應該叫集成電路總線。是飛
利浦公司在1980年代為了讓主板、嵌入式系統或手機用以連接低速周邊設備而發展而來的一種同
步串行半雙工通信總線方式。該總線允許同時連接多個設備(芯片)。每塊芯片在總線上擁有特定的
地址。自2006年10月1日起,使用I2C協議已經不需要支付專利費,但制造商仍然需要付費以獲取
IIC從屬設備地址。
上圖所示是IIC的總線的使用場景,所有掛載在IIC總線上的設備都有兩根信號線,一根是數據線SDA,另一根是時鐘線SCL。這兩個信號線都是雙向的。作為一種通信方式, IIC總線在某一時刻,總線只允許有一個設備處于發送狀態,所發生的數據被總線上所有的設備所接收。 IIC通信協議包含有設備地址,只有發送方攜帶的地址與某個接收方的地址相同時,接收方才真正執行相關的指令.
IIC總線規定,設備在空閑時,兩根總線都處于高電平狀態。為保證這種狀態,數據線SDA和時鐘線SCL都要外接上拉電阻。 對于I.MX來說,這個上拉電阻也可以在引腳電器配置中設置。
IIC總線上連接的若干設備中,每次通信前,發送方首先發送一個“起始”信號,其實信號就是在SCL為高電平時, SDA發送一個低電平。當其它設備接收到這個其實信號后,將進行一次“總線仲裁”。意思就是設備(除發送起始信號的那個設備以外的)都將處于聆聽狀態。
IIC總線進行數據傳送時,時鐘線(SCL)上的信號為高電平期間,數據線(SDA)上的數據必須保持穩定。只有在時鐘線(SCL)上的信號為低電平期間,數據線(SCL)上的高電平或低電平狀態才允許變化。同時, SCL信號由數據啟動發送的設備提供。輸出到數據線(SDA)上的每個字節必須是8位。數據傳送時,先傳送最高位(MSB),后傳送最低位(LSB)
發送器每發送一個字節(8個bit),就在時鐘脈沖 9 期間釋放數據線,由接收器反饋一個應答信號。 主機SCL拉高,讀取從機SDA的電平。對于反饋有效應答位ACK的要求是:接收器在第9個時鐘脈沖之前的低電平期間將數據線SDA拉低,并且確保在該時鐘的高電平期間為穩定的低電平。
數據線(SDA)為低電平時,規定為有效應答位(ACK,簡稱應答位),表示接收器已經成功地接收了該字節。
數據線(SDA)為高電平時,規定為非應答位(NACK),表示接收器沒有成功接收該字節。
當發送方發送完最后一個bit后,需要發送一個結束標志來終止整個通信過程。當時鐘線SCL 為高電平時,數據線SDA 由低電平向高電平跳變。
上圖就是一個完整的IIC通信時序圖。
由于I2C總線是一種總線式連接方式,意味著在同樣的兩根線上可能連接有多個不同的設備,這種總線式連接方案通常會被設計為主從應答通信方式。也就是說,對于總線上連接的所有設備來說,有一個設備是主設備,而其他設備都是從設備。設備之間的通信都是由主設備發起的,從設備被動應答主設備。這里不難看出: 1、從設備之間是無法直接完成通信的; 2、總線上的從設備必須擁有一個獨一無二的標識,這個標識被稱為設備地址。設備地址類似一個人的名字,因為在I2C總線通信過程中,無論哪個設備發送數據,其他所有設備都能夠監聽得到,所以每次通信時,主設備先發送要訪問的子設備地址,每個子設備都把監聽到的這個地址拿來跟自己進行匹配,只有匹配成功的子設備才是真正需要操作的設備。
按照I2C標準,主設備發起通信時先發送一個起始信號,之后發送的第一個字節就是子設備的設備地址。需要注意的是。設備地址本身只占7個比特,最后一個比特所代表的是之后的數據流向。 0代表主發從收,通常描述為寫, 1表示從發主收,通常描述為讀。
例如,某個設備的從機地址為0x48(二進制0100 1000b),主機在發送完起始信號之后要發送要發送的從機地址其實是1001 000x,這里x就是數據流向位。如果x為0,表示接下來主機發送數據,從機接收數據,如果x為1,表示接下要求從機發送數據,主機接收數據
I.MX6ULL本身有四路I2C控制器,但是I.MX6ULL-Mini 開發板上只在I2C2控制器上連接了一個觸控裝置,用于檢測用戶點擊了屏幕的哪個位置。關于觸摸屏的操作我們之后再加以說明。而I2C1、 3、4控制器是空置的,我們可以用杜邦線連接我們需要接入的任意傳感器。這里我們在I2C1上連接兩個傳感器AT24C02和LM75為例,作為本次I2C實驗內容。
首先是AT24C02,這是一款EEPROM,是一種非易失性存儲器。同類型的芯片還有AT24C04,AT24C08,之間的區別僅僅是存儲大小不同。既然是一種存儲器,那么對其操作無外乎有兩種操作,讀取和寫入操作。這兩種操作又同時面臨了一個問題,讀取和寫入的位置。由于AT24C02有256個字節的空間,因此無論讀取還是寫入,都必須先告訴24C02讀取或者寫入的位置,即地址。因此,我們不難總結出對24C02的兩種操作流程,我們分別加以說明:
接下來討論從24C02中讀取數據,事實上讀取數據可以通過兩種不同的方式進行,第一種方式是主機先發送設備地址,然后再發送要讀取的位置地址。需要注意的是,雖然最終的目的是要從從機那里讀取數據,但是由于我們需要先把讀取的存儲地址發送給從機,因此發送設備地址時我們把數據流向設置為寫。發送完存儲地址之后,第一種做法是發送停止位,然后重新啟動通信,這次我們把發送設備地址時的數據流向設置為讀,然后就順序讀取若干字節
第一種方式。這種讀從機方式需要兩次通信才行。大多數情況下我們并不采用這種方式,而是采用第二種方式,形式于此類似,不同之處僅在于第一次通信之后不發停止位,而是立即重新發送從機地址并標記數據流向為讀:
上圖就是完整的第二種方式的時序,可見這種方式在發送完寫入地址之后并未結束通信,而是重新發送起始信號并改變數據流量,因此這種方式效率更高。需要注意的是,大多數I2C芯片都支持兩種方式,但是在讀取到最后一個字節的時候,注意必須回復NACK,否則可能會導致從機通信異常。
I.MX6U 提供了 4 個 I2C 外設,通過這四個 I2C 外設即可完成與 I2C 從器件進行通信I.MX6U的 I2C 支持兩種模式:標準模式和快速模式,標準模式下 I2C 數據傳輸速率最高是 100Kbits/s,在快速模式下數據傳輸速率最高為 400Kbits/s。
先介紹一下跟I2C相關的寄存器,首先看一下 I2Cx_IADR(x=1~4)寄存器,這是I2C 的地址寄存器, ADR(bit7:1)位有效,用來保存 I2C 從設備地址數據。當我們要訪問某個 I2C 從設備的時候就需要將其設備地址寫入到 ADR 里面。
寄存器 I2Cx_IFDR 也只有 IC(bit5:0)這個位,用來設置 I2C 的波特率, I2C 的時鐘源可以選擇IPG_CLK_ROOT=66MHz,通過設置 IC 位既可以得到想要的 I2C 波特率。需要注意的是不像其他外設的分頻設置一樣可以隨意設置,手冊第1464頁給出了I2Cx_IFDR[bit5:0]為不同的值時的分頻值。比如現在 I2C 的時鐘源為 66MHz,我們要設置I2C 的波特率為 100KHz,那么IC 就可以設置為 0X15,也就是 640 分頻。 66000000/640=103.125KHz≈100KHz。
寄存器 I2Cx_I2CR 的各位含義如下:
? IEN(bit7): I2C 使能位,為 1 的時候使能 I2C,為 0 的時候關閉 I2C;
? IIEN(bit6): I2C 中斷使能位,為 1 的時候使能 I2C 中斷,為 0 的時候關閉 I2C 中斷;
? MSTA(bit5):主從模式選擇位,設置 IIC 工作在主模式還是從模式,為 1 的時候工作在主模式,為 0的時候工作在從模式;
? MTX(bit4):傳輸方向選擇位,用來設置是進行發送還是接收,為 0 的時候是接收,為 1 的時候是發送;
? TXAK(bit3):傳輸應答位使能,為 0 的話發送 ACK 信號,為 1 的話發送 NO ACK 信號;
? RSTA(bit2):重復開始信號,為 1 的話產生一個重新開始信號。寄存器 I2Cx_I2SR 的各位含義如下:
? ICF(bit7):數據傳輸狀態位,為 0 的時候表示數據正在傳輸,為 1 的時候表示數據傳輸完成;
? IAAS(bit6):當為 1 的時候表示 I2Cx_IADR 寄存器中的地址是從設備地址。為0表示I2Cx_IADR是自己的地址;
IBB(bit5): I2C 總線忙標志位,當為 0 的時候表示 I2C 總線空閑,為 1 的時候表示 I2C 總線忙;
? IAL(bit4):仲裁丟失位,為 1 的時候表示發生仲裁丟失。仲裁丟失在手冊第1455頁有說明,如果多個設備同時嘗試連接總線,則其中一個成為主設備。硬件會立即將仲裁失敗的設備切換到Slave
Receive模式 。那么仲裁失敗的設備就會產生仲裁丟失,導致此位置位。需要理解的是這種情況一定發生在發送起始位的時候,也就是說在發送完起始位之后應該判斷此位是否為1;
? SRW(bit2):從機讀寫狀態位,當 I2C 作為從機的時候使用,此位用來表明主機發送給從機的是讀還是寫命令。為 0 的時候表示主機要向從機寫數據,為 1 的時候表示主機要從從機讀取數據;
? IIF(bit1): I2C 中斷掛起標志位,當為 1 的時候表示有中斷掛起,此位需要軟件清零;
? RXAK(bit0):應答信號標志位,無論作為主機還是從機,為 0 的時候表示接收到 ACK 應答信號,為1 的話表示檢測到 NO ACK 信號。
最后一個寄存器就是 I2Cx_I2DR,這是 I2C 的數據寄存器,此寄存器只有低 8 位有效,當要發送數據的時候將要發送的數據寫入到此寄存器,注意此時LSB代表的是數據流向,需要按照實際情況設置為1或者0;如果要接收數據的話直接讀取此寄存器即可得到接收到的數據。
本次實驗中我們通過 I.MX6ULL 的 I2C1 來寫AT24C02,為完成這個實驗,需要大家使用杜邦線外接AT24C02,如下圖,我們需要連接4根線:電源、地、 SCL和SDA。查閱AT24C02手冊可以看出24C02的供電電壓從1.8~5.5V之間,電壓越高速度越快,由于I.MX6ULL芯片本身供電是3.3V,所以我們接3.3V電源。查閱I.MX6ULL手冊可以看出,該芯片UART4_RX是可以復用I2C1_SDA的, UART4_TX是可以復用I2C1_SCL的,因此24C02的SCL接43號針腳, SDA接SDA針腳。