欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android FT232H USB高速串口调试

程序员文章站 2022-07-14 09:42:26
...

android FT232H USB高速串口调试

最近用到了一个高速UART转USB模块,8M的8000000波特率,很明显这是非标准波特率。这就得使用专有的驱动程序。这里主要说下在android的使用方法。

内核支持

插上USB模块后,在/dev/下会出现ttyUSB0的设备节点。
dmesg | tail
android FT232H USB高速串口调试
如果没有出现节点,需要开启内核驱动,在内核源码drivers/usb/serial/ftdi_sio.c,包含进去重新编译内核。

驱动集成

出现对应节点后,https://www.ftdichip.com/Drivers/D2XX.htm,下载Java Driver。
android FT232H USB高速串口调试
解压后安装TN_147_Java_D2xx_for_Android_Demo_Source/TN_147_Java_D2xx_for_Android_Demo.apk,可以读出芯片参数,则说明驱动集成完毕。
android FT232H USB高速串口调试

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 Driver