[TOC]
基本了解
PL2303 是Prolific 公司生产的一种高度集成的RS232-USB接口转换器,可提供一个RS232 全双工异步串行通信装置与USB 功能接口便利连接的解决方案。
类简介
- PL2303MultiLib:主类,里面包括连接设备、数据传输等很多操作方法。
- PL2303MultiLib.BaudRate:波特率(枚举类)
- PL2303MultiLib.DataBits:数据位(枚举类)
- PL2303MultiLib.FlowControl:流量控制(枚举类)
- PL2303MultiLib.Parity:(枚举类)
- PL2303MultiLib.StopBits:停止位(枚举类)
构造函数
/*Initialize a PL2303HXD driver, the software 4K Queue buffer is enable.内部调用下面的构造方法,默认第四个参数bWithQueue为true。第三个参数sAppName为芯片内部一个广播接收器的过滤器的ACTION,应该随便一个字符串就行(官方给出的案例用的是
private static final String ACTION_USB_PERMISSION = "com.prolific.pluartmultisimpletest.USB_PERMISSION";)
*/
public PL2303MultiLib(UsbManager manager, Context context, java.lang.String sAppName);
//Initialize a PL2303HXD driver
public PL2303MultiLib(UsbManager manager, Context context, java.lang.String sAppName, boolean bWithQueue)
常用参数和方法
//PL2303芯片发送广播通知的IntentFilter.Action
public String PLUART_MESSAGE = "tw.PL2303MultiUSBMessage";
//检测到Usb设备拔出时,发送的广播所携带的extra数据,为String格式的device index。
public String PLUART_DETACHED = "MultiUSB.Detached";
//返回PL2303HXD device数量,默认的VID_PID为067B_2303。同时会进行一些初始化工作,例如注册广播等。
int PL2303Enumerate();
//通过device index获取该PL2303HXD的连接状态,如果连接成功返回true,否则返回false。
boolean PL2303IsDeviceConnectedByIndex(int index);
//通过URAT设置打开一个PL-UART USB device,成功打开则返回true。第一个参数为设备的index,后面四个为相应的枚举参数
boolean PL2303OpenDevByUARTSetting(int index, BaudRate R, DataBits D, StopBits S, Parity P, FlowControl F) ;
//写入字节数据到PL-UART芯片集。返回写入数据的长度。
int PL2303Write(int index,byte[] buf);
//从PL-UART芯片读取数据。返回读取数据的长度。读取到的数据会存在buf字节数组中。
int PL2303Read(int index,byte[] buf);
//关闭一个PL-UART芯片集
void PL2303Release();
配置
官方给出的demo做了以下配置:
<activity android:name=".PL2303Activity" android:launchMode="singleTop">
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
//device_filter
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1659" product-id="8963" />
<usb-device vendor-id="1659" product-id="9553" />
<usb-device vendor-id="1659" product-id="8964" />
<usb-device vendor-id="1659" product-id="9475" />
<!-- usb-device vendor-id="1659=0x067B" product-id="8963=0x2303" -->
<!-- usb-device vendor-id="1659=0x067B" product-id="9553=0x2551" -->
<!-- usb-device vendor-id="1659=0x067B" product-id="8964=0x2304" -->
<!-- usb-device vendor-id="1659=0x067B" product-id="9475=0x2503" -->
</resources>
不过本人实测,单串口通信时不配置这个也能走通,貌似代码中自己添加了相关参数:
//这其实是个构造函数,混淆过的源码 - -#
private void a(UsbManager var1, Context var2, String var3, boolean var4) {
this.U = var1;
this.a = var2;
this.V = var3;
this.W.add("067B:2303");//这里其实就是device_filter中的参数
this.W.add("067B:2551");
this.W.add("067B:2503");
this.W.add("067B:AAA5");
this.W.add("05AD:0FBA");
this.a("067B:2304");
this.X = this.W.size();
this.ab = new UsbDeviceInfo[4];
this.ad = new PL2303MultiLib.a[4];
至于多串口通信,没做过多测试,而且最后还留了个坑。
基本使用
//第一步:得到PL2303MultiLib对象
PL2303MultiLib mSerialMulti = new PL2303MultiLib((UsbManager)mcontext.getSystemService(Context.USB_SERVICE),mcontext, ACTION_USB_PERMISSION);
//第二步:得到可用的device数目,注册广播接收器,监听一些状态变化(看源码貌似只发送了USB的DETACHED广播,extra数据为device index)
int iDeviceCount = mSerialMulti.PL2303Enumerate();
if(iDeviceCount > 0){
IntentFilter filter = new IntentFilter();
filter.addAction(mSerialMulti.PLUART_MESSAGE);
registerReceiver(PLMultiLibReceiver, filter);
}
//第三步:打开usb device,进行相关的读写操作(第一个参数为自定义的index,后续需要与该device通信时传该index)
boolean res = mSerialMulti.PL2303OpenDevByUARTSetting(DeviceIndex, mBaudrate,mDataBits, mStopBits, mParity, mFlowControl);
if(res){
//todo 读写操作
//读(一般用子线程无线循环进行操作,官方案例间隔60ms)
ReadLoop1.start();
}
//第四步:所有操作结束后释放相关资源
if (mSerialMulti != null) {
if (iDeviceCount > 0)
mcontext.unregisterReceiver(PLMultiLibReceiver);
mSerialMulti.PL2303Release();
mSerialMulti = null;
}
//读取数据的线程
private Runnable ReadLoop1 = new Runnable() {
public void run() {
for (;;) {
ReadLen1 = mSerialMulti.PL2303Read(DeviceIndex1, ReadBuf1);
if (ReadLen1 > 0) {
//ReadBuf1[ReadLen1] = 0;
mHandler1.post(new Runnable() {
public void run() {
StringBuffer sbHex=new StringBuffer();
for (int j = 0; j < ReadLen1; j++) {
sbHex.append((char) (ReadBuf1[j]&0x000000FF));
}
tvRead1.setText(sbHex.toString());
svReadView1.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
DelayTime(60);
if (stop) {
return;
}
}
}
};
暂留个坑
在实际使用的时候遇到这么个问题,我自己是用的anroid作为上位机,如果单串口通信,则一切正常;多个串口通信时,(在部分手机或者网络盒子上)必须先连接好一个usb接口,成功后再连接另一个,如果同时打开进行连接会发生crash,错误日志是usbdevice.getDeviceInterfaceCount为0,应该是国内各种自定义系统的原因,但是还没找到正确的解决办法。如果有知道的大神希望不吝赐教。或者等过段时间我自己搞明白了会亲手填上这个坑。