首頁 > 評(píng)測(cè) > NXP i.MX7D與AndroidThings系列之五:I2C通信
NXP i.MX7D與AndroidThings系列之五:I2C通信
- [導(dǎo)讀]
- 本文將介紹如何通過I2C通信來實(shí)現(xiàn)屏幕點(diǎn)亮和顯示。
“其實(shí)AndroidThings的API已將底層的細(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ù)傳送。
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.MX7D的I2C接口如下
要在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地址)。
我們知道在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
- 我要投稿
-
歡迎入駐,開放投稿
- NRF52810藍(lán)牙數(shù)字耳機(jī)找人定制
預(yù)算:¥30005天前
- 125KW模塊式PCS軟硬件外包開發(fā)
預(yù)算:¥1100000015小時(shí)前
- 12V汽車啟動(dòng)電源項(xiàng)目BMS設(shè)計(jì)
預(yù)算:¥50000023小時(shí)前
- 數(shù)據(jù)可視化軟件 開發(fā)
預(yù)算:¥5000023小時(shí)前
- PLC項(xiàng)目調(diào)試修改
預(yù)算:¥100001天前
- 起動(dòng)電機(jī)控制器開發(fā)
預(yù)算:¥1100001天前