日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android USB转串口通信开发基本流程

發(fā)布時(shí)間:2023/12/15 Android 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android USB转串口通信开发基本流程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

好久沒(méi)有寫(xiě)文章了,年前公司新開(kāi)了一個(gè)項(xiàng)目,是和usb轉(zhuǎn)串口通信相關(guān)的,需求是用安卓平板通過(guò)usb轉(zhuǎn)接后與好幾個(gè)外設(shè)進(jìn)行通信。一直忙到近期,才慢慢閑下來(lái),趁著這個(gè)周末不忙。記錄下usb轉(zhuǎn)串口通信開(kāi)發(fā)的基本流程。

我們開(kāi)發(fā)使用的是usb主機(jī)模式,即:安卓平板作為主機(jī),usb外設(shè)作為從機(jī)進(jìn)行數(shù)據(jù)通信。

整個(gè)開(kāi)發(fā)流程能夠總結(jié)為下面幾點(diǎn):

1.發(fā)現(xiàn)設(shè)備

UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); Map<String, UsbDevice> usbList = usbManager.getDeviceList();

通過(guò)UsbManager這個(gè)系統(tǒng)提供的類(lèi)。我們能夠枚舉出當(dāng)前連接的全部usb設(shè)備,我們主要須要的是UsbDevice對(duì)象。關(guān)于UsbDevice這個(gè)類(lèi),官方是這樣凝視的:

This class represents a USB device attached to the android device with the android deviceacting as the USB host.

是的,這個(gè)類(lèi)就代表了android所連接的usb設(shè)備。

2.打開(kāi)設(shè)備

接下來(lái)。我們須要打開(kāi)剛剛搜索到的usb設(shè)備,我們能夠?qū)⑵桨迮cusb外設(shè)之間的連接想象成一個(gè)通道,僅僅有把通道的門(mén)打開(kāi)后。兩邊才干進(jìn)行通信。

一般來(lái)說(shuō)。在沒(méi)有定制的android設(shè)備上首次訪(fǎng)問(wèn)usb設(shè)備的時(shí)候,默認(rèn)我們是沒(méi)有訪(fǎng)問(wèn)權(quán)限的。因此我們首先要推斷對(duì)當(dāng)前要打開(kāi)的usbDevice是否有訪(fǎng)問(wèn)權(quán)限:

if (!usbManager.hasPermission(usbDevice)) {usbPermissionReceiver = new UsbPermissionReceiver();//申請(qǐng)權(quán)限Intent intent = new Intent(ACTION_DEVICE_PERMISSION);PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, intent, 0);IntentFilter permissionFilter = new IntentFilter(ACTION_DEVICE_PERMISSION);context.registerReceiver(usbPermissionReceiver, permissionFilter);usbManager.requestPermission(usbDevice, mPermissionIntent);}

這里我們聲明一個(gè)廣播UsbPermissionReceiver。當(dāng)接受到授權(quán)成功的廣播后做一些其它處理:

private class UsbPermissionReceiver extends BroadcastReceiver {public void onReceive(Context context, Intent intent) {String action = intent.getAction();if (ACTION_DEVICE_PERMISSION.equals(action)) {synchronized (this) {UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (device.getDeviceName().equals(usbDevice.getDeviceName()) {if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {//授權(quán)成功,在這里進(jìn)行打開(kāi)設(shè)備操作} else {//授權(quán)失敗}}}}}}

接下來(lái),我們要找到具有傳輸數(shù)據(jù)功能的接口UsbInterface。從它里邊兒找到數(shù)據(jù)輸入和輸出portUsbEndpoint。普通情況下,一個(gè)usbDevice有多個(gè)UsbInterface。我們須要的通常是第一個(gè),所以:

usbInterface=usbDevice.getInterface(0);

相同的,一個(gè)usbInterface有多個(gè)UsbEndpoint,有控制port和數(shù)據(jù)port等。因此我們須要依據(jù)類(lèi)型和數(shù)據(jù)流向來(lái)找到我們須要的數(shù)據(jù)輸入和輸出兩個(gè)port:

for (int index = 0; index < usbInterface.getEndpointCount(); index++) {UsbEndpoint point = usbInterface.getEndpoint(index);if (point.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {if (point.getDirection() == UsbConstants.USB_DIR_IN) {usbEndpointIn = point;} else if (point.getDirection() == UsbConstants.USB_DIR_OUT) {usbEndpointOut = point;}}}

最后。才是真正的打開(kāi)usb設(shè)備。我們須要和usb外設(shè)建立一個(gè)UsbDeviceConnection,它的凝視非常easy介紹的說(shuō)明了它的用途:

This class is used for sending and receiving data and control messages to a USB device.

它的獲取也非常easy。就一句代碼:

usbDeviceConnection = usbManager.openDevice(usbDevice);

到這里,理論上平板和usb外設(shè)之間的連接已經(jīng)建立了,也能夠首發(fā)數(shù)據(jù)了,可是,我們大部分情況下還須要對(duì)usb串口進(jìn)行一些配置,比方波特率,停止位,數(shù)據(jù)控制等。不然兩邊配置不同,收到的數(shù)據(jù)會(huì)亂碼。詳細(xì)怎么配置。就看你使用的串口芯片是什么了,眼下流行的有pl2303,ch340等,因?yàn)槠鶈?wèn)題。須要詳細(xì)配置串口代碼的朋友請(qǐng)自行查閱。

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

到這里,我們已經(jīng)能夠與usb外設(shè)進(jìn)行傳輸數(shù)據(jù)了,首先來(lái)看怎么向usb設(shè)備發(fā)送數(shù)據(jù)。

1.向usb外設(shè)發(fā)送數(shù)據(jù)

在第二步中,我們已經(jīng)獲取了數(shù)據(jù)的輸出portusbEndpointIn。我們向外設(shè)發(fā)送數(shù)據(jù)就是通過(guò)這個(gè)port來(lái)實(shí)現(xiàn)的。來(lái)看怎么用:

int ret = usbDeviceConnection.bulkTransfer(usbEndpointOut, data, data.length, DEFAULT_TIMEOUT);

bulkTransfer這個(gè)函數(shù)用于在給定的port進(jìn)行傳輸數(shù)據(jù),第一個(gè)參數(shù)就是此次傳輸?shù)膒ort,這里我們用的輸出port。第二個(gè)參數(shù)是要發(fā)送的數(shù)據(jù),類(lèi)型為字節(jié)數(shù)組,第三個(gè)參數(shù)代表要發(fā)送的數(shù)據(jù)長(zhǎng)度,最后一個(gè)參數(shù)是超時(shí)。返回值代表發(fā)送成功的字節(jié)數(shù),假設(shè)返回-1,那就是發(fā)送失敗了。

2.接受usb外設(shè)發(fā)送來(lái)的數(shù)據(jù)

同理,我們已經(jīng)找到了數(shù)據(jù)輸入portusbEndpointIn,由于數(shù)據(jù)的輸入是不定時(shí)的。因此我們能夠另開(kāi)一個(gè)線(xiàn)程,來(lái)專(zhuān)門(mén)接受數(shù)據(jù),接受數(shù)據(jù)的代碼例如以下:

int inMax = inEndpoint.getMaxPacketSize(); ByteBuffer byteBuffer = ByteBuffer.allocate(inMax); UsbRequest usbRequest = new UsbRequest(); usbRequest.initialize(connection, inEndpoint); usbRequest.queue(byteBuffer, inMax); if(connection.requestWait() == usbRequest){ byte[] retData = byteBuffer.array(); for(Byte byte1 : retData){ System.err.println(byte1); } }

以上。就是usb轉(zhuǎn)串口通信的基本流程。有些地方寫(xiě)的不是非常全面,比方接收usb外設(shè)數(shù)據(jù)的方法應(yīng)該還有別的。不足之處歡迎指正。

轉(zhuǎn)載于:https://www.cnblogs.com/yutingliuyl/p/7287114.html

總結(jié)

以上是生活随笔為你收集整理的Android USB转串口通信开发基本流程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。