久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > Android串口調試助手實現

Android串口調試助手實現 時間:2018-08-16  ;    來(lai)源(yuan):未知

串(chuan)行(xing)接口 (Serial Interface) 是(shi)指(zhi)數(shu)據(ju)(ju)一(yi)位(wei)(wei)一(yi)位(wei)(wei)地(di)順(shun)序(xu)(xu)傳(chuan)(chuan)送(song),其特(te)點是(shi)通(tong)信(xin)線(xian)路簡單(dan),只要一(yi)對(dui)傳(chuan)(chuan)輸(shu)線(xian)就可(ke)以實(shi)現雙(shuang)向通(tong)信(xin)(可(ke)以直(zhi)接利用(yong)電話線(xian)作為(wei)(wei)傳(chuan)(chuan)輸(shu)線(xian)),從而大(da)大(da)降低了成本,特(te)別適用(yong)于遠(yuan)距離(li)通(tong)信(xin),但(dan)傳(chuan)(chuan)送(song)速(su)度較慢。一(yi)條信(xin)息的各位(wei)(wei)數(shu)據(ju)(ju)被逐(zhu)位(wei)(wei)按順(shun)序(xu)(xu)傳(chuan)(chuan)送(song)的通(tong)訊方式稱為(wei)(wei)串(chuan)行(xing)通(tong)訊。串(chuan)行(xing)通(tong)訊的特(te)點是(shi):數(shu)據(ju)(ju)位(wei)(wei)的傳(chuan)(chuan)送(song),按位(wei)(wei)順(shun)序(xu)(xu)進(jin)(jin)行(xing),少只需一(yi)根傳(chuan)(chuan)輸(shu)線(xian)即可(ke)完成;成本低但(dan)傳(chuan)(chuan)送(song)速(su)度慢。串(chuan)行(xing)通(tong)訊的距離(li)可(ke)以從幾米(mi)到幾千米(mi);根據(ju)(ju)信(xin)息的傳(chuan)(chuan)送(song)方向,串(chuan)行(xing)通(tong)訊可(ke)以進(jin)(jin)一(yi)步分為(wei)(wei)單(dan)工(gong)(gong)、半雙(shuang)工(gong)(gong)和全雙(shuang)工(gong)(gong)三種。

日常中(zhong)的很(hen)多設(she)備都是通(tong)過(guo)串(chuan)(chuan)口來(lai)傳輸(shu)數據的。所(suo)以(yi),本項目(mu)在安卓的平臺(tai)上(shang),建(jian)立了(le)一(yi)個通(tong)過(guo)串(chuan)(chuan)口來(lai)收發(fa)數據的平臺(tai)。用戶可以(yi)通(tong)過(guo)設(she)定不同的參數來(lai)連接不同的串(chuan)(chuan)口。

第(di) 1 章 使用說(shuo)明

軟件共分為三個部分:數(shu)據接收區(qu),數(shu)據發(fa)送(song)區(qu),參數(shu)設置區(qu)。

使用之(zhi)前需要(yao)設置參數:需要(yao)打開的(de)設備文件和打開的(de)波(bo)特率(lv)。

點擊Open就可以打開串口,如(ru)果這(zhe)時(shi)候串口有數據(ju)過來,就可以在(zai)左側(ce)顯(xian)示出(chu)來,同時(shi)可以設(she)定是否(fou)以十六(liu)進制顯(xian)示數據(ju)。

如果想要向串口發送(song)數據,在(zai)下方(fang)輸入數據,點擊Send就可以發送(song)。

第(di) 2 章 環境搭(da)建

2.1 Android 開發環境的安(an)裝與配置(zhi)

Android應(ying)用軟件開(kai)發需要(yao)的開(kai)發環境(jing)在路徑“光盤(pan)\Android應(ying)用開(kai)發環境(jing)\”下:

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

(從JDK 8.0開始不支持(chi)Windows XP操(cao)作系(xi)統,使(shi)用Windows XP的(de)用戶可以(yi)使(shi)用JDK7目錄下(xia)的(de)內容)

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

以(yi)下主(zhu)要介紹在Windows環境下搭建Android開發(fa)環境的步驟和注(zhu)意(yi)事項。

2.2 安裝JDK和配置Java開發環境

雙擊JDK\JDK8\jdk-8u5-windows-i586.exe(32bit操作(zuo)系統)或者(zhe)jdk-8u5-windows-x64.exe(64bit操作(zuo)系統)進行(xing)安(an)(an)裝(zhuang)(從JDK 8.0開(kai)始不支(zhi)持Windows XP操作(zuo)系統,使(shi)用Windows XP的用戶可以使(shi)用JDK7目錄下(xia)的內(nei)(nei)容選(xuan)擇代替JDK8目錄下(xia)的內(nei)(nei)容)。接受許可證(zheng),選(xuan)擇需要(yao)安(an)(an)裝(zhuang)的組(zu)件和(he)安(an)(an)裝(zhuang)路徑后,單擊“下(xia)一步”按鈕,完成安(an)(an)裝(zhuang)過程(cheng)。

安(an)裝(zhuang)完(wan)成(cheng)(cheng)后,利用以下(xia)步驟檢查安(an)裝(zhuang)是否成(cheng)(cheng)功:打開Windows CMD窗口(kou),在CMD窗口(kou)中輸入java –version命令,如果屏(ping)幕(mu)出(chu)現(xian)下(xia)圖所(suo)示(shi)的(de)代碼信息,說明JDK安(an)裝(zhuang)成(cheng)(cheng)功。

XP下安裝JDK7如下:

非XP下安裝(zhuang)JDK8如下:

2.3 解(jie)壓adt-bundle-windows

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

注意(yi):解壓路徑不包(bao)含中文;

2.4 運行Eclipse

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

2.5 配置Eclipse

運行解(jie)壓目(mu)(mu)錄下的eclipse\eclipse.exe,為(wei)自己選擇(ze)一(yi)個(ge)工作目(mu)(mu)錄Workspace,不要有中文路徑(jing),不選擇(ze)默認(ren)也(ye)可以(yi)。

需要為Eclipse關(guan)聯SDK的(de)安(an)裝路徑(jing),即(ji)解壓路徑(jing)下的(de)sdk目錄(lu)。在Eclipse中,點(dian)擊(ji)Window->Preferences,會看到其(qi)中添加了Android的(de)配(pei)置,按圖所(suo)示的(de)操作,然后點(dian)擊(ji)Apply,后點(dian)擊(ji)OK即(ji)可。

完成以上步驟后,設(she)置Eclipse環(huan)境

勾選(xuan)(xuan)Android相關的(de)工具,點(dian)擊OK(如果已經勾選(xuan)(xuan),則(ze)不理會)。

第 3 章(zhang) NDK環境配置

3.1 安(an)裝(zhuang)NDK工具包

安裝包(bao)已經放到“華清遠見(jian)開發環(huan)境”光盤當中,名(ming)字為“android-ndk-r10d-windows-x86”,這個是針對32位系統(tong)使用(yong)的(de)工具包(bao),如果有64位的(de)需求可以到我們(men)提供的(de)網盤上(shang)進(jin)行下載。

將安(an)裝(zhuang)包拷貝到E:盤(pan),雙擊程序即(ji)可在當(dang)前路(lu)徑進行安(an)裝(zhuang)。

3.2 配置(zhi)Eclipse

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

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

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

完成(cheng)了,然后(hou)運(yun)行。運(yun)行之前(qian)先編(bian)譯NDK,然后(hou)在(zai)編(bian)譯JAVA代(dai)碼。編(bian)譯也許(xu)會(hui)遇到Unable to launch cygpath. Is Cygwin on the path等(deng)問(wen)題?如(ru)何解決?如(ru)下:

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

在C/C++ Build中點(dian)擊Environment,點(dian)Add...添加環(huan)境(jing)變量NDKROOT,值(zhi)為NDK的(de)根目錄

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

之后,再次(ci)編譯運(yun)行工程,即可成(cheng)功。

第 1 章 源(yuan)碼編譯

1.1 導入源碼

打開Eclipse環境,選擇File->Import。

然(ran)后(hou),導入光盤資料中(zhong)的“BlueHelper”工程(cheng),勾選下(xia)圖中(zhong)的選項。

點擊finish完成工程的(de)導入

1.1 運行程序

注意(yi):如果在(zai)調(diao)試開(kai)發板(ban)的時候,出(chu)現ADB連接不上的問題(已(yi)知華清遠見(jian)FSPAD723開(kai)源平板(ban)),可以試著替換Android SDK的ADB工具(ju)(把(ba)光盤\Android應用開(kai)發環境\ADB\ADB1.0.26\下的4個文件拷(kao)貝到用戶ADT解(jie)壓(ya)目錄下的sdk\platform-tools中)

開(kai)(kai)發(fa)期間(jian),在實(shi)際的設(she)備上運行Android程(cheng)(cheng)序(xu)與在模擬器上運行該程(cheng)(cheng)序(xu)的效(xiao)果幾乎相同,需要(yao)做的就是用USB電(dian)纜連(lian)接手機與計算機,并安(an)裝一個(ge)對應的設(she)備驅動程(cheng)(cheng)序(xu)。如果模擬器窗口(kou)已打(da)開(kai)(kai),請將其關閉(bi)。只要(yao)將開(kai)(kai)發(fa)平臺(tai)通過USB下載(zai)線與計算機相連(lian),應用程(cheng)(cheng)序(xu)就會(hui)在開(kai)(kai)發(fa)平臺(tai)上加載(zai)并運行。

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

第 2 章 詳細設計

2.1 UartTool串口(kou)工具

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

NormalText Code

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

private static native int NativeFileClose();// 返回是(shi)否關閉(bi)成(cheng)功

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

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

串口(kou)初(chu)始化函(han)數,需要傳(chuan)遞想要打開的串口(kou)的文件名和波特(te)率(lv)。

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;

}

}

接下來要封裝(zhuang)讀函(han)數(shu)和(he)寫函(han)數(shu),利用的(de)是底層的(de)read和(he)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調(diao)試助手

本項目中,線(xian)程和(he)UI線(xian)程通(tong)信是通(tong)過Handler 機制實現的。作用是將數據傳(chuan)輸(shu)到UI線(xian)程進(jin)行顯示。

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;

}

}

};

設定(ding)按鈕(niu)(niu)的監(jian)聽(ting)時間,當點擊Open按鈕(niu)(niu)的時候(hou),按照設定(ding)的參數(shu)去打開對應的串口,成(cheng)功(gong)后啟動讀和寫的線程,同時設定(ding)按鈕(niu)(niu)文字為Close,屏幕進行提示打開成(cheng)功(gong)。

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, "打開成(cheng)功".toString(),

Toast.LENGTH_LONG).show();

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

open = true;

threadon = true;

readThread = new ReadThread();

readThread.start();

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

} else {

Toast.makeText(Uarthelper.this,

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

.show();

}

} else {

Toast.makeText(Uarthelper.this, "請填(tian)寫(xie)完(wan)整";.toString(),

Toast.LENGTH_SHORT).show();

}

} else {

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

Toast.LENGTH_LONG).show();

threadon = false;

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

UartQThread uartQThread = new UartQThread();

uartQThread.start();

open = false;

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

}

}

});

讀取數(shu)據(ju)的(de)線(xian)程,調用底(di)層的(de)uartRead函數(shu),接收到數(shu)據(ju)后,將(jiang)數(shu)據(ju)存入全局變量,然后通(tong)知主線(xian)程來顯示。

NormalText Code

class ReadThread extends Thread {

String tmp = null;

@Override

public void run() {

log.E("讀取數(shu)據線(xian)程啟動!");

while (threadon) {

tmp = uart.uartRead(10);

if (threadon) {

if (tmp == null) {

// log.E("接收數據出錯(cuo)!");

} else {

log.E("接收(shou)數據 " + tmp);

recdate += tmp;

NoteThread noteThread = new NoteThread();

noteThread.start();

}

}

}

log.E("讀取數據線程結束!");

}

}

如果想要發送數(shu)(shu)據,需(xu)要調用底層(ceng)的uartWrite函數(shu)(shu)。

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("發送數據(ju) " + date);

} else {

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

Toast.LENGTH_SHORT).show();

}

} else {

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

Toast.LENGTH_SHORT).show();

}

}

});

2.3 NDK程序詳解

2.3.1 jni.c

這個(ge)文件的作(zuo)用主要是連結上(shang)層和底層之間的函數(shu)。

首(shou)先需要(yao)定義一個(ge)結構體(ti),這(zhe)個(ge)結構體(ti)表明了上層函(han)數(shu)(shu)(shu)名(ming)(ming)(ming)稱和底層函(han)數(shu)(shu)(shu)名(ming)(ming)(ming)稱的對應關系。并且函(han)數(shu)(shu)(shu)名(ming)(ming)(ming)稱的書寫是(shi)有要(yao)求的,Java_cn_com_farsight_tool_UartTool_NativeFileRead類(lei)似這(zhe)樣的,格式(shi)為java+程序包(bao)名(ming)(ming)(ming)+函(han)數(shu)(shu)(shu)名(ming)(ming)(ming)稱。

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]));

然后在這些函(han)數(shu)(shu)中調用(yong)底層的函(han)數(shu)(shu)來實現對應(ying)的功能。

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

這個文(wen)件(jian)的(de)主要作用是完成加載底層的(de)庫文(wen)件(jian)的(de)時(shi)候的(de)工作。OnLoad函(han)數在(zai)加載庫文(wen)件(jian)的(de)時(shi)候會第一(yi)個執行。

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函數的(de)作用是(shi)將剛才的(de)關系結構(gou)體注冊進系統當中,同時,尋找(zhao)上層需要調用這些底(di)層函數的(de)類。

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

這個文(wen)(wen)件就(jiu)是底(di)層函數的(de)具體實現了。uart_get函數的(de)功能就(jiu)是打開串口(kou),根(gen)據上層傳遞過來(lai)的(de)參數和波特率(lv)來(lai)打開設備(bei)文(wen)(wen)件。

NormalText Code

int uart_get(char *filename, int rate) { //成功返回(hui)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;

}

當(dang)要(yao)讀(du)取數(shu)據的(de)(de)時候,先(xian)將上層傳遞下來的(de)(de)緩沖清空,使用read函數(shu)進行數(shu)據的(de)(de)讀(du)取,然后返(fan)回(hui)。

NormalText Code

int uart_read(unsigned char *buf, int size) { //返回(hui)讀取(qu)數據的個(ge)數

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;

}

直(zhi)接調用write來向設備(bei)寫入(ru)數據。

NormalText Code

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

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

if (result > 0) {

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

}

return result;

}

后程序(xu)結束的時候,關閉設備(bei)文(wen)件。

NormalText Code

int uart_close() {

close(fd);

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

return 0;

}

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

下一篇:fork函數的小誤區

熱(re)點文章推薦
華(hua)清學員就業榜單
高(gao)薪學員經驗分享
熱點新(xin)聞推薦
前臺(tai)專線:010-82525158 企業培(pei)訓洽談(tan)專線:010-82525379 院校合(he)作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部