Android 串口通信(二)


前言

上一篇中主要介紹了串口基礎內容和基於谷歌官方android-serialport-api庫 對Android設備進行的串口操作,這篇文章主要介紹基於Usb轉串口驅動庫usb-serial-for-android 的相關內容及操作,同時對Usb串口設備進行插拔監聽等相關操作。

Usb轉串口開發

USB轉串口即實現USB接口到通用串口之間的轉換,為沒有串口的設備提供快速的通道,而且,使用USB轉串口設備等於將傳統的串口設備變成了即插即用的USB設備。作為應用最廣泛的USB接口,支持熱插撥,即插即用,傳輸速度快。實際使用中我們能用到USB TO TTL 或者 USB TO RS485 等轉換線,通過轉換后,即可進行串口開發,即通過I/O流讀取,寫入文件數據。

Usb轉串口驅動庫usb-serial-for-android這個庫支持 USB 到串行轉換芯片:

  • FTDI FT232R, FT232H, FT2232H, FT4232H, FT230X, FT231X, FT234XD 232r,FT232H,FT232H,FT4232H,FT230X,FT231X,FT234XD
  • Prolific PL2303 多產的 PL2303
  • Silabs CP2102, CP2105, ... Silabs CP2102,CP2105,..
  • Qinheng CH340, CH341A 秦衡 CH340,CH341A

和實現 CDC/ACM 協議的設備,如

  • Arduino using ATmega32U4 使用 ATmega32U4
  • Digispark using V-USB software USB 使用 V-USB 軟件的數字公園
  • BBC micro:bit using ARM mbed DAPLink firmware 微處理器: 位使用 ARM 處理 DAPLink 固件

開發流程

  1. 獲取USB轉串口設備串口;
  2. 配置(波特率,校驗位等),建立指定串口通信;
  3. 串口寫入及接收返回的數據;
  4. 結束通信,串口關閉。

使用過程

  1. 注冊USB設備監聽及權限獲取相關內容:

    public class UsbBroadcastReceiver extends BroadcastReceiver {
    
        public static final String ACTION_USB_PERMISSION = "android.intent.USB_PERMISSION";
    
        private OnUsbDeviceStateChangeListener mOnUsbDeviceStateChangeListener;
    
        public void registerReceiver(Context context, OnUsbDeviceStateChangeListener onUsbDeviceStateChangeListener) {
            IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
            filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
            filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
            context.registerReceiver(this, filter);
            this.mOnUsbDeviceStateChangeListener = onUsbDeviceStateChangeListener;
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            UsbDevice mUsbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            int usbState = -1;
            //Usb串口權限
            if (ACTION_USB_PERMISSION.equals(action)) {
                usbState = 0;
            }
            // Usb設備連接
            else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
                usbState = 1;
            }
            // Usb設備斷開
            else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                usbState = 2;
            }
            if (mOnUsbDeviceStateChangeListener != null) {
                mOnUsbDeviceStateChangeListener.onUsbDeviceStateChange(usbState, mUsbDevice);
            }
        }
    
        public interface OnUsbDeviceStateChangeListener {
            /**
             * Usb權限獲取
             */
            int ACTION_PERMISSION_GAINED = 0;
            /**
             * Usb設備連接
             */
            int ACTION_DEVICE_ATTACHED = 1;
            /**
             * Usb設備斷開
             */
            int ACTION_DEVICE_DETACHED = 2;
    
            void onUsbDeviceStateChange(int usbDeviceState, UsbDevice usbDevice);
        }
    }
    
  2. 獲取Usb轉串口設備:

    public List<UsbSerialPort> getAllSerialPort() {
        List<UsbSerialDriver> drivers = UsbSerialProber.getDefaultProber().findAllDrivers(mUsbManager);
        List<UsbSerialPort> result = new ArrayList<>();
        for (UsbSerialDriver driver : drivers) {
            List<UsbSerialPort> ports = driver.getPorts();
            result.addAll(ports);
        }
        return result;
    }
    
  3. 建立串口通信:

    public void openSerialPort(UsbSerialPort usbSerialPort, UsbSerialPortParameters usbSerialPortParameters) {
        if (usbSerialPort == null || usbSerialPortParameters == null) {
            return;
        }
        UsbDeviceConnection connection = mUsbManager.openDevice(usbSerialPort.getDriver().getDevice());
        this.mUsbSerialPort = usbSerialPort;
        this.mUsbSerialPortParameters = usbSerialPortParameters;
        if (connection != null) {
            try {
                usbSerialPort.open(connection);
                usbSerialPort.setParameters(usbSerialPortParameters.getBaudRate(), usbSerialPortParameters.getDataBits(), usbSerialPortParameters.getStopBits(), usbSerialPortParameters.getParity());
                mSerialInputOutputManager = new SerialInputOutputManager(usbSerialPort, this);
                ExecutorService mExecutor = Executors.newSingleThreadExecutor();
                mExecutor.submit(mSerialInputOutputManager);
            } catch (IOException e) {
                if (mOnUsbSerialListener != null) {
                    mOnUsbSerialListener.onSerialOpenException(e);
                }
            }
            isOpened = true;
            if (mOnUsbSerialListener != null) {
                mOnUsbSerialListener.onSerialOpenSuccess();
            }
        } else {
            mUsbManager.requestPermission(usbSerialPort.getDriver().getDevice(), mPermissionIntent);
        }
    }
    
  4. 建立串口通信后,利用SerialInputOutputManager進行串口發送及數據返回接收:

    public boolean sendSerialPort(byte[] commandBytes) {
        if (mUsbSerialPort != null && isOpened && commandBytes.length > 0) {
            try {
                mUsbSerialPort.write(commandBytes, PORT_WRITE_TIME_OUT_MILLIS);
            } catch (IOException e) {
                return false;
            }
            return true;
        }
        return false;
    }
    
    public void onNewData(byte[] data) {
        if (mOnUsbSerialListener != null) {
            mOnUsbSerialListener.onReceivedData(data);
        }
    }
    
  5. 串口關閉:

    public void closeSerialPort() {
        try {
            if (mUsbSerialPort != null) {
                mUsbSerialPort.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        isOpened = false;
        if (mSerialInputOutputManager != null) {
            mSerialInputOutputManager.stop();
            mSerialInputOutputManager = null;
        }
    }
    

整個Usb轉串口通信基本操作就是這樣,主要還是對輸入、輸出流的讀寫,具體內容可以查看Usb轉串口驅動庫usb-serial-for-android庫中的詳細內容。

訪問Github項目查看例子具體代碼實現:

https://github.com/MickJson/AndroidUSBSerialPort

如果使用Kotlin進行開發,可以查看這個串口調試工具:https://github.com/HelloHuDi/usbSerialPortTools ,關於串口開發UI很多都參考自此,且使用起來調試還是十分方便的。

參考資料:

Usb轉串口通信庫:https://github.com/mik3y/usb-serial-for-android

歡迎點贊/評論,你們的贊同和鼓勵是我寫作的最大動力!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM