简介
Java Simple Serial Connector (jSSC) 是一个轻量级的Java串口通信库,支持Windows、Linux、Mac OS X和Solaris等多平台。它的特点是简单易用、性能稳定,适合需要串口通信的Java应用程序开发。
主要特性
-
跨平台支持
-
简单API设计
-
事件驱动模型
-
支持波特率自定义
-
支持数据位、停止位、校验位配置
-
支持流控制
安装配置
Maven依赖
java
<dependency>
<groupId>org.scream3r</groupId>
<artifactId>jssc</artifactId>
<version>2.8.0</version>
</dependency>
基础用法
1. 获取串口列表
java
import jssc.SerialPortList;
public class ListPorts {
public static void main(String[] args) {
String[] portNames = SerialPortList.getPortNames();
System.out.println("可用串口:");
for (String portName : portNames) {
System.out.println(portName);
}
}
}
2. 打开和配置串口
java
import jssc.SerialPort;
import jssc.SerialPortException;
public class OpenPort {
public static void main(String[] args) {
// 创建串口对象(Windows: COM1, Linux: /dev/ttyUSB0, Mac: /dev/tty.usbserial)
SerialPort serialPort = new SerialPort("COM3");
try {
// 打开串口
serialPort.openPort();
// 配置串口参数
serialPort.setParams(
SerialPort.BAUDRATE_9600, // 波特率
SerialPort.DATABITS_8, // 数据位
SerialPort.STOPBITS_1, // 停止位
SerialPort.PARITY_NONE // 校验位
);
System.out.println("串口打开成功!");
} catch (SerialPortException e) {
e.printStackTrace();
}
}
}
3. 发送数据
java
// 发送字符串
serialPort.writeString("Hello Arduino!");
// 发送字节数组
byte[] data = {0x01, 0x02, 0x03, 0x04};
serialPort.writeBytes(data);
// 发送单个字节
serialPort.writeByte((byte)0x55);
4. 接收数据
java
// 同步读取
byte[] buffer = serialPort.readBytes(10); // 读取10个字节
String received = serialPort.readString(); // 读取字符串
// 设置超时
serialPort.readBytes(10, 1000); // 最多等待1000毫秒
高级特性
1. 事件监听器
java
import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
public class SerialReader implements SerialPortEventListener {
private SerialPort serialPort;
public SerialReader(String portName) {
serialPort = new SerialPort(portName);
try {
serialPort.openPort();
serialPort.setParams(9600, 8, 1, 0);
// 设置事件掩码(监听数据接收事件)
serialPort.setEventsMask(SerialPort.MASK_RXCHAR);
// 添加事件监听器
serialPort.addEventListener(this);
} catch (SerialPortException e) {
e.printStackTrace();
}
}
@Override
public void serialEvent(SerialPortEvent event) {
if (event.isRXCHAR() && event.getEventValue() > 0) {
try {
// 读取接收到的数据
byte[] buffer = serialPort.readBytes(event.getEventValue());
String received = new String(buffer);
System.out.println("收到数据:" + received);
} catch (SerialPortException e) {
e.printStackTrace();
}
}
}
// 关闭串口
public void close() {
try {
serialPort.closePort();
} catch (SerialPortException e) {
e.printStackTrace();
}
}
}
2. 流控制设置
java
// 设置RTS/CTS流控制
serialPort.setFlowControlMode(
SerialPort.FLOWCONTROL_RTSCTS_IN |
SerialPort.FLOWCONTROL_RTSCTS_OUT
);
// 设置XON/XOFF流控制
serialPort.setFlowControlMode(
SerialPort.FLOWCONTROL_XONXOFF_IN |
SerialPort.FLOWCONTROL_XONXOFF_OUT
);
3. 手动控制RTS/DTR信号
java
// 设置RTS信号
serialPort.setRTS(true); // 高电平
serialPort.setRTS(false); // 低电平
// 设置DTR信号
serialPort.setDTR(true); // 高电平
serialPort.setDTR(false); // 低电平
示例代码
完整示例:串口调试助手
java
import jssc.*;
import java.util.Scanner;
public class SerialDebugger implements SerialPortEventListener {
private SerialPort serialPort;
private Scanner scanner;
public SerialDebugger(String portName, int baudRate) {
serialPort = new SerialPort(portName);
scanner = new Scanner(System.in);
try {
// 打开串口
serialPort.openPort();
System.out.println("串口 " + portName + " 已打开");
// 配置串口
serialPort.setParams(
baudRate,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE
);
// 设置事件监听
serialPort.setEventsMask(SerialPort.MASK_RXCHAR);
serialPort.addEventListener(this);
System.out.println("串口配置完成,波特率:" + baudRate);
// 发送数据线程
startSendThread();
} catch (SerialPortException e) {
e.printStackTrace();
}
}
private void startSendThread() {
Thread sendThread = new Thread(() -> {
while (true) {
System.out.print("请输入要发送的数据(输入'exit'退出):");
String input = scanner.nextLine();
if (input.equalsIgnoreCase("exit")) {
close();
break;
}
try {
// 发送数据
serialPort.writeString(input + "\r\n");
System.out.println("发送成功:" + input);
} catch (SerialPortException e) {
System.out.println("发送失败:" + e.getMessage());
}
}
});
sendThread.start();
}
@Override
public void serialEvent(SerialPortEvent event) {
if (event.isRXCHAR() && event.getEventValue() > 0) {
try {
byte[] buffer = serialPort.readBytes(event.getEventValue());
System.out.println("\n接收数据:" + new String(buffer));
System.out.print("请输入要发送的数据(输入'exit'退出):");
} catch (SerialPortException e) {
e.printStackTrace();
}
}
}
private void close() {
try {
if (serialPort != null && serialPort.isOpened()) {
serialPort.closePort();
System.out.println("串口已关闭");
}
scanner.close();
} catch (SerialPortException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 显示可用串口
String[] ports = SerialPortList.getPortNames();
System.out.println("可用串口:");
for (String port : ports) {
System.out.println(port);
}
if (ports.length > 0) {
// 使用第一个可用串口
new SerialDebugger(ports[0], 9600);
} else {
System.out.println("没有找到可用串口");
}
}
}
常见问题
1. 找不到串口
-
Windows: 检查驱动是否正确安装,端口号是否正确(如COM3)
-
Linux: 检查用户是否有权限访问串口(需要加入dialout组)
bashsudo usermod -a -G dialout $USER -
Mac: 检查是否安装了驱动,端口名称通常为/dev/tty.usbserial-*
2. 权限问题
在Linux/Mac上运行Java程序时,可能需要root权限:
java
sudo java -jar yourprogram.jar
3. 数据乱码
检查波特率、数据位、停止位、校验位是否与设备匹配
4. 本地库加载失败
确保jssc的本地库文件(.dll/.so/.dylib)可以被Java访问,或者将库文件放在系统库路径中
5. 资源释放
确保在使用完串口后正确关闭:
java
try {
if (serialPort != null && serialPort.isOpened()) {
serialPort.closePort();
}
} catch (SerialPortException e) {
e.printStackTrace();
}