色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > Android串口調(diào)試助手實現(xiàn)

Android串口調(diào)試助手實現(xiàn) 時間:2018-08-16      來源:未知

串行接口 (Serial Interface) 是指數(shù)據(jù)一位一位地順序傳送,其特點是通信線路簡單,只要一對傳輸線就可以實現(xiàn)雙向通信(可以直接利用電話線作為傳輸線),從而大大降低了成本,特別適用于遠距離通信,但傳送速度較慢。一條信息的各位數(shù)據(jù)被逐位按順序傳送的通訊方式稱為串行通訊。串行通訊的特點是:數(shù)據(jù)位的傳送,按位順序進行,少只需一根傳輸線即可完成;成本低但傳送速度慢。串行通訊的距離可以從幾米到幾千米;根據(jù)信息的傳送方向,串行通訊可以進一步分為單工、半雙工和全雙工三種。

日常中的很多設(shè)備都是通過串口來傳輸數(shù)據(jù)的。所以,本項目在安卓的平臺上,建立了一個通過串口來收發(fā)數(shù)據(jù)的平臺。用戶可以通過設(shè)定不同的參數(shù)來連接不同的串口。

第 1 章 使用說明

軟件共分為三個部分:數(shù)據(jù)接收區(qū),數(shù)據(jù)發(fā)送區(qū),參數(shù)設(shè)置區(qū)。

使用之前需要設(shè)置參數(shù):需要打開的設(shè)備文件和打開的波特率。

點擊Open就可以打開串口,如果這時候串口有數(shù)據(jù)過來,就可以在左側(cè)顯示出來,同時可以設(shè)定是否以十六進制顯示數(shù)據(jù)。

如果想要向串口發(fā)送數(shù)據(jù),在下方輸入數(shù)據(jù),點擊Send就可以發(fā)送。

第 2 章 環(huán)境搭建

2.1 Android 開發(fā)環(huán)境的安裝與配置

Android應(yīng)用軟件開發(fā)需要的開發(fā)環(huán)境在路徑“光盤\Android應(yīng)用開發(fā)環(huán)境\”下:

JDK: JDK\JDK8\jdk-8u5-windows-i586.exe(32bit)或者jdk-8u5-windows-x64.exe(64bit)

(從JDK 8.0開始不支持Windows XP操作系統(tǒng),使用Windows XP的用戶可以使用JDK7目錄下的內(nèi)容)

ADT: adt-bundle-windows-x86.7z(32bit)或者adt-bundle-windows-x86_64.7z(64bit)

以下主要介紹在Windows環(huán)境下搭建Android開發(fā)環(huán)境的步驟和注意事項。

2.2 安裝JDK和配置Java開發(fā)環(huán)境

雙擊JDK\JDK8\jdk-8u5-windows-i586.exe(32bit操作系統(tǒng))或者jdk-8u5-windows-x64.exe(64bit操作系統(tǒng))進行安裝(從JDK 8.0開始不支持Windows XP操作系統(tǒng),使用Windows XP的用戶可以使用JDK7目錄下的內(nèi)容選擇代替JDK8目錄下的內(nèi)容)。接受許可證,選擇需要安裝的組件和安裝路徑后,單擊“下一步”按鈕,完成安裝過程。

安裝完成后,利用以下步驟檢查安裝是否成功:打開Windows CMD窗口,在CMD窗口中輸入java –version命令,如果屏幕出現(xiàn)下圖所示的代碼信息,說明JDK安裝成功。

XP下安裝JDK7如下:

非XP下安裝JDK8如下:

2.3 解壓adt-bundle-windows

JDK安裝成功后,使用軟件解壓ADT目錄下的adt-bundle-windows-x86.7z(32bit)或者adt-bundle-windows-x86_64.7z(64bit)。

注意:解壓路徑不包含中文;

2.4 運行Eclipse

解壓完畢后,直接執(zhí)行其中的eclipse\eclipse.exe文件,Eclipse可以自動找到用戶前期安裝的JDK路徑。

2.5 配置Eclipse

運行解壓目錄下的eclipse\eclipse.exe,為自己選擇一個工作目錄Workspace,不要有中文路徑,不選擇默認也可以。

需要為Eclipse關(guān)聯(lián)SDK的安裝路徑,即解壓路徑下的sdk目錄。在Eclipse中,點擊Window->Preferences,會看到其中添加了Android的配置,按圖所示的操作,然后點擊Apply,后點擊OK即可。

完成以上步驟后,設(shè)置Eclipse環(huán)境

勾選Android相關(guān)的工具,點擊OK(如果已經(jīng)勾選,則不理會)。

第 3 章 NDK環(huán)境配置

3.1 安裝NDK工具包

安裝包已經(jīng)放到“華清遠見開發(fā)環(huán)境”光盤當(dāng)中,名字為“android-ndk-r10d-windows-x86”,這個是針對32位系統(tǒng)使用的工具包,如果有64位的需求可以到我們提供的網(wǎng)盤上進行下載。

將安裝包拷貝到E:盤,雙擊程序即可在當(dāng)前路徑進行安裝。

3.2 配置Eclipse

打開Eclipse,點Window->Preferences->Android->NDK,設(shè)置NDK路徑,例如E:\ android-ndk-r10d

新建一個Android工程,在工程上右鍵點擊Android Tools->Add Native Support...,然后給我們的.so文件取個名字,例如:my-ndk

這時候工程就會多一個jni的文件夾,jni下有Android.mk和my-ndk.cpp文件。Android.mk是NDK工程的Makefile,my-ndk.cpp就是NDK的源文件。

完成了,然后運行。運行之前先編譯NDK,然后在編譯JAVA代碼。編譯也許會遇到Unable to launch cygpath. Is Cygwin on the path等問題?如何解決?如下:

工程右鍵,點Properties->C/C++ Build的Building Settings中去掉Use default build command,然后輸入${NDKROOT}/ndk-build.cmd

在C/C++ Build中點擊Environment,點Add...添加環(huán)境變量NDKROOT,值為NDK的根目錄

接著,按照如下圖所示的位置,根據(jù)使用的SDK的版本的不同選擇不同的頭文件包,例如如果使用的是android4.0.3 的話,就選擇:E:\ android-ndk-r10d\platforms\android-15\arch-arm\usr\include

之后,再次編譯運行工程,即可成功。

第 1 章 源碼編譯

1.1 導(dǎo)入源碼

打開Eclipse環(huán)境,選擇File->Import。

然后,導(dǎo)入光盤資料中的“BlueHelper”工程,勾選下圖中的選項。

點擊finish完成工程的導(dǎo)入

1.1 運行程序

注意:如果在調(diào)試開發(fā)板的時候,出現(xiàn)ADB連接不上的問題(已知華清遠見FSPAD723開源平板),可以試著替換Android SDK的ADB工具(把光盤\Android應(yīng)用開發(fā)環(huán)境\ADB\ADB1.0.26\下的4個文件拷貝到用戶ADT解壓目錄下的sdk\platform-tools中)

開發(fā)期間,在實際的設(shè)備上運行Android程序與在模擬器上運行該程序的效果幾乎相同,需要做的就是用USB電纜連接手機與計算機,并安裝一個對應(yīng)的設(shè)備驅(qū)動程序。如果模擬器窗口已打開,請將其關(guān)閉。只要將開發(fā)平臺通過USB下載線與計算機相連,應(yīng)用程序就會在開發(fā)平臺上加載并運行。

在Eclipse中選擇“Run” →“Run”(或Debug)命令(或者在工程上點擊右鍵),這時會彈出一個窗口,讓你選擇用模擬器還是手機來顯示,如果選擇手機,即可在手機上運行該程序。

第 2 章 詳細設(shè)計

2.1 UartTool串口工具

因為本項目要連接上層java和底層c語言,所以需要先聲明本地方法。

NormalText Code

private static native int NativeFileOpen(String filename, int size);// 成功返回0,失敗-1

private static native int NativeFileClose();// 返回是否關(guān)閉成功

private static native int NativeFileRead(byte[] buf, int size);// 返回讀取數(shù)據(jù)的個數(shù)

private static native int NativeFileWrite(byte[] buf, int size);// 返回寫入的數(shù)據(jù)長度

串口初始化函數(shù),需要傳遞想要打開的串口的文件名和波特率。

NormalText Code

public Boolean uartInit(String filename, int size) {

if ((fd = NativeFileOpen(filename, size)) != -1) {

uartInit = true;

return true;

} else {

log.E("%%%%% _uart_init() == -1 !!!! %%%%%");

return false;

}

}

接下來要封裝讀函數(shù)和寫函數(shù),利用的是底層的read和write。

NormalText Code

public String uartRead(int num) {

byte[] data = new byte[num];

int re = 0;

if ((re = NativeFileRead(data, data.length)) > 0) {

return new String(data, 0, re);

} else {

log.E("%%%%% _uart_read() != num !!!! %%%%%");

return null;

}

}

NormalText Code

public Boolean uartWrite(byte[] data) {

if (NativeFileWrite(data, data.length) > 0) {

return true;

} else {

log.E("%%%%% _uart_write(data) == -1 !!!! %%%%%");

return false;

}

}

2.2 Uarthelper調(diào)試助手

本項目中,線程和UI線程通信是通過Handler 機制實現(xiàn)的。作用是將數(shù)據(jù)傳輸?shù)経I線程進行顯示。

NormalText Code

private Handler handler = new Handler() {

@SuppressLint("SimpleDateFormat")

public void handleMessage(Message msg) {

switch (msg.what) {

case 0:

if (!check.isChecked()) {

treceive.append(recdate + " ");

} else {

treceive.append("0x" + printHex(recdate.getBytes()) + " ");

}

scroll.scrollTo(0,

treceive.getMeasuredHeight() - scroll.getHeight());

recdate = "";

break;

default:

break;

}

}

};

設(shè)定按鈕的監(jiān)聽時間,當(dāng)點擊Open按鈕的時候,按照設(shè)定的參數(shù)去打開對應(yīng)的串口,成功后啟動讀和寫的線程,同時設(shè)定按鈕文字為Close,屏幕進行提示打開成功。

NormalText Code

save.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

if (open == false) {

if (!fd.getText().toString().equalsIgnoreCase("")) {

if (uart.uartInit("/dev/" + fd.getText().toString(),

rate_t) == true) {

Toast.makeText(Uarthelper.this, "打開成功".toString(),

Toast.LENGTH_LONG).show();

log.E("打開文件 " + "/dev/" + fd.getText().toString());

open = true;

threadon = true;

readThread = new ReadThread();

readThread.start();

save.setText("Close".toString());

} else {

Toast.makeText(Uarthelper.this,

"文件打開失敗".toString(), Toast.LENGTH_SHORT)

.show();

}

} else {

Toast.makeText(Uarthelper.this, "請?zhí)顚懲暾?quot;.toString(),

Toast.LENGTH_SHORT).show();

}

} else {

Toast.makeText(Uarthelper.this, "正在關(guān)閉串口。。。".toString(),

Toast.LENGTH_LONG).show();

threadon = false;

uart.uartWrite("s".getBytes());

UartQThread uartQThread = new UartQThread();

uartQThread.start();

open = false;

save.setText("Open".toString());

}

}

});

讀取數(shù)據(jù)的線程,調(diào)用底層的uartRead函數(shù),接收到數(shù)據(jù)后,將數(shù)據(jù)存入全局變量,然后通知主線程來顯示。

NormalText Code

class ReadThread extends Thread {

String tmp = null;

@Override

public void run() {

log.E("讀取數(shù)據(jù)線程啟動!");

while (threadon) {

tmp = uart.uartRead(10);

if (threadon) {

if (tmp == null) {

// log.E("接收數(shù)據(jù)出錯!");

} else {

log.E("接收數(shù)據(jù) " + tmp);

recdate += tmp;

NoteThread noteThread = new NoteThread();

noteThread.start();

}

}

}

log.E("讀取數(shù)據(jù)線程結(jié)束!");

}

}

如果想要發(fā)送數(shù)據(jù),需要調(diào)用底層的uartWrite函數(shù)。

NormalText Code

send.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

if (uart.uartInit == true) {

String date = tsent.getText().toString();

if (uart.uartWrite(date.getBytes()) == true) {

// tsent.setText("");

log.E("發(fā)送數(shù)據(jù) " + date);

} else {

Toast.makeText(Uarthelper.this, "發(fā)送失敗".toString(),

Toast.LENGTH_SHORT).show();

}

} else {

Toast.makeText(Uarthelper.this, "請先設(shè)置串口".toString(),

Toast.LENGTH_SHORT).show();

}

}

});

2.3 NDK程序詳解

2.3.1 jni.c

這個文件的作用主要是連結(jié)上層和底層之間的函數(shù)。

首先需要定義一個結(jié)構(gòu)體,這個結(jié)構(gòu)體表明了上層函數(shù)名稱和底層函數(shù)名稱的對應(yīng)關(guān)系。并且函數(shù)名稱的書寫是有要求的,Java_cn_com_farsight_tool_UartTool_NativeFileRead類似這樣的,格式為java+程序包名+函數(shù)名稱。

NormalText Code

static JNINativeMethod gMethods[] = { { "NativeFileOpen",

"(Ljava/lang/String;I)I",

(void *) Java_cn_com_farsight_tool_UartTool_NativeFileOpen }, {

"NativeFileRead", "([BI)I",

(void *) Java_cn_com_farsight_tool_UartTool_NativeFileRead }, {

"NativeFileWrite", "([BI)I",

(void *) Java_cn_com_farsight_tool_UartTool_NativeFileWrite }, {

"NativeFileClose", "()I",

(void *) Java_cn_com_farsight_tool_UartTool_NativeFileClose }, };

int register_cn_com_farsight_tool_UartTool(JNIEnv *env) {

return jniRegisterNativeMethods(env, kClassPathName, gMethods,

sizeof(gMethods) / sizeof(gMethods[0]));

然后在這些函數(shù)中調(diào)用底層的函數(shù)來實現(xiàn)對應(yīng)的功能。

NormalText Code

jint Java_cn_com_farsight_tool_UartTool_NativeFileRead(JNIEnv* env,

jobject thiz, jbyteArray buf, jint size) {

unsigned char *buf_char = (char*) ((*env)->GetByteArrayElements(env, buf,

NULL));

int result = uart_read(buf_char, size);

(*env)->ReleaseByteArrayElements(env, buf, buf_char, 0);

return result;

}

2.3.2 onLoad.cpp

這個文件的主要作用是完成加載底層的庫文件的時候的工作。OnLoad函數(shù)在加載庫文件的時候會第一個執(zhí)行。

NormalText Code

jint JNI_OnLoad(JavaVM* vm, void* reserved) {

JNIEnv* env = NULL;

jint result = JNI_ERR;

sVm = vm;

if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {

LOGE("GetEnv failed!");

return result;

}

if (register_cn_com_farsight_tool_UartTool(env) != JNI_OK) {

LOGE("can't load register_cn_com_farsight_tool_UartTool()");

goto end;

}

LOGE("loaded succeed");

result = JNI_VERSION_1_4;

end: return result;

}

jniRegisterNativeMethods函數(shù)的作用是將剛才的關(guān)系結(jié)構(gòu)體注冊進系統(tǒng)當(dāng)中,同時,尋找上層需要調(diào)用這些底層函數(shù)的類。

NormalText Code

int jniRegisterNativeMethods(JNIEnv* env, const char* className,

const JNINativeMethod* gMethods, int numMethods) {

jclass clazz;

LOGE("Registering %s natives\n", className);

clazz = env->FindClass(className);

if (clazz == NULL) {

LOGE("Native registration unable to find class '%s'\n", className);

return -1;

}

if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {

LOGE("RegisterNatives failed for '%s'\n", className);

return -1;

}

return 0;

}

2.3.3 uart.c

這個文件就是底層函數(shù)的具體實現(xiàn)了。uart_get函數(shù)的功能就是打開串口,根據(jù)上層傳遞過來的參數(shù)和波特率來打開設(shè)備文件。

NormalText Code

int uart_get(char *filename, int rate) { //成功返回0,失敗-1

struct termios opt;

// uart

if ((fd = open(filename, O_RDWR | O_NOCTTY, 0777)) == -1) {

LOGE("UART open error!!! :%s ", strerror(errno));

return -1;

}

//初始化串口

tcgetattr(fd, &opt);

LOGE("rate is %d", rate);

switch (rate) {

case 4800:

cfsetispeed(&opt, B4800);

cfsetospeed(&opt, B4800);

break;

case 9600:

cfsetispeed(&opt, B9600);

cfsetospeed(&opt, B9600);

break;

case 19200:

cfsetispeed(&opt, B19200);

cfsetospeed(&opt, B19200);

break;

case 38400:

cfsetispeed(&opt, B38400);

cfsetospeed(&opt, B38400);

break;

case 115200:

LOGE("rate is %d", rate);

cfsetispeed(&opt, B115200);

cfsetospeed(&opt, B115200);

break;

default:

cfsetispeed(&opt, B115200);

cfsetospeed(&opt, B115200);

break;

}

opt.c_cflag |= (CLOCAL | CREAD);

opt.c_cflag &= ~CSIZE;

opt.c_cflag &= ~CRTSCTS;

opt.c_cflag |= CS8;

opt.c_iflag |= IGNPAR;

opt.c_cflag &= ~CSTOPB;

opt.c_oflag = 0;

opt.c_lflag = 0;

tcsetattr(fd, TCSANOW, &opt);

LOGE("UART open %s succeed!!!", filename);

return 0;

}

當(dāng)要讀取數(shù)據(jù)的時候,先將上層傳遞下來的緩沖清空,使用read函數(shù)進行數(shù)據(jù)的讀取,然后返回。

NormalText Code

int uart_read(unsigned char *buf, int size) { //返回讀取數(shù)據(jù)的個數(shù)

int len = 0;

memset(buf, 0, size);

int result = read(fd, buf, size);

if (result <= 0) {

LOGE("uart_read(%d) is error %s", size, strerror(errno));

return -1;

}

// while (result < size) {

// len = read(fd, buf + result, size - result);

// result += len;

// }

LOGE("uart_read is %s", buf);

return result;

}

直接調(diào)用write來向設(shè)備寫入數(shù)據(jù)。

NormalText Code

int uart_write(const unsigned char *buf, int size) { //返回寫入的數(shù)據(jù)長度

int result = write(fd, buf, size);

if (result > 0) {

LOGE("uart write is %s", buf);

}

return result;

}

后程序結(jié)束的時候,關(guān)閉設(shè)備文件。

NormalText Code

int uart_close() {

close(fd);

LOGE("UART close succeed!!!");

return 0;

}

上一篇:linux make命令安裝詳解

下一篇:fork函數(shù)的小誤區(qū)

熱點文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗分享
熱點新聞推薦
前臺專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權(quán)所有 ,京ICP備16055225號-5京公海網(wǎng)安備11010802025203號

回到頂部

主站蜘蛛池模板: 亚洲精品国偷自产在线99人热 | 欧美天堂一区二区 | 97国产婷婷综合在线视频 | 在线免费看污 | 女人被添全过程A片久久AV | 蜜臀aⅴ一区二区三区 | 精品人妻无码一区二区三区换脸 | 变态另类AV天堂手机版 | 999福利视频 | 日韩卡一卡二无线乱码新区仙踪林 | 成人午夜特黄aaaaa片男男 | 岳好紧好湿夹太紧了好爽矜持 | 精品无码欧美一区二区三区不卡 | 日本黄页网站免费大全1688 | 在线观看AV网站永久免费观看 | 97精品一区二区视频在线观看 | 久久性色欲AV免费精品观看 | 一道本AV免费不卡播放 | 亚洲中文久久精品无码 | 伊人色合天天久久综合网 | 无码人妻精品丰满熟妇区 | 国产精品内射久久久久欢欢 | 亚欧无码AV在线观看 | 老王亚洲福利在线观看 | 亚洲AV无码无在线观看红杏 | 网友自拍露脸国语对白 | 欧美精品国外破除大片扒开特写 | 亚洲精品AV无码精品 | 国产成人久久精品流白浆 | 伊人色综合一区二区三区 | 我的巨臀人肉坐便器老师 | 中文字幕色偷偷人妻久久 | 精品人妻久久久久久888 | 亚洲国产精品成人久久久麻豆 | 午夜无码片在线观看影视 | 亚洲AV综合AV一区二区三区 | 好紧好爽午夜视频 | 欧美成人aaa片一区国产精品 | 男女18禁啪啪无遮挡 | 小荡货腿张开让我cao爽视频 | 午夜寂寞视频无码专区 |