实验目的:
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-57
- Stm32_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