首頁 > 評(píng)測(cè) > NXP i.MX7D與AndroidThings系列之五:I2C通信

NXP i.MX7D與AndroidThings系列之五:I2C通信

NXP   IMX7D   AndroidThings   I2C   
  • 作者:SATURN
  • 來源:21ic
  • [導(dǎo)讀]
  • 本文將介紹如何通過I2C通信來實(shí)現(xiàn)屏幕點(diǎn)亮和顯示。

 “其實(shí)AndroidThingsAPI已將底層的細(xì)節(jié)大大抽象了,正如Arduino簡化了底層細(xì)節(jié)一樣,這樣一來將大大提高生產(chǎn)效率。本例的復(fù)雜之處在LCD的具體操作上,所以除了掌握AndroidThings基礎(chǔ)知識(shí),要想在Maker領(lǐng)域中取得更好的效果,學(xué)會(huì)看數(shù)據(jù)手冊(cè)也算是基本功之一,如果實(shí)在啃不動(dòng)數(shù)據(jù)手冊(cè),也可以參考別人的代碼來改,不過適用性就差了一點(diǎn)點(diǎn)。”

歡迎加入Android Things交流群:452863046

先給小白講下I2C,大神直接略過就好。

I2C總線是由Philips公司開發(fā)的一種簡單、雙向二線制同步串行總線。它只需要兩根線即可在連接于總線上的器件之間傳送信息。 主器件用于啟動(dòng)總線傳送數(shù)據(jù),并產(chǎn)生時(shí)鐘以開放傳送的器件,此時(shí)任何被尋址的器件均被認(rèn)為是從器件.在總線上主和從、發(fā)和收的關(guān)系不是恒定的,而取決于此時(shí)數(shù)據(jù)傳送方向。如果主機(jī)要發(fā)送數(shù)據(jù)給從器件,則主機(jī)首先尋址從器件,然后主動(dòng)發(fā)送數(shù)據(jù)至從器件,最后由主機(jī)終止數(shù)據(jù)傳送;如果主機(jī)要接收從器件的數(shù)據(jù),首先由主器件尋址從器件.然后主機(jī)接收從器件發(fā)送的數(shù)據(jù),最后由主機(jī)終止接收過程。在這種情況下.主機(jī)負(fù)責(zé)產(chǎn)生定時(shí)時(shí)鐘和終止數(shù)據(jù)傳送。

 rId21.png

 

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

• 共享時(shí)鐘信號(hào)(SCL

• 共享數(shù)據(jù)線(SDA

• 公共地參考(GND

I2C支持沿同一總線連接的多個(gè)從設(shè)備。與SPI不同,從設(shè)備使用I2C軟件協(xié)議進(jìn)行尋址。每個(gè)設(shè)備都使用唯一的地址進(jìn)行編程,并僅響應(yīng)主設(shè)備發(fā)送到該地址的傳輸。即使總線僅包含一個(gè)從站,每個(gè)從站設(shè)備也必須具有一個(gè)地址。

i.MX7DI2C接口如下

 rId22.png

 

要在AndroidThings中使用I2C設(shè)備,需要啟用如下權(quán)限

<uses-permission android:name="com.google.android.things.permission.USE_PERIPHERAL_IO" />

正如上一節(jié)介紹的一樣,如果想要查看I2C接口列表,可以使用PeripheralManager來實(shí)現(xiàn),下面是具體的代碼及輸出

Log.d(TAG, "I2C: " + PeripheralManager.getInstance().getI2cBusList());
 
LogCat窗口會(huì)看到如下的輸出:
 
/com.example.netlh.lcd1602 D/AndroidThings: I2C: [I2C1, I2C2]

實(shí)現(xiàn)I2C通信需要I2C設(shè)備,這里我們使用的是Grove RGB LCD顯示屏,這是一個(gè)1602顯示屏,支持RGB三色背光。該屏包括兩個(gè)I2C設(shè)備,一個(gè)地址為0x62(RGB地址),另一個(gè)為0x3e(LCD地址)。

 rId23.jpg

 

我們知道在Linux下,可以使用 i2c-tools來方便的調(diào)試I2C設(shè)備,該工具包括i2cdetect,i2cdump等常用命令,可以方便的檢測(cè)并操作i2c設(shè)備。

使用i2c-tools源碼,可以編譯出android可用的版本,具體編譯方法請(qǐng)自行參考。

利用adb命令將編譯后的工具上傳到i.MX7D,下面是在i.MX7D上的用法

adb root
adb push i2cdetect /data
...
adb shell 
imx7d_pico:/ #

總而言之,就是將i2cdetect等工具上傳到開發(fā)板,然后其它的附加操作例如添加執(zhí)行權(quán)限等都省略不提,接下來使用i2cdetect來檢測(cè)下設(shè)備是否在線

127|imx7d_pico:/ # /data/i2cdetect -l
i2c-3   i2c             30a50000.i2c                            I2C adapter
i2c-1   i2c             30a30000.i2c                            I2C adapter
i2c-0   i2c             30a20000.i2c                            I2C adapter
imx7d_pico:/ # /data/i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 -- -- -- -- -- -- UU -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- 62 -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --
imx7d_pico:/ #

設(shè)備地址已檢測(cè),接下來就開始寫代碼了。

LCD的數(shù)據(jù)手冊(cè)請(qǐng)參考官方給出的文檔,這里我們專門定義了一個(gè)類Lcd1602,代碼內(nèi)容如下

package com.example.netlh.lcd1602;
 
import com.google.android.things.pio.I2cDevice;
import com.google.android.things.pio.PeripheralManager;
 
import java.io.IOException;
 
public class Lcd1602 {
    private final static int LCD_I2C_ADDRESS = 0x3E;
    private final static int RGB_I2C_ADDRESS = 0x62; 
 
    public final static String DEBUG_TAG = "GROVE LCD RGB";
    private final static String I2C_NAME = "I2C1";
 
    private I2cDevice mLcdDevice, mRgbDevice;
 
 
    public void setColor(int r, int g, int b) throws IOException {
        mRgbDevice.writeRegByte(0, (byte)1);
        mRgbDevice.writeRegByte(1, (byte) 0);
        mRgbDevice.writeRegByte(0x08, (byte) 0xaa);
        mRgbDevice.writeRegByte(4, (byte) r);
        mRgbDevice.writeRegByte(3, (byte) g);
        mRgbDevice.writeRegByte(2, (byte) b);
 
 
    }
 
    private void textCommand(int cmd) throws IOException{
        mLcdDevice.writeRegByte(0x80, (byte)cmd);
    }
 
    private void setPosition(int row, int col) throws IOException {
        if(row == 0) {
            textCommand(0x80 + col);
        }
 
        if(row == 1) {
            textCommand(0xC0 + col);
        }
    }
 
    public void setText(int row, int col, byte[] msg) throws IOException {
        //textCommand(0x01);
        textCommand(0x08 | 0x04);  //display on, no cursor
        textCommand(0x28); //two lines
 
        setPosition(row, col);
 
        for(int i = 0; i < msg.length; i ++) {
            mLcdDevice.writeRegByte(0x40, msg[i]);
        }
 
 
    }
 
    public void clear() throws IOException {
        textCommand(0x01); //clear screen
    }
 
    public void setup() {
        PeripheralManager peripheralManager = PeripheralManager.getInstance();
        try {
            mLcdDevice = peripheralManager.openI2cDevice(I2C_NAME, LCD_I2C_ADDRESS);
            mRgbDevice = peripheralManager.openI2cDevice(I2C_NAME, RGB_I2C_ADDRESS);
        } catch (IOException e) {
            e.printStackTrace();
        }
 
    }
 
    public void close(){
 
        if(mLcdDevice != null) {
            try {
                mLcdDevice.close();
                mLcdDevice = null;
 
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
 
        if(mRgbDevice != null) {
            try {
                mRgbDevice.close();
                mRgbDevice = null;
 
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

該類的內(nèi)容比較簡單,只提供一些簡單的操作功能,如設(shè)備背景,顯示字串內(nèi)容,以及關(guān)閉設(shè)備等操作。這里包括的大部分命令項(xiàng)比如0x01, 0x04需要查詢LCD的數(shù)據(jù)手冊(cè)。

主要的功能實(shí)現(xiàn)如下

  • 本文系21ic原創(chuàng),未經(jīng)許可禁止轉(zhuǎn)載!

網(wǎng)友評(píng)論

  • 聯(lián)系人:巧克力娃娃
  • 郵箱:board@21ic.com
  • 我要投稿
  • 歡迎入駐,開放投稿

熱門標(biāo)簽
項(xiàng)目外包 more+