本文实例为大家分享了java使用Rxtx实现串口通信调试工具的具体代码,供大家参考,具体内容如下
最终效果如下图:
1、把rxtxParallel.dll、rxtxSerial.dll拷贝到:C:WINDOWSsystem32下。
2、RXTXcomm.jar 添加到项目类库中。
代码:
package serialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.TooManyListenersException;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
public class SerialTool {
private static SerialTool serialTool = null;
static {
//在该类被ClassLoader加载时就初始化一个SerialTool对象
if (serialTool == null) {
serialTool = new SerialTool();
}
}
//私有化SerialTool类的构造方法,不允许其他类生成SerialTool对象
private SerialTool() {}
public static SerialTool getSerialTool() {
if (serialTool == null) {
serialTool = new SerialTool();
}
return serialTool;
}
public static final List findPort() {
//获得当前所有可用串口
@SuppressWarnings("unchecked")
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
List portNameList = new ArrayList<>();
//将可用串口名添加到List并返回该List
while (portList.hasMoreElements()) {
String portName = portList.nextElement().getName();
portNameList.add(portName);
}
return portNameList;
}
public static final SerialPort openPort(String portName, int baudrate) throws UnsupportedCommOperationException, PortInUseException, NoSuchPortException {
//通过端口名识别端口
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
//打开端口,并给端口名字和一个timeout(打开操作的超时时间)
CommPort commPort = portIdentifier.open(portName, 2000);
//判断是不是串口
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
//设置一下串口的波特率等参数
serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
return serialPort;
}
return null;
}
public static void closePort(SerialPort serialPort) {
if (serialPort != null) {
serialPort.close();
serialPort = null;
}
}
public static void sendToPort(SerialPort serialPort, byte[] order) throws IOException {
OutputStream out = null;
out = serialPort.getOutputStream();
out.write(order);
out.flush();
out.close();
}
public static byte[] readFromPort(SerialPort serialPort) throws IOException {
InputStream in = null;
byte[] bytes = null;
try {
in = serialPort.getInputStream();
int bufflenth = in.available(); //获取buffer里的数据长度
while (bufflenth != 0) {
bytes = new byte[bufflenth]; //初始化byte数组为buffer中数据的长度
in.read(bytes);
bufflenth = in.available();
}
} catch (IOException e) {
throw e;
} finally {
if (in != null) {
in.close();
in = null;
}
}
return bytes;
}
public static void addListener(SerialPort port, SerialPortEventListener listener) throws TooManyListenersException {
//给串口添加监听器
port.addEventListener(listener);
//设置当有数据到达时唤醒监听接收线程
port.notifyonDataAvailable(true);
//设置当通信中断时唤醒中断线程
port.notifyonBreakInterrupt(true);
}
}
package serialPort;
import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TooManyListenersException;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.Jframe;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.Jtextarea;
import javax.swing.border.TitledBorder;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
public class SerialView extends Jframe {
private static final long serialVersionUID = 1L;
//设置window的icon
Toolkit toolKit = getToolkit();
Image icon = toolKit.getImage(SerialView.class.getResource("computer.png"));
DateTimeFormatter df= DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss.SSS");
private JComboBox commChoice;
private JComboBox bpsChoice;
private JButton openSerialButton;
private JButton sendButton;
private Jtextarea sendArea;
private Jtextarea receiveArea;
private JButton closeSerialButton;
private List commList = null; //保存可用端口号
private SerialPort serialPort = null; //保存串口对象
public SerialView() {
init();
TimerTask task = new TimerTask() {
@Override
public void run() {
commList = SerialTool.findPort(); //程序初始化时就扫描一次有效串口
//检查是否有可用串口,有则加入选项中
if (commList == null || commList.size()<1) {
JOptionPane.showMessageDialog(null, "没有搜索到有效串口!", "错误", JOptionPane.INFORMATION_MESSAGE);
}else{
commChoice.removeAllItems();
for (String s : commList) {
commChoice.addItem(s);
}
}
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, 0, 10000);
listen();
}
private void listen(){
//打开串口连接
openSerialButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//获取串口名称
String commName = (String) commChoice.getSelectedItem();
//获取波特率
String bpsStr = (String) bpsChoice.getSelectedItem();
//检查串口名称是否获取正确
if (commName == null || commName.equals("")) {
JOptionPane.showMessageDialog(null, "没有搜索到有效串口!", "错误", JOptionPane.INFORMATION_MESSAGE);
}else {
//检查波特率是否获取正确
if (bpsStr == null || bpsStr.equals("")) {
JOptionPane.showMessageDialog(null, "波特率获取错误!", "错误", JOptionPane.INFORMATION_MESSAGE);
}else {
//串口名、波特率均获取正确时
int bps = Integer.parseInt(bpsStr);
try {
//获取指定端口名及波特率的串口对象
serialPort = SerialTool.openPort(commName, bps);
SerialTool.addListener(serialPort, new SerialListener());
if(serialPort==null) return;
//在该串口对象上添加监听器
closeSerialButton.setEnabled(true);
sendButton.setEnabled(true);
openSerialButton.setEnabled(false);
String time=df.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.of("Asia/Shanghai")));
receiveArea.append(time+" ["+serialPort.getName().split("/")[3]+"] : "+" 连接成功..."+"rn");
receiveArea.setCaretPosition(receiveArea.getText().length());
} catch (UnsupportedCommOperationException | PortInUseException | NoSuchPortException | TooManyListenersException e1) {
e1.printStackTrace();
}
}
}
}
});
//发送数据
sendButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(!sendButton.isEnabled())return;
String message= sendArea.getText();
//"FE0400030001D5C5"
try {
SerialTool.sendToPort(serialPort, hex2byte(message));
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
//关闭串口连接
closeSerialButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(!closeSerialButton.isEnabled())return;
SerialTool.closePort(serialPort);
String time=df.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.of("Asia/Shanghai")));
receiveArea.append(time+" ["+serialPort.getName().split("/")[3]+"] : "+" 断开连接"+"rn");
receiveArea.setCaretPosition(receiveArea.getText().length());
openSerialButton.setEnabled(true);
closeSerialButton.setEnabled(false);
sendButton.setEnabled(false);
}
});
}
private void init() {
this.setBounds(WellcomView.LOC_X, WellcomView.LOC_Y, WellcomView.WIDTH, WellcomView.HEIGHT);
this.setTitle("串口调试");
this.setIconImage(icon);
this.setBackground(Color.gray);
this.setLayout(null);
Font font =new Font("微软雅黑", Font.BOLD, 16);
receiveArea=new Jtextarea(18, 30);
receiveArea.setEditable(false);
JScrollPane receiveScroll = new JScrollPane(receiveArea);
receiveScroll.setBorder(new TitledBorder("接收区"));
//滚动条自动出现 FE0400030001D5C5
receiveScroll.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
receiveScroll.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
receiveScroll.setBounds(52, 20, 680,340);
this.add(receiveScroll);
JLabel chuankou=new JLabel(" 串口选择: ");
chuankou.setFont(font);
chuankou.setBounds(50, 380, 100,50);
this.add(chuankou);
JLabel botelv=new JLabel(" 波 特 率: ");
botelv.setFont(font);
botelv.setBounds(290, 380, 100,50);
this.add(botelv);
//添加串口选择选项
commChoice = new JComboBox(); //串口选择(下拉框)
commChoice.setBounds(145, 390, 100, 30);
this.add(commChoice);
//添加波特率选项
bpsChoice = new JComboBox(); //波特率选择
bpsChoice.setBounds(380, 390, 100, 30);
bpsChoice.addItem("1500");
bpsChoice.addItem("2400");
bpsChoice.addItem("4800");
bpsChoice.addItem("9600");
bpsChoice.addItem("14400");
bpsChoice.addItem("19500");
bpsChoice.addItem("115500");
this.add(bpsChoice);
//添加打开串口按钮
openSerialButton = new JButton("连接");
openSerialButton.setBounds(540, 390, 80, 30);
openSerialButton.setFont(font);
openSerialButton.setForeground(Color.darkGray);
this.add(openSerialButton);
//添加关闭串口按钮
closeSerialButton = new JButton("关闭");
closeSerialButton.setEnabled(false);
closeSerialButton.setBounds(650, 390, 80, 30);
closeSerialButton.setFont(font);
closeSerialButton.setForeground(Color.darkGray);
this.add(closeSerialButton);
sendArea=new Jtextarea(30,20);
JScrollPane sendScroll = new JScrollPane(sendArea);
sendScroll.setBorder(new TitledBorder("发送区"));
//滚动条自动出现
sendScroll.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
sendScroll.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sendScroll.setBounds(52, 450, 500,100);
this.add(sendScroll);
sendButton = new JButton("发 送");
sendButton.setBounds(610, 520, 120, 30);
sendButton.setFont(font);
sendButton.setForeground(Color.darkGray);
sendButton.setEnabled(false);
this.add(sendButton);
this.setResizable(false); //窗口大小不可更改
this.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);
this.setVisible(true);
}
private byte[] hex2byte(String hex) {
String digital = "0123456789ABCDEF";
String hex1 = hex.replace(" ", "");
char[] hex2char = hex1.toCharArray();
byte[] bytes = new byte[hex1.length() / 2];
byte temp;
for (int p = 0; p < bytes.length; p++) {
temp = (byte) (digital.indexOf(hex2char[2 * p]) * 16);
temp += digital.indexOf(hex2char[2 * p + 1]);
bytes[p] = (byte) (temp & 0xff);
}
return bytes;
}
private String printHexString(byte[] b) {
StringBuffer sbf=new StringBuffer();
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sbf.append(hex.toUpperCase()+" ");
}
return sbf.toString().trim();
}
class SerialListener implements SerialPortEventListener {
public void serialEvent(SerialPortEvent serialPortEvent) {
switch (serialPortEvent.getEventType()) {
case SerialPortEvent.BI: // 10 通讯中断
JOptionPane.showMessageDialog(null, "与串口设备通讯中断", "错误", JOptionPane.INFORMATION_MESSAGE);
break;
case SerialPortEvent.OE: // 7 溢位(溢出)错误
break;
case SerialPortEvent.FE: // 9 帧错误
break;
case SerialPortEvent.PE: // 8 奇偶校验错误
break;
case SerialPortEvent.CD: // 6 载波检测
break;
case SerialPortEvent.CTS: // 3 清除待发送数据
break;
case SerialPortEvent.DSR: // 4 待发送数据准备好了
break;
case SerialPortEvent.RI: // 5 振铃指示
break;
case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 输出缓冲区已清空
break;
case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据
String time=df.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.of("Asia/Shanghai")));
byte[] data;//FE0400030001D5C5
try {
data = SerialTool.readFromPort(serialPort);
receiveArea.append(time+" ["+serialPort.getName().split("/")[3]+"] : "+ printHexString(data)+"rn");
receiveArea.setCaretPosition(receiveArea.getText().length());
} catch (IOException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}
}
package serialPort;
import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.Jframe;
import javax.swing.JLabel;
public class WellcomView {
public static final int WIDTH = 800;
public static final int HEIGHT = 620;
public static final int LOC_X = 200;
public static final int LOC_Y = 70;
private Jframe jframe;
public static void main(String[] args) {
new WellcomView();
}
public WellcomView() {
init();
listen();
}
private void listen() {
//添加键盘监听器
jframe.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_ENTER) { //当监听到用户敲击键盘enter键后执行下面的操作
jframe.setVisible(false); //隐去欢迎界面
new SerialView(); //主界面类(显示监控数据主面板)
}
}
});
}
private void init() {
jframe=new Jframe("串口调试");
jframe.setBounds(LOC_X, LOC_Y, WIDTH, HEIGHT); //设定程序在桌面出现的位置
jframe.setLayout(null);
//设置window的icon(这里我自定义了一下Windows窗口的icon图标,因为实在觉得哪个小咖啡图标不好看 = =)
Toolkit toolKit = jframe.getToolkit();
Image icon = toolKit.getImage(WellcomView.class.getResource("computer.png"));
jframe.setIconImage(icon);
jframe.setBackground(Color.white); //设置背景色
JLabel huanyin=new JLabel("欢迎使用串口调试工具");
huanyin.setBounds(170, 80,600,50);
huanyin.setFont(new Font("微软雅黑", Font.BOLD, 40));
jframe.add(huanyin);
JLabel banben=new JLabel("Version:1.0 Powered By:cyq");
banben.setBounds(180, 390,500,50);
banben.setFont(new Font("微软雅黑", Font.ITALIC, 26));
jframe.add(banben);
JLabel enter=new JLabel("————点击Enter键进入主界面————");
enter.setBounds(100, 480,600,50);
enter.setFont(new Font("微软雅黑", Font.BOLD, 30));
jframe.add(enter);
jframe.setResizable(false); //窗口大小不可更改
jframe.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);
jframe.setVisible(true); //显示窗口
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



