Android Things 外設(shè)I/O-SPI

寫(xiě)在前面的話:由于外設(shè)I/O涉及到GPIO、PWM肥荔、和串行通信三部分绿渣,而串行通信有講了I2C(IIC)、SPI燕耿、UART中符,這樣導(dǎo)致本文的篇幅過(guò)長(zhǎng)不便于閱讀,特此將本文分成幾部分來(lái)方便閱讀

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

串行通信

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

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

SPI

串行外設(shè)接口(SPI)設(shè)備通常被發(fā)現(xiàn)在需要快速數(shù)據(jù)傳輸速率的地方舟茶。 SPI非常適合高帶寬使用情況,例如外部非易失性存儲(chǔ)器和圖形顯示器堵第。 除了I2C吧凉,許多傳感器器件還支持SPI。
??SPI是同步串行接口踏志,這意味著它依賴于共享時(shí)鐘信號(hào)來(lái)同步設(shè)備之間的數(shù)據(jù)傳輸阀捅。 主器件控制時(shí)鐘信號(hào)的觸發(fā),所有其他連接的外設(shè)稱為從器件针余。 每個(gè)設(shè)備連接到同一組數(shù)據(jù)信號(hào)以形成總線饲鄙。
??理論上,SPI的數(shù)據(jù)傳輸速率僅受主機(jī)切換時(shí)鐘信號(hào)的速度的限制圆雁。 時(shí)鐘速度通常在16MHz至25MHz范圍內(nèi)忍级。 該高速共享時(shí)鐘允許SPI外設(shè)比UART更快速地傳輸數(shù)據(jù)并且具有更少的錯(cuò)誤。

SPI連接

SPI支持全雙工數(shù)據(jù)傳輸伪朽,意味著主站和從站可以同時(shí)交換信息轴咱。 為了支持全雙工傳輸,總線必須提供以下單獨(dú)的信號(hào),這使SPI成為最小的4線接口:

  • 主出從入(MOSI)
  • 主入從出(MISO)
  • 共享時(shí)鐘信號(hào)(CLK)
  • 公共接地參考(GND)

SPI支持沿同一總線連接的多個(gè)從器件朴肺。 與I2C不同窖剑,從器件使用硬件尋址。 每個(gè)從設(shè)備需要外部芯片選擇信號(hào)戈稿,以允許主設(shè)備將該特定設(shè)備尋址為數(shù)據(jù)傳輸目標(biāo)西土。 如果只使用一個(gè)從機(jī),則不需要該信號(hào)鞍盗。

管理設(shè)備連接

為了打開(kāi)到特定SPI從器件的連接需了,您需要知道總線的唯一名稱。 在開(kāi)發(fā)的初始階段或?qū)?yīng)用程序移植到新硬件時(shí)橡疼,可以使用getSpiBusList()從PeripheralManagerService找到所有可用的設(shè)備名稱:

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

支持多個(gè)硬件片選的SPI控制器將報(bào)告每個(gè)可用從端口作為單獨(dú)的設(shè)備名稱援所。 例如,在同一SPI總線上支持CS0欣除,CS1和CS2的電路板將返回類似于getSpiBusList()中的“SPI0.0”住拭,“SPI0.1”和“SPI0.2”的名稱。
??一旦知道目標(biāo)名稱历帚,就可以使用PeripheralManagerService連接到該設(shè)備滔岳。 與外圍設(shè)備通信后,記得關(guān)閉連接以釋放資源挽牢。 此外谱煤,在現(xiàn)有連接關(guān)閉之前,無(wú)法打開(kāi)與設(shè)備的新連接禽拔。 要關(guān)閉連接刘离,請(qǐng)使用設(shè)備的close()方法。

public class HomeActivity extends Activity {
    // SPI 設(shè)備名稱
    private static final String SPI_DEVICE_NAME = ...;

    private SpiDevice mDevice;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 嘗試訪問(wèn)SPI設(shè)備
        try {
            PeripheralManagerService manager = new PeripheralManagerService();
            mDevice = manager.openSpiDevice(SPI_DEVICE_NAME);
        } catch (IOException e) {
             Log.w(TAG, "Unable to access SPI 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 SPI device", e);
            }
        }
    }
}

配置時(shí)鐘和數(shù)據(jù)模式

在與SPI總線建立連接后睹栖,配置數(shù)據(jù)傳輸速率和操作模式以匹配同一總線上的從器件硫惕。 為了使數(shù)據(jù)傳輸成功,總線上的所有器件都必須具有相同的時(shí)鐘和數(shù)據(jù)格式行為野来。

注:有些從器件不能配置其SPI操作模式恼除,因此在選擇外設(shè)時(shí)請(qǐng)參考硬件文檔。

  1. 設(shè)置SPI模式曼氛,該模式定義時(shí)鐘信號(hào)的極性和相位豁辉。 您選擇的模式基于三個(gè)屬性:


    SPI時(shí)鐘
  2. 空閑電平:當(dāng)沒(méi)有數(shù)據(jù)傳輸時(shí),時(shí)鐘信號(hào)的電平(低或高)舀患。

  3. 前沿:每個(gè)時(shí)鐘脈沖的前沿徽级。

  4. 后沿:在每個(gè)時(shí)鐘脈沖中與前沿相反的過(guò)渡。
    支持以下模式:

    • MODE0 - 時(shí)鐘信號(hào)空閑聊浅,數(shù)據(jù)在前沿時(shí)鐘邊沿傳輸
    • MODE1 - 時(shí)鐘信號(hào)空閑為低電平餐抢,數(shù)據(jù)在后沿時(shí)鐘邊沿傳輸
    • MODE2 - 時(shí)鐘信號(hào)空閑堵幽,數(shù)據(jù)在前沿時(shí)鐘邊沿傳輸
    • MODE3 - 時(shí)鐘信號(hào)空閑為高電平,數(shù)據(jù)在后沿時(shí)鐘邊沿傳輸
  5. 設(shè)置以下SpiDevice參數(shù):

  • 頻率 - 指定以Hz為單位的共享時(shí)鐘信號(hào)弹澎。 時(shí)鐘信號(hào)能力因設(shè)備硬件而異。 在設(shè)置此值之前努咐,應(yīng)驗(yàn)證特定設(shè)備支持的頻率苦蒿。
  • 對(duì)齊 - 指定每個(gè)字節(jié)中各個(gè)位在總線上傳輸時(shí)的順序。 這也稱為數(shù)據(jù)的字節(jié)順序渗稍。 默認(rèn)情況下佩迟,數(shù)據(jù)將首先使用最高有效位(MSB)發(fā)送。
  • 每位字位 - 配置在切換給定從器件的片選線之間一次傳輸?shù)奈粩?shù)竿屹。 默認(rèn)值為每個(gè)字節(jié)8位报强。

以下代碼使用模式0,16MHz時(shí)鐘拱燃,每字8位和MSB優(yōu)先級(jí)配置SPI連接:

public void configureSpiDevice(SpiDevice device) throws IOException {
    // 低時(shí)鐘秉溉,前沿傳輸
    device.setMode(SpiDevice.MODE0);

    device.setFrequency(16000000);     // 16MHz
    device.setBitsPerWord(8);          // 8 BPW
    device.setBitJustification(false); // MSB first
}

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

SPI支持半雙工和全雙工數(shù)據(jù)傳輸。 大多數(shù)應(yīng)用程序應(yīng)該使用半雙工write()或read()方法與從設(shè)備交換數(shù)據(jù)碗誉。

// 半雙工數(shù)據(jù)傳輸
public void sendCommand(SpiDevice device, byte[] buffer) throws IOException {
    // 將數(shù)據(jù)移出到從機(jī)
    device.write(buffer, buffer.length);

    // 閱讀響應(yīng)
    byte[] response = new byte[32];
    device.read(response, response.length);
    ...
}

要執(zhí)行全雙工交換召嘶,請(qǐng)改用transfer()方法。 此方法接受兩個(gè)緩沖區(qū)進(jìn)行讀取和寫(xiě)入哮缺。 寫(xiě)緩沖區(qū)包含要發(fā)送到從設(shè)備的數(shù)據(jù)弄跌,而讀緩沖區(qū)為空并接受來(lái)自從設(shè)備的數(shù)據(jù)。

數(shù)據(jù)長(zhǎng)度必須小于或等于最小緩沖區(qū)大小尝苇。 對(duì)于全雙工傳輸铛只,緩沖區(qū)大小是相等的。

// 全雙工數(shù)據(jù)傳輸
public void sendCommand(SpiDevice device, byte[] buffer) throws IOException {
    byte[] response = new byte[buffer.length];
    device.transfer(buffer, response, buffer.length);
    ...
}

參考文獻(xiàn) https://developer.android.google.cn/things/sdk

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末糠溜,一起剝皮案震驚了整個(gè)濱河市淳玩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌诵冒,老刑警劉巖凯肋,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異汽馋,居然都是意外死亡侮东,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)豹芯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)悄雅,“玉大人,你說(shuō)我怎么就攤上這事铁蹈】硐校” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)容诬。 經(jīng)常有香客問(wèn)我娩梨,道長(zhǎng),這世上最難降的妖魔是什么览徒? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任狈定,我火速辦了婚禮,結(jié)果婚禮上习蓬,老公的妹妹穿的比我還像新娘纽什。我一直安慰自己,他們只是感情好躲叼,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布芦缰。 她就那樣靜靜地躺著,像睡著了一般枫慷。 火紅的嫁衣襯著肌膚如雪让蕾。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天或听,我揣著相機(jī)與錄音涕俗,去河邊找鬼。 笑死神帅,一個(gè)胖子當(dāng)著我的面吹牛再姑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播找御,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼元镀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了霎桅?” 一聲冷哼從身側(cè)響起栖疑,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滔驶,沒(méi)想到半個(gè)月后遇革,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡揭糕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年萝快,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片著角。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡揪漩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吏口,到底是詐尸還是另有隱情奄容,我是刑警寧澤冰更,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站昂勒,受9級(jí)特大地震影響蜀细,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜戈盈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一审葬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧奕谭,春花似錦、人聲如沸痴荐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)生兆。三九已至难捌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鸦难,已是汗流浹背根吁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留合蔽,地道東北人击敌。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像拴事,于是被迫代替她去往敵國(guó)和親沃斤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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