天天看点

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