Android之USB转串口通信
来源:互联网 发布:everest硬件检测软件 编辑:程序博客网 时间:2024/04/28 07:55
实验目的:
STM32通过USB转串口向Android Device持续发送数据,并让其显示在Android Device的Editview界面上
manifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.dai.usb_test"> <uses-feature android:name="android.hardware.usb.host"></uses-feature> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".UsbTestActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> </intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter" /> </activity> </application></manifest><strong></strong>
xml/usb_device_filter.xml:
<?xml version="1.0" encoding="utf-8"?><resources> <usb-device vendor-id="6790" product-id="29987" /></resources>
注:vendor-id和product-id都为十进制数值;
USB_Admin:
package com.example.dai.usb_test;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.hardware.usb.UsbDevice;import android.hardware.usb.UsbDeviceConnection;import android.hardware.usb.UsbEndpoint;import android.hardware.usb.UsbInterface;import android.hardware.usb.UsbManager;import android.util.Log;import android.widget.Toast;/** * Created by DAI on 2016/1/23. * Author:Will Smith * Email:15997135562@163.com * * Tip: *before developing USB on Android,you should configure manifests * accoriding to Android Developer */public class USB_Admin { private UsbManager usbManager; private UsbDevice usbDevice; private UsbInterface usbInterface; private UsbEndpoint usbEndpointIn; private UsbEndpoint usbEndpointOut; private UsbDeviceConnection usbDeviceConnection; private static int TIMEOUT = 5000; /*自己编写的USB管理类的构造函数*/ public USB_Admin(Context context){ usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); Log.v("USBManager:","" + usbManager); } /*****************************USB相关的操作**********************************/ /*获得USB的usbManager*/ public UsbManager get_UsbManager(){ return usbManager; } /*获得USB设备*/ public UsbDevice get_UsbDevice(Intent intent){ //这个USBDevice还有问题,暂时还得不到; /*使用意图过滤器的方法*/ if (intent != null) { Log.d("intent: ", "" + intent.toString()); if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) { //说明没有进入到这个if语句中 usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); //待查找; Log.v("USBDevice ","" + usbDevice); if (usbDevice != null) { Log.d("USB device attached: ", "" + usbDevice.getDeviceName()); } } } /*使用枚举的方法做一下*/ return usbDevice; } /*获得访问USB设备的权限*/ /*若没有在清单文件中配置USB的意图过滤器,那么就需要手动通过这一步去获取权限*/ /* public void getPermission(){ } */ /*获取USB设备的UsbInterface*/ /*和系统提供的函数名有冲突*/ public UsbInterface get_Interface(Context context){ usbInterface = usbDevice.getInterface(0); Log.v("USBInterface:", "" + usbInterface); if(usbInterface == null){ Toast.makeText(context,"can't get usbInterface",Toast.LENGTH_SHORT); return null; } return usbInterface; } /* 作用:获取USB设备UsbEndpoint 参数: 0:表示获取输入端点 1:表示获取输出端点 */ /*和系统提供的函数名有冲突*/ public UsbEndpoint get_Endpoint(int i,Context context){ //获取输入端点 if(i == 0){ if((usbEndpointIn = usbInterface.getEndpoint(0)) != null){ Log.v("USBEndpointIn:","" + usbEndpointIn); return usbEndpointIn; } Toast.makeText(context,"can't get usbEndpointIn",Toast.LENGTH_SHORT); }else if(i == 1){ //获取输出端点 if((usbEndpointOut = usbInterface.getEndpoint(1)) != null){ Log.v("USBEndpointOut:","" + usbEndpointOut); return usbEndpointOut; } Toast.makeText(context,"can't get usbEndpointOut",Toast.LENGTH_SHORT); } Toast.makeText(context,"can't get any usbEndpoint",Toast.LENGTH_SHORT); return null; } /*获得USB设备的UsbDeviceConnection*/ public UsbDeviceConnection get_usbDeviceConnection(Context context){ if(usbManager.hasPermission(usbDevice)){ usbDeviceConnection = usbManager.openDevice(usbDevice); Log.v("USBDeviceConnection:","" + usbDeviceConnection); return usbDeviceConnection; } Toast.makeText(context,"can't get usbDeviceConnection",Toast.LENGTH_SHORT); return null; } /*接收数据*/ public int receive_Message(byte[] receiveBytes){ int ret = -1; if(usbEndpointIn != null){ ret = usbDeviceConnection.bulkTransfer(usbEndpointIn, receiveBytes, receiveBytes.length, TIMEOUT); }else { Log.v("receiveBytes: ", "failed"); } return ret; } /*发送数据*/ public int send_Message(byte[] sendBytes){ int ret = -1; if(usbEndpointOut != null){ ret = usbDeviceConnection.bulkTransfer(usbEndpointOut, sendBytes, sendBytes.length, TIMEOUT); }else { Log.v("Send: ","failed"); } return ret; } /*断开已连接的USB设备*/ public void disconnect_USB(Context context){ BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) { UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (device != null) { usbDeviceConnection.releaseInterface(get_Interface(context)); usbDeviceConnection.close(); } } } }; } /*获得设备的product-id和vendor-id*/ public int get_ProductId(){ return usbDevice.getProductId(); } /*获得设备的vendor-id*/ public int get_VendorId(){ return usbDevice.getVendorId(); } /*获得设备的getSerialNumber*/ /* public String get_SerialNumber(){ return null; } */}
UsbTestActivity:
package com.example.dai.usb_test;import android.content.Intent;import android.hardware.usb.UsbDevice;import android.hardware.usb.UsbDeviceConnection;import android.hardware.usb.UsbEndpoint;import android.hardware.usb.UsbInterface;import android.hardware.usb.UsbManager;import android.os.Bundle;import android.os.Message;import android.support.design.widget.FloatingActionButton;import android.support.design.widget.Snackbar;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.Toolbar;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.EditText;import java.io.UnsupportedEncodingException;/*Purpose:** test USB on Android by receiving data from stm32 board,* then display on X4418 board** */public class UsbTestActivity extends AppCompatActivity { private USB_Admin usb_admin; private UsbManager usbManager; private UsbDevice usbDevice; private UsbInterface usbInterface; private UsbDeviceConnection usbDeviceConnection; private UsbEndpoint usbEndpointIn; private UsbEndpoint usbEndpointOut; protected final Object mReadBufferLock = new Object(); protected final Object mWriteBufferLock = new Object(); byte[] receiveBytes = new byte[32]; byte[] sendBytes = new byte[32]; private StringBuffer stringBuffer = new StringBuffer(); EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_usb_test); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); editText = (EditText)findViewById(R.id.editText); usb_Init(); usb_receiveData(); usb_sendData(); } public void usb_Init(){ Intent intent = getIntent(); usb_admin = new USB_Admin(this); Log.v("usb_admin: ", "" + usb_admin); usbManager = usb_admin.get_UsbManager(); Log.v("usbManager: ","" + usbManager); usbDevice = usb_admin.get_UsbDevice(intent); Log.v("usbDevice: ", "" + usbDevice); Log.v("interfaceCount: ",""+usbDevice.getInterfaceCount()); usbInterface = usb_admin.get_Interface(this); Log.v("usbInterface: ", "" + usbInterface); //1个; Log.v("usbEndpointCount: ", "" + usbInterface.getEndpointCount()); usbEndpointIn = usb_admin.get_Endpoint(0, this); Log.v("usbEndpointIn: ", "" + usbEndpointIn); Log.v("usbEndpointDirection: ", "" + usbEndpointIn.getDirection()); usbEndpointOut = usb_admin.get_Endpoint(1, this); Log.v("usbEndpointOut: ", "" + usbEndpointOut); Log.v("usbEndpointDirection: ", "" + usbEndpointOut.getDirection()); usbDeviceConnection = usb_admin.get_usbDeviceConnection(this); Log.v("usbDeviceConnection: ", "" + usbDeviceConnection); configUsb340(115200); } public void usb_receiveData(){ ReceiveThread receiveThread = new ReceiveThread(); Thread thread = new Thread(receiveThread); thread.start(); } public void usb_sendData(){ SendThread sendThread = new SendThread(); Thread send = new Thread(sendThread); send.start(); } class ReceiveThread implements Runnable{ @Override public void run() { synchronized(mReadBufferLock){ while (!Thread.currentThread().isInterrupted()){ if(usbDeviceConnection.claimInterface(usbInterface, true)){ if((usb_admin.receive_Message(receiveBytes)) >= 0){ /* for(int i=0;i<receiveBytes.length;i++){ Log.v("Data: ",""+receiveBytes[i]); //为什么这里得到的数据大部分都为0呢? } */ Log.v("length: ",""+usb_admin.receive_Message(receiveBytes)); String string = null; Log.v("receiveBytes: ","" + receiveBytes.toString()); Log.v("receiveBytes: ","is OK "); try { string = new String(receiveBytes,"UTF-8"); stringBuffer.append(string); Log.v("3D DATA", string); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } Message message = handler.obtainMessage(); message.obj = stringBuffer; message.what = 1; handler.sendMessage(message); }else { Log.v("Receive Data: ","failed"); } }else { Log.v("claimInterface: ","failed"); } try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } class SendThread implements Runnable{ @Override public void run() { synchronized(mWriteBufferLock){ while (!Thread.currentThread().isInterrupted()){ if(usbDeviceConnection.claimInterface(usbInterface, true)){ String string = " Android USB Test "; sendBytes = string.getBytes(); if((usb_admin.send_Message(sendBytes)) >= 0){ Log.v("sendBytes: ","is OK "); }else { Log.v("Send Data: ","failed"); } }else { Log.v("claimInterface: ","failed"); } try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } private android.os.Handler handler = new android.os.Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case 1: editText.setText((StringBuffer)msg.obj); break; default: break; } } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_usb_test, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } private boolean configUsb340(int paramInt) { byte[] arrayOfByte = new byte[8]; usbDeviceConnection.controlTransfer(192, 95, 0, 0, arrayOfByte, 8, 1000); usbDeviceConnection.controlTransfer(64, 161, 0, 0, null, 0, 1000); long l1 = 1532620800 / paramInt; for (int i = 3; ; i--) { if ((l1 <= 65520L) || (i <= 0)) { long l2 = 65536L - l1; int j = (short)(int)(0xFF00 & l2 | i); int k = (short)(int)(0xFF & l2); usbDeviceConnection.controlTransfer(64, 154, 4882, j, null, 0, 1000); usbDeviceConnection.controlTransfer(64, 154, 3884, k, null, 0, 1000); usbDeviceConnection.controlTransfer(192, 149, 9496, 0, arrayOfByte, 8, 1000); usbDeviceConnection.controlTransfer(64, 154, 1304, 80, null, 0, 1000); usbDeviceConnection.controlTransfer(64, 161, 20511, 55562, null, 0, 1000); usbDeviceConnection.controlTransfer(64, 154, 4882, j, null, 0, 1000); usbDeviceConnection.controlTransfer(64, 154, 3884, k, null, 0, 1000); usbDeviceConnection.controlTransfer(64, 164, 0, 0, null, 0, 1000); return true; } l1 >>= 3; } }}
从STM32发送数据那段的程序如下:
#include "sys.h"#include "delay.h"#include "uart.h"#include "led.h"int main(void){int i = 0;char res[10] = {'0','1','2','3','4','5','6','7','8','9'}; //ASCII:49-57Stm32_Clock_Init(336,8,2,7);//ʨ׃ʱד,168Mhz delay_init(168);USART_Init();while(1){for(i=0;i<10;i++){USART1->DR = res[i];while(((USART1->SR)&(0x80)) != 0x80); }delay_ms(3000);}}
注:针对不同的USB转串口芯片,USB部分的配置代码不一样;本程序只针对CH340芯片可用;
具体的USB转串口程序可参考Github上的开源项目https://github.com/ksksue/PhysicaloidLibrary
或者 https://github.com/mik3y/usb-serial-for-android
2 0
- Android之USB转串口通信
- android usb转串及串口通信
- 11.3 USB转串口通信
- Android USB转串口通信开发基本流程
- 详解Android USB转串口通信开发基本流程
- Android 外接USB转串口设备开发笔记(Android与单片机通过usb转串口通信)
- USB转串口通信实践总结
- Android USB转串口编程
- Android USB转串口编程
- Android 之 USB Host 串口编程
- android盒子的usb和串口之间的通信
- 【android之USB通信】android之USB数据传输
- Android实战技巧之四十九:Usb通信之USB Host
- Android实战技巧之四十九:Usb通信之USB Host
- linux下USB转串口与minicom通信
- NDK USB-HID 转串口通信参数设置代码
- (学习笔记1)stm32f4USART中USB转串口通信
- USB转串口之minicom的设置
- 召回率Recall、精确度Precision、准确率Accuracy、F值
- 无法将notepad++添加到打开方式列表中的解决办法
- SAS Email - Windows Platform
- Android开发深化之关于自定义GridView控件的实现
- UVA 1614(p254)----Hell on the Markets
- Android之USB转串口通信
- java容器学习之——Set
- 一种新型的游戏服务器架构CDDE
- 简单的web编辑器
- 适配器模式
- OpenGL ES 三种类型修饰 uniform attribute varying
- UVA 1619(p256)----Feel Good
- bzoj1864 三色二叉树 树形dp
- Android学习资源网站大全