Android Things 外設I/O-I2C(IIC)

寫在前面的話:由于外設I/O涉及到GPIO纠吴、PWM硬鞍、和串行通信三部分,而串行通信有講了I2C(IIC)戴已、SPI固该、UART,這樣導致本文的篇幅過長不便于閱讀糖儡,特此將本文分成幾部分來方便閱讀

  1. Android Things 外設I/O-GPIO
  2. Android Things 外設I/O-PWM
  3. Android Things 外設I/O-I2C(IIC)
  4. Android Things 外設I/O-SPI
  5. Android Things 外設I/O-UART

串行通信

使用這些API在連接在同一本地總線上的兩個或多個智能設備之間傳輸更大的數(shù)據(jù)有效負載伐坏。 下表概述了每個支持的串行協(xié)議的基本屬性:

協(xié)議 傳輸類型 電線數(shù)量 外圍設備數(shù)量 傳輸速度
I2C 同步 2 Up to 127 Low
SPI 同步 4+ Unlimited High
UART 異步 2 or 4 1 Medium

I2C

內(nèi)部集成電路(IIC或I2C)總線連接具有小數(shù)據(jù)有效載荷的簡單外圍設備。 傳感器和執(zhí)行器是I2C的常見用例握联。 示例包括加速度計桦沉,溫度計每瞒,LCD顯示器和電機驅動器。

I2C是同步串行接口纯露,這意味著它依賴于共享時鐘信號來同步設備之間的數(shù)據(jù)傳輸剿骨。 觸發(fā)時鐘信號的控制裝置稱為主機。 所有其他連接的外圍設備稱為從設備埠褪。 每個設備連接到同一組數(shù)據(jù)信號以形成總線浓利。

I2C器件使用3-Wire接口連接,包括:

  • 共享時鐘信號(SCL)
  • 共享數(shù)據(jù)線(SDA)
  • 公共接地參考(GND)
I<sup>2</sup>C連接

由于所有數(shù)據(jù)都通過一條線傳輸组橄,I2C僅支持半雙工通信荞膘。 所有通信由主設備發(fā)起罚随,并且從設備必須在主設備的傳輸完成后進行響應玉工。
??I2C支持沿同一總線連接的多個從器件。 與SPI不同淘菩,從器件使用I2C軟件協(xié)議尋址遵班。 每個設備都用唯一的地址編程,并且只響應主設備發(fā)送到該地址的傳輸潮改。 每個從設備必須有一個地址狭郑,即使總線只包含一個從設備。

管理從設備連接

為了打開到特定I2C從器件的連接汇在,您需要知道總線的唯一名稱翰萨。 在開發(fā)的初始階段或將應用程序移植到新硬件時,可以通過getI2CBusList()方法從PeripheralManagerService中找到所有可用的設備名稱:

PeripheralManagerService manager = new PeripheralManagerService();
List<String> deviceList = manager.getI2CBusList();
if (deviceList.isEmpty()) {
    Log.i(TAG, "No I2C bus available on this device.");
} else {
    Log.i(TAG, "List of available devices: " + deviceList);
}

一旦知道目標設備名稱糕殉,就可以使用PeripheralManagerService連接到該設備亩鬼。 與外圍設備通信后,記得關閉連接以釋放資源阿蝶。 此外雳锋,在現(xiàn)有連接關閉之前,無法打開與設備的新連接羡洁。 要關閉連接玷过,請使用設備的close()方法。

public class HomeActivity extends Activity {
    // IIC 設備名稱
    private static final String I2C_DEVICE_NAME = ...;
    // IIC 從設備地址
    private static final int I2C_ADDRESS = ...;

    private I2cDevice mDevice;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 嘗試訪問I2C設備
        try {
            PeripheralManagerService manager = new PeripheralManagerService();
            mDevice = manager.openI2cDevice(I2C_DEVICE_NAME, I2C_ADDRESS)
        } catch (IOException e) {
            Log.w(TAG, "Unable to access I2C device", e);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mDevice != null) {
            try {
                mDevice.close();
                mDevice = null;
            } catch (IOException e) {
                Log.w(TAG, "Unable to close I2C device", e);
            }
        }
    }
}

注:器件名稱表示I2C總線筑煮,地址表示該總線上的各個從器件辛蚊。 因此,I2cDevice是到相應I2C總線上的特定從器件的連接真仲。

與寄存器交互

I2C從器件將其內(nèi)容組織為可讀或可寫寄存器(由地址值引用的數(shù)據(jù)的單個字節(jié)):

  • 可讀寄存器 - 包含從機要向主機報告的數(shù)據(jù)袋马,例如傳感器值或狀態(tài)標志。
  • 可寫寄存器 - 包含主控可以控制的配置數(shù)據(jù)袒餐。

稱為系統(tǒng)管理總線(SMBus)的通用協(xié)議實現(xiàn)存在于I2C之上飞蛹,以標準方式與寄存器數(shù)據(jù)交互谤狡。 SMBus命令由兩個I2C事務組成,如下所示:

I<sup>2</sup>C-SMBus

第一個事務標識要訪問的寄存器地址卧檐,第二個事務在該地址讀取或寫入數(shù)據(jù)墓懂。 從設備上的邏輯數(shù)據(jù)通常可以占用多個字節(jié)霉囚,并且因此包含多個寄存器地址捕仔。 提供給API的寄存器地址始終是要引用的第一個寄存器。

注:根據(jù)SMBus協(xié)議盈罐,設備將在地址和數(shù)據(jù)事務之間發(fā)送“重復啟動”條件榜跌。

外設I/O提供三種類型的SMBus命令來訪問寄存器數(shù)據(jù):

  • 字節(jié)數(shù)據(jù) - readRegByte()和writeRegByte()讀取或寫入一個8位寄存器值。
  • 字數(shù)據(jù) - readRegWord()和writeRegWord()讀取或寫入兩個連續(xù)的寄存器值作為16位小端字盅粪。 第一個寄存器地址被解釋為字中的最低有效字節(jié)(LSB)钓葫,后跟最高有效字節(jié)(MSB)。
  • 塊數(shù)據(jù) - readRegBuffer()和writeRegBuffer()讀取或寫入多達32個連續(xù)的寄存器值作為數(shù)組票顾。
// 修改單個寄存器的內(nèi)容
public void setRegisterFlag(I2cDevice device, int address) throws IOException {
    // 從從器件讀取一個寄存器
    byte value = device.readRegByte(address);
    // 設置bit 6
    value |= 0x40;
    // 將更新的值寫回從器件
    device.writeRegByte(address, value);
}

// 讀取寄存器塊
public byte[] readCalibration(I2cDevice device, int startAddress) throws IOException {
    // 讀取三個連續(xù)的寄存器值
    byte[] data = new byte[3];
    device.readRegBuffer(startAddress, data, data.length);
    return data;
}

傳輸原始數(shù)據(jù)

當與不同于SMBus定義其寄存器的I2C外設交互時础浮,或者根本不使用寄存器時,使用原始 read()和write()方法來完全控制通過線傳輸?shù)臄?shù)據(jù)字節(jié)奠骄。 這些方法將執(zhí)行單個I2C事務豆同,如下所示:

I<sup>2</sup>C-raw

使用原始傳輸時,器件將在傳輸之前發(fā)送單個啟動條件含鳞,并在之后發(fā)送單個停止條件影锈。 不可能將多個事務與“重復開始”條件組合。

注意:原始事務沒有明確的最大長度蝉绷,但是設備上的I2C控制器硬件可能對其可以處理的字節(jié)數(shù)有限制鸭廷。 如果您的外設需要大量數(shù)據(jù)傳輸,請查閱您的設備硬件文檔潜必。

以下代碼示例說明如何構造原始字節(jié)緩沖區(qū)并將其寫入I2C從設備:

public void writeBuffer(I2cDevice device, byte[] buffer) throws IOException {
    int count = device.write(buffer, buffer.length);
    Log.d(TAG, "Wrote " + count + " bytes over I2C.");
}

參考文獻 https://developer.android.google.cn/things/sdk

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末靴姿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子磁滚,更是在濱河造成了極大的恐慌佛吓,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垂攘,死亡現(xiàn)場離奇詭異维雇,居然都是意外死亡,警方通過查閱死者的電腦和手機晒他,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門吱型,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人陨仅,你說我怎么就攤上這事津滞÷燎郑” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵触徐,是天一觀的道長咪鲜。 經(jīng)常有香客問我,道長撞鹉,這世上最難降的妖魔是什么疟丙? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮鸟雏,結果婚禮上享郊,老公的妹妹穿的比我還像新娘。我一直安慰自己孝鹊,他們只是感情好炊琉,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惶室,像睡著了一般温自。 火紅的嫁衣襯著肌膚如雪玄货。 梳的紋絲不亂的頭發(fā)上皇钞,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音松捉,去河邊找鬼夹界。 笑死,一個胖子當著我的面吹牛隘世,可吹牛的內(nèi)容都是我干的可柿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼丙者,長吁一口氣:“原來是場噩夢啊……” “哼复斥!你這毒婦竟也來了?” 一聲冷哼從身側響起械媒,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤目锭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后纷捞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痢虹,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年主儡,在試婚紗的時候發(fā)現(xiàn)自己被綠了奖唯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡糜值,死狀恐怖丰捷,靈堂內(nèi)的尸體忽然破棺而出坯墨,到底是詐尸還是另有隱情,我是刑警寧澤病往,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布畅蹂,位于F島的核電站,受9級特大地震影響荣恐,放射性物質發(fā)生泄漏液斜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一叠穆、第九天 我趴在偏房一處隱蔽的房頂上張望少漆。 院中可真熱鬧,春花似錦硼被、人聲如沸示损。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽检访。三九已至,卻和暖如春仔掸,著一層夾襖步出監(jiān)牢的瞬間脆贵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工起暮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留卖氨,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓负懦,卻偏偏與公主長得像筒捺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子纸厉,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容