1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 使用RXTX实现简单串口通信调试工具

使用RXTX实现简单串口通信调试工具

时间:2019-08-28 01:46:42

相关推荐

使用RXTX实现简单串口通信调试工具

最终效果如下图:

1、把rxtxParallel.dll、rxtxSerial.dll拷贝到:C:\WINDOWS\system32下。

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 mPort;import mPortIdentifier;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() {}/*** 获取提供服务的SerialTool对象* @return serialTool*/public static SerialTool getSerialTool() {if (serialTool == null) {serialTool = new SerialTool();}return serialTool;}/*** 查找所有可用端口* @return 可用端口名称列表*/public static final List<String> findPort() {//获得当前所有可用串口@SuppressWarnings("unchecked")Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();List<String> portNameList = new ArrayList<>();//将可用串口名添加到List并返回该Listwhile (portList.hasMoreElements()) {String portName = portList.nextElement().getName();portNameList.add(portName);}return portNameList;}/*** 打开串口* @param portName 端口名称* @param baudrate 波特率* @return 串口对象* @throws UnsupportedCommOperationException* @throws PortInUseException* @throws NoSuchPortException*/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;}/*** 关闭串口* @param serialport 待关闭的串口对象*/public static void closePort(SerialPort serialPort) {if (serialPort != null) {serialPort.close();serialPort = null;}}/*** 往串口发送数据* @param serialPort 串口对象* @param order待发送数据* @throws IOException */public static void sendToPort(SerialPort serialPort, byte[] order) throws IOException {OutputStream out = null;out = serialPort.getOutputStream();out.write(order);out.flush();out.close();}/*** 从串口读取数据* @param serialPort 当前已建立连接的SerialPort对象* @return 读取到的数据* @throws IOException */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;}/**添加监听器* @param port串口对象* @param listener 串口监听器* @throws TooManyListenersException */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;/*** 监测数据显示类* @author Zhong**/public class SerialView extends JFrame {/***/private static final long serialVersionUID = 1L;//设置window的iconToolkit toolKit = getToolkit();Image icon = toolKit.getImage(SerialView.class.getResource("computer.png"));DateTimeFormatter df= DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss.SSS");private JComboBox<String> commChoice;private JComboBox<String> bpsChoice;private JButton openSerialButton;private JButton sendButton;private JTextArea sendArea;private JTextArea receiveArea;private JButton closeSerialButton;private List<String> commList = null;//保存可用端口号private SerialPort serialPort = null;//保存串口对象/**类的构造方法* @param client*/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]+"] : "+" 连接成功..."+"\r\n");receiveArea.setCaretPosition(receiveArea.getText().length()); } catch (UnsupportedCommOperationException | PortInUseException | NoSuchPortException | TooManyListenersException e1) {e1.printStackTrace();}}}}});//发送数据sendButton.addMouseListener(new MouseAdapter() {@Overridepublic 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() {@Overridepublic 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]+"] : "+" 断开连接"+"\r\n");receiveArea.setCaretPosition(receiveArea.getText().length()); openSerialButton.setEnabled(true);closeSerialButton.setEnabled(false);sendButton.setEnabled(false);}});}/*** 主菜单窗口显示;* 添加JLabel、按钮、下拉条及相关事件监听;*/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("接收区"));//滚动条自动出现 FE0400030001D5C5receiveScroll.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<String>();//串口选择(下拉框)commChoice.setBounds(145, 390, 100, 30);this.add(commChoice);//添加波特率选项bpsChoice = new JComboBox<String>();//波特率选择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);}/**字符串转16进制* @param hex* @return*/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;}/**字节数组转16进制* @param b* @return*/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();}/*** 以内部类形式创建一个串口监听类* @author zhong*/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;//FE0400030001D5C5try {data = SerialTool.readFromPort(serialPort);receiveArea.append(time+" ["+serialPort.getName().split("/")[3]+"] : "+ printHexString(data)+"\r\n");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;/*** @author bh* 如果运行过程中抛出 java.lang.UnsatisfiedLinkError 错误,* 请将rxtx解压包中的 rxtxParallel.dll,rxtxSerial.dll 这两个文件复制到 C:\Windows\System32 目录下即可解决该错误。*/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;/**主方法* @param args//*/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);//显示窗口}}

无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。