CH340/CH341 USB转串口安卓免驱应用开发
开发环境准备 安装Android Studio最新版本 添加USB转串口库依赖:在build.gradle中添加implementation 'com.github.licheedev:Android-SerialPort-API:2.1.1' 确保设备支持OTG功能并在AndroidManifest.xml中添加USB权限声明:
<uses-feature android:name="android.hardware.usb.host"/>
<uses-permission android:name="android.permission.USB_PERMISSION"/>
USB设备检测与权限处理
创建USB设备过滤器res/xml/device_filter.xml:
<resources>
<usb-device vendor-id="6790" product-id="29987"/> <!-- CH340 -->
<usb-device vendor-id="6790" product-id="21795"/> <!-- CH341 -->
</resources>
在Activity中注册USB设备插拔广播:
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(mUsbReceiver, filter);
处理USB权限请求:
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if(device != null && isSupportedDevice(device)){
requestUsbPermission(device);
}
}
}
};
串口通信初始化
获取USB设备并打开串口:
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbSerialPort port = UsbSerialProber.getDefaultProber().probeDevice(usbDevice);
if(port != null){
UsbSerialDriver driver = port.getDriver();
if(driver instanceof Ch340SerialDriver){
// CH34x specific initialization
port.open(usbManager.openDevice(usbDevice));
port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
}
}
数据收发实现
创建数据接收线程:
class SerialReadThread extends Thread {
public void run() {
byte[] buffer = new byte[1024];
while(!isInterrupted()){
int len = port.read(buffer, 1000);
if(len > 0){
final String data = new String(buffer, 0, len);
runOnUiThread(() -> receiveData(data));
}
}
}
}
实现数据发送方法:
public void sendData(String data) {
try {
byte[] bytes = data.getBytes();
port.write(bytes, 1000);
} catch (IOException e) {
e.printStackTrace();
}
}
错误处理与资源释放
实现异常处理机制:
try {
port.setDTR(true);
port.setRTS(true);
} catch (IOException e) {
showError("设备控制失败:" + e.getMessage());
}
正确释放资源:
@Override
protected void onDestroy() {
super.onDestroy();
if(port != null){
try {
port.close();
} catch (IOException e) {
e.printStackTrace();
}
}
unregisterReceiver(mUsbReceiver);
}
波特率配置优化
CH34x系列支持的波特率范围:
private static final int[] BAUD_RATES = {
50, 75, 100, 110, 134, 150, 200, 300, 600,
1200, 1800, 2400, 4800, 9600, 19200, 38400,
57600, 115200, 230400, 460800, 921600
};
public void setBaudRate(int baudRate) throws IOException {
if(Arrays.binarySearch(BAUD_RATES, baudRate) < 0){
throw new IllegalArgumentException("不支持的波特率");
}
port.setParameters(baudRate, dataBits, stopBits, parity);
}
流控制实现
硬件流控制配置:
public void setFlowControl(int flowControl) {
try {
switch(flowControl){
case FLOW_CONTROL_OFF:
port.setRTS(false);
port.setDTR(false);
break;
case FLOW_CONTROL_RTS_CTS:
port.setRTS(true);
port.setDTR(false);
break;
case FLOW_CONTROL_DSR_DTR:
port.setRTS(false);
port.setDTR(true);
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
性能优化技巧
使用缓冲区提高收发效率:
ByteArrayOutputStream receiveBuffer = new ByteArrayOutputStream();
private static final int BUFFER_SIZE = 4096;
void readData() throws IOException {
byte[] tempBuffer = new byte[BUFFER_SIZE];
int len;
while((len = port.read(tempBuffer, 0)) > 0){
receiveBuffer.write(tempBuffer, 0, len);
processCompletePackets();
}
}
完整示例项目结构
典型项目结构:
app/
├── libs/
├── src/
│ ├── main/
│ │ ├── java/com/example/serialapp/
│ │ │ ├── SerialService.java
│ │ │ ├── MainActivity.java
│ │ │ └── utils/
│ │ │ ├── SerialUtils.java
│ │ │ └── ProtocolParser.java
│ │ ├── res/
│ │ │ ├── xml/
│ │ │ │ └── device_filter.xml
│ │ │ └── layout/
│ │ │ └── activity_main.xml
│ │ └── AndroidManifest.xml
└── build.gradle
常见问题解决方案
CH34x设备不识别问题: 检查设备VID/PID是否匹配:CH340通常为VID_1A86/PID_7523 确保已安装正确的USB驱动,部分设备需要手动加载驱动
数据收发不完整问题: 增加超时设置和缓冲区管理 校验数据包的起始和结束标记 实现数据分包和组包逻辑
兼容性问题处理:
public static boolean isCh34xDevice(UsbDevice device) {
return (device.getVendorId() == 0x1A86 &&
(device.getProductId() == 0x7523 ||
device.getProductId() == 0x5523));
}
5953

被折叠的 条评论
为什么被折叠?



