天天看點

RS232序列槽通信 基于ZE613_Android序列槽轉接裝置

在網上看到了很多RS232序列槽操作的講解,發現基本都是root了,但是在實際開發應用中,這個還有有很多限制的,下面是在非root的情況下,使用基于ZE_613裝置RS232序列槽通信的一些使用情況。

(一)RS232标準接口 (這裡是借鑒的https://www.cnblogs.com/leestar54/p/6604636.html#wiz_toc_1)

也就是PC電腦上所說的COM口,RS232是負邏輯電平,它定義+5+12V為低電平,而-12-5V為高電平。

RS232序列槽通信 基于ZE613_Android序列槽轉接裝置

正常情況下,PC台式主機機箱都會有一個RS232的通訊接口(别和VGI的口搞錯啦!),而目前筆記本幾乎不會帶有了,是以都是用USB轉接口。

UART

及Universal Asynchronous Receiver Transmitter:通用異步收發器,通常ARM嵌入式闆子都會內建此接口

RS232序列槽通信 基于ZE613_Android序列槽轉接裝置

UART有4個pin(VCC, GND, RX, TX), 用的TTL電平, 低電平為0(0V),高電平為1(3.3V或以上)。

RS232序列槽通信 基于ZE613_Android序列槽轉接裝置

RS232與UART轉接

通常嵌入式裡所說的序列槽,是指UART口,但硬體衆多,大多數都是基于RS232和UART,有時候這兩種口之間需要通訊,最主要不同的其實也就是電平不一樣,是以需要轉接口,某寶上MAX3232種類繁多。

(二)RS232 Android開發

這裡是源代碼位址:https://github.com/LeeVanie/USB232Demo

1、添權重限

<uses-feature android:name="android.hardware.usb.host" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
           

如果是7.0以上的手機,對于讀寫權限需要自己處理,網上很多,這裡就不介紹了

2、在需要使用RS232序列槽的界面添加下面代碼

<activity android:name=".MainActivity"
            android:launchMode="singleTask">

            <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/device_filter" />
        </activity>
           

3、在res下建立device_filter.xml檔案

<?xml version="1.0" encoding="utf-8"?>

RS232序列槽通信 基于ZE613_Android序列槽轉接裝置
<resources>
	<usb-device vendor-id="1118" product-id="688"></usb-device>  
	<usb-device vendor-id="1027" product-id="24577" /> <!-- FT232RL -->
	<usb-device vendor-id="1027" product-id="24596" /> <!-- FT232H -->
	<usb-device vendor-id="1027" product-id="24592" /> <!-- FT2232C/D/HL -->
	<usb-device vendor-id="1027" product-id="24593" /> <!-- FT4232HL -->
	<usb-device vendor-id="1027" product-id="24597" /> <!-- FT230X -->
	<usb-device vendor-id="1412" product-id="45088" /> <!-- REX-USB60F -->
</resources>
           

3、在libs中導入包d2xx.jar,因為這裡是用的是Z-TEK廠家的

(ps----我也怕廠家追究我盜用他們的版權)

首先對包進行初始化:

try {
            ftD2xx = D2xxManager.getInstance(this);
        } catch (D2xxManager.D2xxException ex) {
            ex.printStackTrace();
        }
           

然後設定vid、pid

if(!ftD2xx.setVIDPID(0x0403, 0x6001))
            Log.i("ftd2xx-java","setVIDPID Error");        
           

開啟廣播

IntentFilter filter = new IntentFilter();
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        filter.setPriority(500);
        this.registerReceiver(mUsbReceiver, filter);
           

檢測裝置

int tempDevCount = ftD2xx.createDeviceInfoList(this);

        if (tempDevCount > 0) {
            if( DevCount != tempDevCount ) {
                DevCount = tempDevCount;
            }
        } else {
            DevCount = -1;
            currentIndex = -1;
        }
           

連接配接裝置

int tmpProtNumber = openIndex + 1;

        if( currentIndex != openIndex ) {
            if(null == ftDev) {
                try {
                    ftDev = ftD2xx.openByIndex(this, openIndex);
                } catch (Exception e){
                    ftDev = null;
                }
            } else {
                synchronized(ftDev) {
                    ftDev = ftD2xx.openByIndex(this, openIndex);
                }
            }
            uart_configured = false;
        } else {
            Toast.makeText(this,"Device port " + tmpProtNumber + " is already opened",Toast.LENGTH_LONG).show();
            return;
        }

        if(ftDev == null) {
            Toast.makeText(this,"open device port("+tmpProtNumber+") NG, ftDev == null", Toast.LENGTH_LONG).show();
            return;
        }

        if (true == ftDev.isOpen()) {
            currentIndex = openIndex;
            Toast.makeText(this, "open device port(" + tmpProtNumber + ") OK", Toast.LENGTH_SHORT).show();

            if(false == bReadThreadGoing) {
                read_thread = new readThread(handler);
                read_thread.start();
                bReadThreadGoing = true;
            }
        } else {
            FT_EEPROM ft_Data = null;
            if(ftD2xx.createDeviceInfoList(this) <= 0)
                return;
            ftDev = ftD2xx.openByIndex(this, 0);
            ft_Data = ftDev.eepromRead();
            if (ft_Data == null) {
                Toast.makeText(this, "Not supported device",
                        Toast.LENGTH_SHORT).show();
            } else {
                final FT_EEPROM finalFt_Data = ft_Data;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        ((TextView)findViewById(R.id.vid)).setText(Integer.toHexString(finalFt_Data.VendorId));
                        ((TextView)findViewById(R.id.pid)).setText(Integer.toHexString(finalFt_Data.ProductId));
                    }
                });

            }
            int iVid = Integer.parseInt(Integer.toHexString(ft_Data.VendorId),16);
            int iPid = Integer.parseInt(Integer.toHexString(ft_Data.ProductId),16);
            ftD2xx.setVIDPID(iVid,iPid);

            Toast.makeText(this, "open device port(" + tmpProtNumber + ") NG", Toast.LENGTH_LONG).show();
            //Toast.makeText(this, "Need to get permission!", Toast.LENGTH_SHORT).show();			
        }
           

設定連接配接參數

if (ftDev == null){
            return;
        }
        if (ftDev.isOpen() == false) {
            Log.e("j2xx", "SetConfig: device not open");
            return;
        }

        // configure our port
        // reset to UART mode for 232 devices
        ftDev.setBitMode((byte) 0, D2xxManager.FT_BITMODE_RESET);

        ftDev.setBaudRate(baud);

        switch (dataBits) {
            case 7:
                dataBits = D2xxManager.FT_DATA_BITS_7;
                break;
            case 8:
                dataBits = D2xxManager.FT_DATA_BITS_8;
                break;
            default:
                dataBits = D2xxManager.FT_DATA_BITS_8;
                break;
        }

        switch (stopBits) {
            case 1:
                stopBits = D2xxManager.FT_STOP_BITS_1;
                break;
            case 2:
                stopBits = D2xxManager.FT_STOP_BITS_2;
                break;
            default:
                stopBits = D2xxManager.FT_STOP_BITS_1;
                break;
        }

        switch (parity) {
            case 0:
                parity = D2xxManager.FT_PARITY_NONE;
                break;
            case 1:
                parity = D2xxManager.FT_PARITY_ODD;
                break;
            case 2:
                parity = D2xxManager.FT_PARITY_EVEN;
                break;
            case 3:
                parity = D2xxManager.FT_PARITY_MARK;
                break;
            case 4:
                parity = D2xxManager.FT_PARITY_SPACE;
                break;
            default:
                parity = D2xxManager.FT_PARITY_NONE;
                break;
        }

        ftDev.setDataCharacteristics(dataBits, stopBits, parity);

        short flowCtrlSetting;
        switch (flowControl) {
            case 0:
                flowCtrlSetting = D2xxManager.FT_FLOW_NONE;
                break;
            case 1:
                flowCtrlSetting = D2xxManager.FT_FLOW_RTS_CTS;
                break;
            case 2:
                flowCtrlSetting = D2xxManager.FT_FLOW_DTR_DSR;
                break;
            case 3:
                flowCtrlSetting = D2xxManager.FT_FLOW_XON_XOFF;
                break;
            default:
                flowCtrlSetting = D2xxManager.FT_FLOW_NONE;
                break;
        }
        // TODO : flow ctrl: XOFF/XOM
        // TODO : flow ctrl: XOFF/XOM
        ftDev.setFlowControl(flowCtrlSetting, (byte) 0x0b, (byte) 0x0d);

        uart_configured = true;
        Toast.makeText(this, "Config done", Toast.LENGTH_SHORT).show();
           

開啟線程,接收資料

private class readThread  extends Thread {
        Handler mHandler;

        readThread(Handler h){
            mHandler = h;
            this.setPriority(Thread.MIN_PRIORITY);
        }

        @Override
        public void run() {
            int i;

            while(true == bReadThreadGoing) {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {

                }

                synchronized(ftDev) {
                    iavailable = ftDev.getQueueStatus();
                    if (iavailable > 0) {

                        if(iavailable > readLength){
                            iavailable = readLength;
                        }

                        ftDev.read(readData, iavailable);
                        reciveData = "";
                        for (i = 0; i < iavailable; i++) {
                            readDataToText[i] = (char) readData[i];
                            reciveData += HexUtils.bytesToHexString(readData) + " ";
//                            LogUtil.open().appendMethodB(
//                                    "{rs232:---readDataToText---" + HexUtils.bytesToHexString(readData) +
//                                            "},");
                        }
                        Message msg = mHandler.obtainMessage();
                        mHandler.sendMessage(msg);
                    }
                }
            }
        }

    }

    final Handler handler =  new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if(iavailable > 0) {
                accept.append(String.copyValueOf(readDataToText, 0, iavailable));
                accept.setText(reciveData);
                LogUtil.open().appendMethodB(
                        "{rs232:---reciveData---" + accept.getText().toString().trim() +
                                "},");

            }
        }
    };
           

發送資料

if (ftDev.isOpen() == false) {
            Log.e("j2xx", "SendMessage: device not open");
            return;
        }
        ftDev.setLatencyTimer((byte) 16);
//		ftDev.purge((byte) (D2xxManager.FT_PURGE_TX | D2xxManager.FT_PURGE_RX));
        String writeData = editText.getText().toString();
        byte[] OutData = writeData.getBytes();
        ftDev.write(OutData, writeData.length());
           

監聽裝置連接配接是否斷開

/***********USB broadcast receiver*******************************************/
    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            String TAG = "FragL";
            String action = intent.getAction();
            if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                Log.i(TAG,"DETACHED...");
                LogUtil.open().appendMethodB("{rs232:---DETACHED---},");
                disconnectFunction();

            }
        }
    };
           

就隻有這麼多,如果有需要的可以聯系

這裡是源代碼位址:https://github.com/LeeVanie/USB232Demo