I2C總線操作
對I2C總線的操作實際就是主從設備之間的讀寫操作。大致可分為以下三種操作情況:
第一,主設備往從設備中寫數據。數據傳輸格式如下:
第二,主設備從從設備中讀數據。數據傳輸格式如下:
第三,主設備往從設備中寫數據,然后重啟起始條件,緊接著從從設備中讀取數據;或者是主設備從從設備中讀數據,然后重啟起始條件,緊接著主設備往從設備中寫數據。數據傳輸格式如下:
第三種操作在單個主設備系統中,重復的開啟起始條件機制要比用STOP終止傳輸后又再次開啟總線更有效率。
1.2.1 I2C總線硬件接口電路示例一
這個電路是基于LPC2368 ARM7芯片進行設計的,使用其內部的I2C接口作為主設備,使用ADT75和SC16IS740作為兩個從設備的I2C總線應用。
ADT75是一個帶I2C接口的溫度傳感器器件,數據手冊上對其地址的描述如下:
由此,其地址跟A0、A1、A2引腳的接法有關,我們這里的實例是將A0、A1、A2全部接到高電平上,因此其地址是:1001111(即0x4F),又因根據協議再給地址添加一個最低位(方向位,默認給寫方向),因此最后這個溫度傳感器作為從設備的地址是:10011110(即0x9E)。
SC16IS740是一個具有I2C或者SPI接口的擴展UART的器件(通過第8腳來決定使用I2C還是SPI接口,我們這里要求使用I2C接口,因此將第8腳接到高電平)。根據數據手冊,我們同樣的可以知道地址跟A0、A1的接法有關,我們這里的A0接高電平,A1接低電平。因此這個器件作為從設備的地址是:10010010(即0x92)。
1.2.2 I2C總線硬件接口電路示例二
這個電路是Mini2440開發板上I2C總線接口的應用。我們可以看到,SDA和SCL線上接了一個10K的上拉排阻。AT24C08是一個容量為8Kbit的EEPROM存儲器件(注意是8Kbit,也就是1KB) ,根據數據手冊中器件地址部分的描述,AT24C08的地址是:1010+A2A1A0+方向位,其中1010是EEPROM的類型識別符;僅僅使用A2來確定總線訪問本器件的從設備地址,這里接的低電平,所以為0;A1和A0是器件內部頁地址,在對器件擦除或者編程時使用,雖然這里也接的低電平,但器件內部并不使用引腳的輸入值,也就是說A1和A0的值是由軟件進行設定的。
1.3 脫離操作系統的I2C總線驅動示例(以電路示例一為例)
1.3.1 LPC2368中I2C接口寄存器描述
LPC2368中有三個I2C總線接口,分別表示為I2C0、I2C1和I2C2,每個I2C接口都包含7個寄存器。它們分別是:
I2C控制置位寄存器(I2CONSET): 8位寄存器,各位不同的設置是對I2C總線不同的控制。
在前面的I2C總線特征中我們提到過,I2C總線的速率通過可編程時鐘來調整,即必須通過軟件對I2SCLH和I2SCLL寄存器進行設置來選擇合適的數據頻率和占空比。 頻率由下面的公式得出(fPCLK是PCLK的頻率)。
LPC2368中I2C總線操作
在1.1.4中我們已經講過了對I2C總線的操作,但那只是從協議和時序上的描述,那我們如何從軟件上去體現出來呢?接下來我們就討論這個問題。
對I2C總線上主從設備的讀寫可使用兩種方法,一是使用輪詢的方式,二是使用中斷的方式。輪詢方式即是在一個循環中判斷I2C狀態寄存器當前的狀態值來確定總線當前所處的狀態,然后根據這個狀態來進行下一步的操作。中斷方式即是使能I2C中斷,注冊I2C中斷服務程序,在服務程序中讀取I2C狀態寄存器的當前狀態值,再根據狀態值來確定下一步的操作。
不管使用哪種方法,看來I2C狀態寄存器的值是至關重要的。這些狀態值代表什么意思呢?下面我們描述一些常用的狀態值(詳細的狀態值含義請參考數據手冊)。
0x08: 表明主設備向總線已發出了一個起始條件;
0x10: 表明主設備向總線已發出了一個重復的起始條件;
0x18: 表明主設備向總線已發送了一個從設備地址(寫方向)并且接收到從設備的應答;
0x20: 表明主設備向總線已發送了一個從設備地址(寫方向)并且接收到從設備的非應答;
0x28: 表明主設備向總線已發送了一個數據字節并且接收到從設備的應答;
0x30: 表明主設備向總線已發送了一個數據字節并且接收到從設備的非應答;
0x40: 表明主設備向總線已發送了一個從設備地址(讀方向)并且接收到從設備的應答;
0x48: 表明主設備向總線已發送了一個從設備地址(讀方向)并且接收到從設備的非應答;
0x50: 表明主設備從總線上已接收一個數據字節并且返回了應答;
0x58: 表明主設備從總線上已接收一個數據字節并且返回了非應答;
四、 總線信號時序分析
1. 總線空閑狀態
SDA和SCL兩條信號線都處于高電平,即總線上所有的器件都釋放總線,兩條信號線各自的上拉電阻把電平拉高;
2. 啟動信號START
時鐘信號SCL保持高電平,數據信號SDA的電平被拉低(即負跳變)。啟動信號必須是跳變信號,而且在建立該信號前必修保證總線處于空閑狀態;
3. 停止信號STOP
時鐘信號SCL保持高電平,數據線被釋放,使得SDA返回高電平(即正跳變),停止信號也必須是跳變信號。
4. 數據傳送
SCL線呈現高電平期間,SDA線上的電平必須保持穩定,低電平表示0(此時的線電壓為地電壓),高電平表示1(此時的電壓由元器件的VDD決定)。只有在SCL線為低電平期間,SDA上的電平允許變化。
5. 應答信號ACK
I2C總線的數據都是以字節(8位)的方式傳送的,發送器件每發送一個字節之后,在時鐘的第9個脈沖期間釋放數據總線,由接收器發送一個ACK(把數據總線的電平拉低)來表示數據成功接收。
6. 無應答信號NACK
在時鐘的第9個脈沖期間發送器釋放數據總線,接收器不拉低數據總線表示一個NACK,NACK有兩種用途:
a. 一般表示接收器未成功接收數據字節;
b. 當接收器是主控器時,它收到最后一個字節后,應發送一個NACK信號,以通知被控發送器結束數據發送,并釋放總線,以便主控接收器發送一個停止信號STOP。
評論