android FT232H USB高速串口调试
程序员文章站
2022-07-14 09:42:26
...
android FT232H USB高速串口调试
android FT232H USB高速串口调试
最近用到了一个高速UART转USB模块,8M的8000000波特率,很明显这是非标准波特率。这就得使用专有的驱动程序。这里主要说下在android的使用方法。
内核支持
插上USB模块后,在/dev/下会出现ttyUSB0的设备节点。
dmesg | tail
如果没有出现节点,需要开启内核驱动,在内核源码drivers/usb/serial/ftdi_sio.c,包含进去重新编译内核。
驱动集成
出现对应节点后,https://www.ftdichip.com/Drivers/D2XX.htm,下载Java Driver。
解压后安装TN_147_Java_D2xx_for_Android_Demo_Source/TN_147_Java_D2xx_for_Android_Demo.apk,可以读出芯片参数,则说明驱动集成完毕。
SDK使用
修改build.gradle,复制demo中的d2xx.jar到项目app/libs文件夹下
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
// FT232H USB转串口
implementation files('libs/d2xx.jar')
}
package com.liulc.utils;
import android.content.Context;
import com.ftdi.j2xx.D2xxManager;
import com.ftdi.j2xx.FT_Device;
import static com.liulc.utils.LogUtils.logld;
import static com.liulc.utils.LogUtils.logle;
/**
* @author Liulc
* @version 1.0
* @date 2020/3/26
*/
public class FT232Util {
private static final String TAG = "liulc";
private static FT_Device ftDev = null;
private static D2xxManager ftdid2xx;
public FT232Util (Context context) {
try {
ftdid2xx = D2xxManager.getInstance(context);
ftdid2xx.createDeviceInfoList(context);
} catch (D2xxManager.D2xxException ex) {
logle(TAG, ex.toString());
}
}
public boolean open(Context context) {
if (ftDev!=null && ftDev.isOpen()) {
logld(TAG, "FT232串口已打开");
return true;
}
for (int openIndex = 0; openIndex < 10; openIndex++) {
ftDev = ftdid2xx.openByIndex(context, openIndex);
if (ftDev == null) {
continue;
}
if (ftDev.isOpen()) {
logld(TAG, "发现FT232串口, index: " + openIndex);
return true;
}
}
logle(TAG, "没有发现FT232串口");
return false;
}
// 8000000 8 1 0 0
public boolean setConfig(int baud, byte dataBits, byte stopBits, byte parity, byte flowControl) {
if (!ftDev.isOpen()) {
logle(TAG, "device not open");
return false;
}
// 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);
logld(TAG, "串口配置完成");
return true;
}
public int write(byte[] data) {
return ftDev.write(data);
}
public int write(byte[] data, int length) {
return ftDev.write(data, length);
}
public int write(byte[] data, int length, boolean wait) {
return ftDev.write(data, length, wait);
}
public int read(byte[] data) {
return ftDev.read(data);
}
public int read(byte[] data, int length) {
return ftDev.read(data, length);
}
public int read(byte[] data, int length, long wait_ms) {
return ftDev.read(data, length, wait_ms);
}
public int getQueueStatus() {
return ftDev.getQueueStatus();
}
}
private static FT232Util sFT232Util;
sFT232Util = new FT232Util(context);
// 波特率8000000,数据位8,停止位1,不使用校验,不使用流控
if (sFT232Util.open(context)) {
sFT232Util.setConfig(8000000, (byte) 8, (byte) 1, (byte) 0, (byte) 0);
}
/*用的时候,要先判断有没有数据,再去读,不然会出问题,数据读不全*/
int available = sFT232Util.getQueueStatus();
if (available <= 0) {
// logld(TAG, "USB空数据");
try{
sleep(50);
}catch (Exception e){
e.printStackTrace();
}
continue;
}
if (available > maxLen) {
available = maxLen;
}
int readLen = sFT232Util.read(readData, available);
去除“默认情况下用于该USB设备”提示框
在AndroidManifest.xml中,添加android:sharedUserId=“android.uid.system” 到manifest节点,再对apk进行系统签名。签名之后就不再出现了。怎么签名的就不介绍了,这个网上一堆。
推荐阅读
-
android Studio调试出现USB device not found怎么办?
-
Android项目实战(四十五):Usb转串口通讯(CH34xUARTDriver)
-
如何在无数据线USB连接, 只有wifi情况下使用android studio build app到手机进行调试?
-
Android 开发中如何不用USB数据线进行调试
-
Android USB转串口通信开发实例详解
-
android FT232H USB高速串口调试
-
详解Android USB转串口通信开发基本流程
-
Android 11 usb调试默认打开
-
Android 允许USB调试弹窗是怎么弹出来的
-
Android P开发者选项中的USB调试关闭