diff --git a/docs/CH934X_Android_开发说明.md b/docs/CH934X_Android_开发说明.md index 7e51b99..38bd5d3 100644 --- a/docs/CH934X_Android_开发说明.md +++ b/docs/CH934X_Android_开发说明.md @@ -1,376 +1,382 @@ # CH934X 系列芯片串口 Android 程序开发说明 -## 目录 - -- [1 概述](#1-概述) -- [2 权限申请](#2-权限申请) -- [3 引入 SDK](#3-引入-sdk) -- [4 设备查找](#4-设备查找) - - [4.1 UsbHelper](#41-usbhelper) -- [5 设备打开与关闭](#5-设备打开与关闭) - - [5.1 打开设备](#51-打开设备) - - [5.2 关闭设备](#52-关闭设备) -- [6 串口读写](#6-串口读写) - - [6.1 读数据](#61-读数据) - - [6.2 写数据](#62-写数据) -- [7 其他接口](#7-其他接口) - - [7.1 GPIO 接口](#71-gpio-接口) - - [7.2 Modem 控制接口](#72-modem-控制接口) - - [7.3 异常接口](#73-异常接口) -- [8 接口总览](#8-接口总览) -- [9 更新日志](#9-更新日志) - ---- - -## 1 概述 - -CH934X 是 USB 转串口芯片,支持多路串口。CH934X 提供了 Android 端 SDK,本文档主要介绍在 Android 平台进行串口程序开发所用到的接口。 - -CH934X 库接口主要分为以下几类:基本操作、设备查找、串口读写、其他接口、异常接口等。下文将以 API 形式介绍这些接口。 - -## 2 权限申请 - -需要在 AndroidManifest.xml 中添加 USB 权限申请: - -```xml - - -``` - -需要在 Activity 启动之前(即 onCreate 函数中)添加以下代码来动态申请权限: - -```java -// 申请权限,接收广播 -UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); -// 申请权限 -PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_DEVICE_PERMISSION), 0); -IntentFilter filter = new IntentFilter(ACTION_DEVICE_PERMISSION); -context.registerReceiver(mUsbPermissionReceiver, filter); -// 获取 usb 设备列表并依次申请权限 -HashMap deviceList = usbManager.getDeviceList(); -for (UsbDevice device : deviceList.values()) { - usbManager.requestPermission(device, mPermissionIntent); -} -``` - -```java -// 接收权限申请广播 -private static final String ACTION_DEVICE_PERMISSION = "com.example.USB_PERMISSION"; -private final BroadcastReceiver mUsbPermissionReceiver = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (ACTION_DEVICE_PERMISSION.equals(action)) { - synchronized (this) { - UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); - if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { - if (device != null) { - // 用户授权,可以进行设备打开等操作 - } - } else { - Log.d(TAG, "permission denied for device " + device); - } - } - } - } -}; -``` +## 概述 -## 3 引入 SDK - -将 CH934XLib.jar 引入到工程,可放置在 app/libs/ 目录下,然后修改 app 模块的 build.gradle: - -```gradle -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - // ... 其他依赖 -} -``` - -## 4 设备查找 - -CH934X 设备主要为 USB 转串口芯片,因此可以通过 Android USB Host API 来枚举设备。用户也可以使用 CH934X SDK 提供的 UsbHelper 工具类,简化设备枚举流程。 +本文档是针对 CH934X/CH348 系列的 USB 转串口安卓库的开发说明文档。 -### 4.1 UsbHelper - -通过 UsbHelper 工具类,获取 CH934X 设备的序列号及对应设备类,从而实现对 CH934X 设备与串口的精确查找。 +CH934X 串口提供的 Android 接口需要基于 Android 4.4 及以上版本系统,使用 CH934X串口 Android 驱动条件: -#### 4.1.1 CH934XSerialNum +- 基于 Android 4.4 及以上版本系统 -- 函数原型: +- Android 设备具有 USB Host 或 OTG 接口 -```java -public static String CH934XSerialNum(UsbDevice device) -``` - -- 参数:device,UsbDevice 对象。 -- 返回值:String 类型,CH934X 设备序列号。如果设备不是 CH934X 设备,则返回 null。 -- 说明:通过 USB 设备获取 CH934X 序列号。 +## 接口说明 -#### 4.1.2 CH934XDeviceType +### getInstance -- 函数原型: +public static CH934XManager getInstance()用于获取全局唯一实例 -```java -public static int CH934XDeviceType(UsbDevice device) -``` +| | | +|---|---| +| **返回** | 返回全局唯一实例 | -- 参数:device,UsbDevice 对象。 -- 返回值:int 类型,CH934X 设备类型。返回值为下表中的常量: +### init -| 常量 | 值 | 描述 | -| -------------------------- | --- | ----------------------------- | -| DEVICE_TYPE_CH9344 | 0 | CH9344 芯片 | -| DEVICE_TYPE_CH9344L | 1 | CH9344L 芯片 | -| DEVICE_TYPE_CH9350 | 2 | CH9350 芯片 | -| DEVICE_TYPE_CH9348Q | 3 | CH9348Q 芯片 | -| DEVICE_TYPE_CH9342 | 4 | CH9342 芯片 | -| DEVICE_TYPE_CH934X_OTHER | 5 | 其他 CH934X 设备 | +public void init(android.app.Application application)初始化上下文,注册动态广播监听设备状态变化 -- 说明:通过 USB 设备获取 CH934X 设备类型。 +| | | +|---|---| +| **参数** | application - 全局上下文 | -#### 4.1.3 getCH934XSerialPortList +### enumDevice -- 函数原型: +public ArrayList enumDevice() throws UartLibException枚举当前的 CH934X 设备 -```java -public static UsbSerial[] getCH934XSerialPortList(Context context, UsbDevice device, int interfaceNum) -``` +| | | +|---|---| +| **返回** | 设备列表 | +| **抛出** | UartLibException | -- 参数: - - context,Context 对象。 - - device,UsbDevice 对象。 - - interfaceNum,int 类型,CH934X 设备的接口号。 -- 返回值:UsbSerial 数组。 -- 说明:获取 CH934X 设备的串口列表。 +### getChipType -#### 4.1.4 getCH934XDeviceList +public ChipType getChipType(@NonNull UsbDevice usbDevice)根据 UsbDevice 获取芯片类型 -- 函数原型: +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | +| **返回** | 如果为 null 则表示参数USB 设备并不是 CH934X | -```java -public static List getCH934XDeviceList(Context context) -``` +### openDevice -- 参数:context,Context 对象。 -- 返回值:List,CH934X 设备信息列表。 -- 说明:获取 CH934X 设备列表。 +public boolean openDevice(@NonNull UsbDevice usbDevice) -## 5 设备打开与关闭 +throws .UartLibException,NoPermissionException,ChipException -### 5.1 打开设备 +打开设备 -#### 5.1.1 init +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | +| **返回** | true 成功;false 失败 | -- 函数原型: +| | | +|---|---| +| **抛出** | UartLibException
NoPermissionException ChipException | -```java -public boolean init(Context context, UsbDevice device, int interfaceNum, int serialPortIndex) -``` +### requestPermission -- 参数: - - context,Context 对象。 - - device,UsbDevice 对象。 - - interfaceNum,int 类型,CH934X 设备的接口号。 - - serialPortIndex,int 类型,串口索引。 -- 返回值:boolean 类型,true 表示成功,false 表示失败。 -- 说明:初始化 CH934X 设备并打开指定串口。 +public void requestPermission(@NonNullContext context, -```java -// 示例代码 -UsbSerial serialPort = new UsbSerial(); -if (serialPort.init(context, device, interfaceNum, serialPortIndex)) { - // 初始化成功 -} -``` +@NonNullUsbDevice usbDevice) throws UartLibException -### 5.2 关闭设备 +请求 USB 设备权限 -#### 5.2.1 close +| | | +|---|---| +| **参数** | context – 上下文
usbDevice - USB 设备 | +| **抛出** | UartLibException | -- 函数原型: +### setUsbStateListener -```java -public boolean close() -``` +public void setUsbStateListener(@NonNullIUsbStateChange usbStateListener)监听设备的状态变化 -- 返回值:boolean 类型,true 表示成功,false 表示失败。 -- 说明:关闭串口。 +| | | +|---|---| +| **参数** | usbStateListener – 设备状态监听调 | -```java -// 示例代码 -if (serialPort != null) { - serialPort.close(); - serialPort = null; -} -``` +### getSerialCount -## 6 串口读写 +public int getSerialCount(@NonNull UsbDevice usbDevice)获取设备的串口数目 -### 6.1 读数据 +| | | +|---|---| +| **参数** | usbDevice – USB 设备 | +| **返回** | 返串口数目;如果为负,说明获取失败 | -#### 6.1.1 read +### setSerialParameter -- 函数原型: +public boolean setSerialParameter(@NonNull -```java -public int read(byte[] buf, int length) -``` +UsbDevice usbDevice, int serialNumber, int baud, -- 参数: - - buf,byte[] 类型,接收数据的缓冲区。 - - length,int 类型,要读取的字节数。 -- 返回值:int 类型,实际读取的字节数;返回 0 或负值表示无数据或读取失败。 -- 说明:从串口读取数据。 +int dataBit, int stopBit, int parityBit, boolean flow) -```java -// 示例代码 -byte[] buffer = new byte[1024]; -int length = serialPort.read(buffer, buffer.length); -if (length > 0) { - // 处理读取到的数据 -} -``` +throws .UartLibException,ChipException -### 6.2 写数据 +设置串口参数 -#### 6.2.1 write +| | | +|---|---| +| **参数** | usbDevice - USB 设备 serialNumber - 串口号 baud - 波特率 dataBit - 数据位 stopBit - 停止位 parityBit - 校验位
flow - 流控 | -- 函数原型: +| | | +|---|---| +| **返回** | true 设置成功;false 设置失败 | +| **抛出** | UartLibException
ChipException | -```java -public int write(byte[] buf, int length) -``` +### writeData -- 参数: - - buf,byte[] 类型,要发送的数据。 - - length,int 类型,要发送的字节数。 -- 返回值:int 类型,实际写入的字节数;返回 0 或负值表示写入失败。 -- 说明:向串口写入数据。 +public int writeData(@NonNull -```java -// 示例代码 -byte[] data = new byte[]{0x01, 0x02, 0x03}; -int length = serialPort.write(data, data.length); -if (length > 0) { - // 写入成功 -} -``` +UsbDevice usbDevice, int serialNumber, byte[] data, -## 7 其他接口 +int length, int timeout) -### 7.1 GPIO 接口 +throws UartLibException,ChipException发送数据 -#### 7.1.1 setGpioOutput +| | | +|---|---| +| **参数** | usbDevice - USB 设备 serialNumber - 串口号 data - 待发送的数据
length - 待发送的数据的长度
timeout - 超时时间 | +| **返回** | 发送成功的数据的长度 | +| **抛出** | UartLibException
ChipException | -- 函数原型: +### readData -```java -public boolean setGpioOutput(int gpioNum, int level) -``` +public byte[] readData(@NonNull UsbDevice usbDevice,int serialNumber) throws ChipException -- 参数: - - gpioNum,int 类型,GPIO 引脚编号。 - - level,int 类型,输出电平(0 或 1)。 -- 返回值:boolean 类型,true 表示成功,false 表示失败。 -- 说明:设置 GPIO 引脚为输出模式并设置电平。 +读取数据 -#### 7.1.2 getGpioInput +| | | +|---|---| +| **参数** | usbDevice - USB 设备
serialNumber - 串口号 | +| **返回** | 读取到的数据 | +| **抛出** | ChipException | -- 函数原型: +### registerDataCallback -```java -public int getGpioInput(int gpioNum) -``` +public void registerDataCallback(@NonNull UsbDevice usbDevice, -- 参数:gpioNum,int 类型,GPIO 引脚编号。 -- 返回值:int 类型,输入电平(0 或 1),负值表示读取失败。 -- 说明:读取 GPIO 引脚输入电平。 +IDataCallback dataCallback) throws ChipException -### 7.2 Modem 控制接口 +注册串口数据 调, 解除注册使用 registerDataCallback(device,null) 方法, 或者 removeDataCallback(device)方法 -#### 7.2.1 setModemControl +| | | +|---|---| +| **参数** | usbDevice - USB 设备
dataCallback – 调 | +| **返回** | 读取到的数据 | +| **抛出** | ChipException | -- 函数原型: +### removeDataCallback -```java -public boolean setModemControl(int dtr, int rts) -``` +public void removeDataCallback(@NonNull UsbDevice usbDevice)解除注册串口数据回调 -- 参数: - - dtr,int 类型,DTR 信号电平(0 或 1)。 - - rts,int 类型,RTS 信号电平(0 或 1)。 -- 返回值:boolean 类型,true 表示成功,false 表示失败。 -- 说明:设置 DTR 和 RTS 信号。 +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | -#### 7.2.2 getModemStatus +### setBreak -- 函数原型: +public boolean setBreak(@NonNull UsbDevice usbDevice,int serialNumber, -```java -public int getModemStatus() -``` +boolean valid) throws Exception -- 返回值:int 类型,Modem 状态位。返回值为下表中的位掩码: +设置 Break 信号 -| 常量 | 值 | 描述 | -| --------------------- | ----- | ---------- | -| MODEM_STATUS_CTS | 0x01 | CTS 状态 | -| MODEM_STATUS_DSR | 0x02 | DSR 状态 | -| MODEM_STATUS_RI | 0x04 | RI 状态 | -| MODEM_STATUS_DCD | 0x08 | DCD 状态 | +| | | +|---|---| +| **参数** | usbDevice - USB 设备 serialNumber - 串口号
valid – 是否有效(低电平标识有效) | +| **返回** | true 设置成功;false 设置失败 | +| **抛出** | Exception | -- 说明:获取 Modem 状态。 +### setDTR -```java -// 示例代码 -int status = serialPort.getModemStatus(); -boolean cts = (status & UsbSerial.MODEM_STATUS_CTS) != 0; -``` +public boolean setDTR(UsbDevice usbDevice,int serialNumber,boolean dtr) -### 7.3 异常接口 +throws UartLibException, ChipException -#### 7.3.1 setExceptionCallback +设置 DTR 信号 -- 函数原型: +| | | +|---|---| +| **参数** | usbDevice - USB 设备 serialNumber - 串口号
dtr – true 有效;false 无效 | +| **返回** | true 设置成功;false 设置失败 | +| **抛出** | ChipException
UartLibException | -```java -public void setExceptionCallback(UsbSerial.ExceptionCallback callback) -``` +### setRTS -- 参数:callback,ExceptionCallback 对象,异常回调接口。 -- 返回值:无。 -- 说明:设置异常回调,用于接收设备拔出等异常事件。 +public boolean setRTS(UsbDevice usbDevice,int serialNumber,boolean rts) throws -```java -// 示例代码 -serialPort.setExceptionCallback(new UsbSerial.ExceptionCallback() { - @Override - public void onException(int type, Exception e) { - // 处理异常,例如设备拔出 - } -}); -``` +UartLibException, ChipException -## 8 接口总览 +设置 RTS 信号 -| 接口 | 名称 | 分类 | 说明 | -| ---- | ---- | ---- | ---- | -| UsbHelper.CH934XSerialNum | 获取 CH934X 序列号 | 设备查找 | 获取 CH934X 设备的序列号 | -| UsbHelper.CH934XDeviceType | 获取 CH934X 设备类型 | 设备查找 | 获取 CH934X 设备的类型 | -| UsbHelper.getCH934XSerialPortList | 获取 CH934X 串口列表 | 设备查找 | 获取指定 CH934X 设备的串口列表 | -| UsbHelper.getCH934XDeviceList | 获取 CH934X 设备列表 | 设备查找 | 获取所有 CH934X 设备列表 | -| UsbSerial.init | 初始化并打开串口 | 设备打开 | 初始化并打开指定串口 | -| UsbSerial.close | 关闭串口 | 设备关闭 | 关闭已打开的串口 | -| UsbSerial.read | 读取数据 | 串口读写 | 从串口读取数据 | -| UsbSerial.write | 写入数据 | 串口读写 | 向串口写入数据 | -| UsbSerial.setGpioOutput | 设置 GPIO 输出 | GPIO | 设置 GPIO 引脚为输出模式并设置电平 | -| UsbSerial.getGpioInput | 读取 GPIO 输入 | GPIO | 读取 GPIO 引脚输入电平 | -| UsbSerial.setModemControl | 设置 Modem 控制 | Modem | 设置 DTR 和 RTS 信号 | -| UsbSerial.getModemStatus | 获取 Modem 状态 | Modem | 获取 Modem 状态 | -| UsbSerial.setExceptionCallback | 设置异常回调 | 异常 | 设置设备拔出等异常回调 | +| | | +|---|---| +| **参数** | usbDevice - USB 设备 serialNumber - 串口号
rts– true 有效;false 无效 | +| **返回** | true 设置成功;false 设置失败 | +| **抛出** | ChipException
UartLibException | -## 9 更新日志 +### registerModemStatusCallback + +public void registerModemStatusCallback(@NonNull UsbDevice usbDevice, + +IModemStatus modemStatus) throws Exception注册 Modem 输入信号状态的调 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备
modemStatus – 状态回调 | + +| | | +|---|---| +| **抛出** | Exception | + +### querySerialErrorCount + +public int querySerialErrorCount(@NonNull UsbDevice usbDevice, int serialNumber,@NonNull SerialErrorType errorType) + +throws Exception + +查询串口错误状态 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 serialNumber– 串口号
errorType– 错误类型 | +| **返回** | 出现错误的次数 | +| **抛出** | Exception | + +### getCurrentMode + +public Mode getCurrentMode(UsbDevice usbDevice,int serialNumber) + +获取当前串口的模式。初始默认状态为普通模式(仅针对 CH934X 型号设备,CH348 无效) + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | +| **参数** | serialNumber-串口序号 | +| **返回** | Mode.NORMAL 普通模式;Mode.HARDFLOW 硬件流控模式;
Mode.GPIO GPIO 模式; | +| **抛出** | UartLibException | + +### getSpecificType + +public SpecificChipType getSpecificType(UsbDevice usbDevice) + +throws UartLibException + +获取芯片具体型号 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | +| **返回** | 芯片具体型号 | +| **抛出** | UartLibException | + +### getGPIOCount + +public int getGPIOCount(UsbDevice usbDevice) throws UartLibException获取 GPIO 数量 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | +| **返回** | GPIO 具体数量(从 0 开始使用) | +| **抛出** | UartLibException | + +### getGPIOGroup + +public int getGPIOGroup(UsbDevice usbDevice) throws UartLibException + +获取 GPIO 组 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | +| **返回** | GPIO 组数量(从 0 开始使用) | +| **抛出** | UartLibException | + +### enableGPIO + +public boolean enableGPIO(@NonNull UsbDevice usbDevice, ChipType chipType, int gpioGroup, int enable) throws UartLibException + +使能串口的 GPIO 功能,如果当前模式为硬件流控模式,需要先退出。 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 chipType – 芯片类型 gpioGroup – GPIO 组号 enable – 使能状态
CH9344: 1 使能组内所有 GPIO;0 失能组内所有GPIO
CH348: bits0-7 对应 GPIO[0*N-7*N], 1 使能;0 失能 | +| **返回** | true 操作成功;false 操作失败 | +| **抛出** | UartLibException | + +### setGPIODir + +public boolean setGPIODir(@NonNull UsbDevice usbDevice,int gpioGroup, int gpioNumber, @NonNull GPIO_DIR dir) throws UartLibException + +设置 GPIO 口的方向,成功后会同步至缓存 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 gpioGroup –GPIO 组号 gpioNumber – GPIO 序号
dir -方向 | +| **返回** | true 操作成功;false 操作失败 | +| **抛出** | UartLibException | + +### queryGPIODirFromCache + +public GPIO_DIR queryGPIODirFromCache(@NonNull UsbDevice usbDevice, int gpioGroup, int gpioNumber) throws UartLibException + +从缓存中获取某个 GPIO 的方向。初始每个 GPIO 初始默认方向是 GPIO_DIR.IN + +| | | +|---|---| +| **参数** | usbDevice - USB 设备
gpioGroup – GPIO 组号 gpioNumber -GPIO 序号 | +| **返回** | GPIO_DIR.IN IN 方向;GPIO_DIR.OUT OUT 方向 | +| **抛出** | UartLibException | + +### setGPIOValue + +public boolean setGPIOValue(@NonNull UsbDevice usbDevice, int gpioGroup, int gpioNumber, @NonNull GPIO_VALUE value) throws UartLibException + +设置 GPIO 口的值,成功后会同步至缓存 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 gpioGroup – GPIO 组号 gpioNumber -GPIO 序号
value - GPIO 值 | +| **返回** | true 操作成功;false 操作失败 | +| **抛出** | UartLibException | + +### getGPIOValue + +public boolean getGPIOValue(@NonNull UsbDevice usbDevice) throws UartLibException + +从硬件获取 GPIO 值,成功后会刷新缓存 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | +| **返回** | true 操作成功;false 操作失败 | +| **抛出** | UartLibException | + +### queryGPIOValueFromCache + +public GPIO_VALUE queryGPIOValueFromCache(@NonNull UsbDevice usbDevice,int gpioGroup,int gpioNumber) throws UartLibException + +从缓存中获取某个 GPIO 值。使用此方法前需要先成功使用 getGPIOValue()方法,刷新缓存。初始每个 GPIO 初始默认值是GPIO_VALUE.LOW + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 gpioGroup – GPIO 组号
gpioNumber -GPIO 序号 | +| **返回** | GPIO_VALUE.HIGH 高电平;GPIO_VALUE.LOW 低电平 | +| **抛出** | UartLibException | + +### isConnected + +public boolean isConnected(@NonNull UsbDevice usbDevice)设备是否已经被打开 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | +| **返回** | true 已经被打开;false 没有被打开 | + +### getConnectedDevices + +public ArrayList getConnectedDevices()获取当前已经被打开的设备列表 + +### disconnect + +public void disconnect(@NonNull UsbDevice usbDevice)断开连接 + +| | | +|---|---| +| **参数** | usbDevice - USB 设备 | + +### close + +public void close(@NonNull Context context)释放资源。断开所有连接设备 -| 版本 | 日期 | 更新内容 | -| ---- | ---- | -------- | -| 1.0 | 2024-08-15 | 初版发布,包含 CH934X 设备查找、串口读写、GPIO、Modem 控制、异常回调等接口 |