最新版程序请查看 《使用Java实现串口通信(二)》

1.介绍

使用Java实现的串口通信程序,支持十六进制数据的发送与接收。
源码下载地址:http://download.csdn.net/download/kong_gu_you_lan/10015803
效果图如下:

2.RXTXcomm

Java串口通信依赖的jar包RXTXcomm.jar
下载地址:http://download.csdn.net/detail/kong_gu_you_lan/9611334

内含32位与64位版本
使用方法:
拷贝 RXTXcomm.jar 到 JAVA_HOME\jre\lib\ext目录中;
拷贝 rxtxSerial.dll 到 JAVA_HOME\jre\bin目录中;
拷贝 rxtxParallel.dll 到 JAVA_HOME\jre\bin目录中;
JAVA_HOME为jdk安装路径

3.串口通信管理

SerialPortManager实现了对串口通信的管理,包括查找可用端口、打开关闭串口、发送接收数据。

package com.yang.serialport.manage;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;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.TooManyListenersException;import com.yang.serialport.exception.NoSuchPort;
import com.yang.serialport.exception.NotASerialPort;
import com.yang.serialport.exception.PortInUse;
import com.yang.serialport.exception.ReadDataFromSerialPortFailure;
import com.yang.serialport.exception.SendDataToSerialPortFailure;
import com.yang.serialport.exception.SerialPortInputStreamCloseFailure;
import com.yang.serialport.exception.SerialPortOutputStreamCloseFailure;
import com.yang.serialport.exception.SerialPortParameterFailure;
import com.yang.serialport.exception.TooManyListeners;/*** 串口管理* * @author yangle*/
public class SerialPortManager {/*** 查找所有可用端口* * @return 可用端口名称列表*/@SuppressWarnings("unchecked")public static final ArrayList<String> findPort() {// 获得当前所有可用串口Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();ArrayList<String> portNameList = new ArrayList<String>();// 将可用串口名添加到List并返回该Listwhile (portList.hasMoreElements()) {String portName = portList.nextElement().getName();portNameList.add(portName);}return portNameList;}/*** 打开串口* * @param portName*            端口名称* @param baudrate*            波特率* @return 串口对象* @throws SerialPortParameterFailure*             设置串口参数失败* @throws NotASerialPort*             端口指向设备不是串口类型* @throws NoSuchPort*             没有该端口对应的串口设备* @throws PortInUse*             端口已被占用*/public static final SerialPort openPort(String portName, int baudrate)throws SerialPortParameterFailure, NotASerialPort, NoSuchPort,PortInUse {try {// 通过端口名识别端口CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);// 打开端口,设置端口名与timeout(打开操作的超时时间)CommPort commPort = portIdentifier.open(portName, 2000);// 判断是不是串口if (commPort instanceof SerialPort) {SerialPort serialPort = (SerialPort) commPort;try {// 设置串口的波特率等参数serialPort.setSerialPortParams(baudrate,SerialPort.DATABITS_8, SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);} catch (UnsupportedCommOperationException e) {throw new SerialPortParameterFailure();}return serialPort;} else {// 不是串口throw new NotASerialPort();}} catch (NoSuchPortException e1) {throw new NoSuchPort();} catch (PortInUseException e2) {throw new PortInUse();}}/*** 关闭串口* * @param serialport*            待关闭的串口对象*/public static void closePort(SerialPort serialPort) {if (serialPort != null) {serialPort.close();serialPort = null;}}/*** 向串口发送数据* * @param serialPort*            串口对象* @param order*            待发送数据* @throws SendDataToSerialPortFailure*             向串口发送数据失败* @throws SerialPortOutputStreamCloseFailure*             关闭串口对象的输出流出错*/public static void sendToPort(SerialPort serialPort, byte[] order)throws SendDataToSerialPortFailure,SerialPortOutputStreamCloseFailure {OutputStream out = null;try {out = serialPort.getOutputStream();out.write(order);out.flush();} catch (IOException e) {throw new SendDataToSerialPortFailure();} finally {try {if (out != null) {out.close();out = null;}} catch (IOException e) {throw new SerialPortOutputStreamCloseFailure();}}}/*** 从串口读取数据* * @param serialPort*            当前已建立连接的SerialPort对象* @return 读取到的数据* @throws ReadDataFromSerialPortFailure*             从串口读取数据时出错* @throws SerialPortInputStreamCloseFailure*             关闭串口对象输入流出错*/public static byte[] readFromPort(SerialPort serialPort)throws ReadDataFromSerialPortFailure,SerialPortInputStreamCloseFailure {InputStream in = null;byte[] bytes = null;try {in = serialPort.getInputStream();// 获取buffer里的数据长度int bufflenth = in.available();while (bufflenth != 0) {// 初始化byte数组为buffer中数据的长度bytes = new byte[bufflenth];in.read(bytes);bufflenth = in.available();}} catch (IOException e) {throw new ReadDataFromSerialPortFailure();} finally {try {if (in != null) {in.close();in = null;}} catch (IOException e) {throw new SerialPortInputStreamCloseFailure();}}return bytes;}/*** 添加监听器* * @param port*            串口对象* @param listener*            串口监听器* @throws TooManyListeners*             监听类对象过多*/public static void addListener(SerialPort port,SerialPortEventListener listener) throws TooManyListeners {try {// 给串口添加监听器port.addEventListener(listener);// 设置当有数据到达时唤醒监听接收线程port.notifyOnDataAvailable(true);// 设置当通信中断时唤醒中断线程port.notifyOnBreakInterrupt(true);} catch (TooManyListenersException e) {throw new TooManyListeners();}}
}

4.程序主窗口

/** MainFrame.java** Created on 2016.8.19*/package com.yang.serialport.ui;import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;import java.awt.Color;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;import com.yang.serialport.exception.NoSuchPort;
import com.yang.serialport.exception.NotASerialPort;
import com.yang.serialport.exception.PortInUse;
import com.yang.serialport.exception.SendDataToSerialPortFailure;
import com.yang.serialport.exception.SerialPortOutputStreamCloseFailure;
import com.yang.serialport.exception.SerialPortParameterFailure;
import com.yang.serialport.exception.TooManyListeners;
import com.yang.serialport.manage.SerialPortManager;
import com.yang.serialport.utils.ByteUtils;
import com.yang.serialport.utils.ShowUtils;/*** 主界面* * @author yangle*/
public class MainFrame extends JFrame {/*** 程序界面宽度*/public static final int WIDTH = 500;/*** 程序界面高度*/public static final int HEIGHT = 360;private JTextArea dataView = new JTextArea();private JScrollPane scrollDataView = new JScrollPane(dataView);// 串口设置面板private JPanel serialPortPanel = new JPanel();private JLabel serialPortLabel = new JLabel("串口");private JLabel baudrateLabel = new JLabel("波特率");private JComboBox commChoice = new JComboBox();private JComboBox baudrateChoice = new JComboBox();// 操作面板private JPanel operatePanel = new JPanel();private JTextField dataInput = new JTextField();private JButton serialPortOperate = new JButton("打开串口");private JButton sendData = new JButton("发送数据");private List<String> commList = null;private SerialPort serialport;public MainFrame() {initView();initComponents();actionListener();initData();}private void initView() {// 关闭程序setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);// 禁止窗口最大化setResizable(false);// 设置程序窗口居中显示Point p = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();setBounds(p.x - WIDTH / 2, p.y - HEIGHT / 2, WIDTH, HEIGHT);this.setLayout(null);setTitle("串口通讯");}private void initComponents() {// 数据显示dataView.setFocusable(false);scrollDataView.setBounds(10, 10, 475, 200);add(scrollDataView);// 串口设置serialPortPanel.setBorder(BorderFactory.createTitledBorder("串口设置"));serialPortPanel.setBounds(10, 220, 170, 100);serialPortPanel.setLayout(null);add(serialPortPanel);serialPortLabel.setForeground(Color.gray);serialPortLabel.setBounds(10, 25, 40, 20);serialPortPanel.add(serialPortLabel);commChoice.setFocusable(false);commChoice.setBounds(60, 25, 100, 20);serialPortPanel.add(commChoice);baudrateLabel.setForeground(Color.gray);baudrateLabel.setBounds(10, 60, 40, 20);serialPortPanel.add(baudrateLabel);baudrateChoice.setFocusable(false);baudrateChoice.setBounds(60, 60, 100, 20);serialPortPanel.add(baudrateChoice);// 操作operatePanel.setBorder(BorderFactory.createTitledBorder("操作"));operatePanel.setBounds(200, 220, 285, 100);operatePanel.setLayout(null);add(operatePanel);dataInput.setBounds(25, 25, 235, 20);operatePanel.add(dataInput);serialPortOperate.setFocusable(false);serialPortOperate.setBounds(45, 60, 90, 20);operatePanel.add(serialPortOperate);sendData.setFocusable(false);sendData.setBounds(155, 60, 90, 20);operatePanel.add(sendData);}@SuppressWarnings("unchecked")private void initData() {commList = SerialPortManager.findPort();// 检查是否有可用串口,有则加入选项中if (commList == null || commList.size() < 1) {ShowUtils.warningMessage("没有搜索到有效串口!");} else {for (String s : commList) {commChoice.addItem(s);}}baudrateChoice.addItem("9600");baudrateChoice.addItem("19200");baudrateChoice.addItem("38400");baudrateChoice.addItem("57600");baudrateChoice.addItem("115200");}private void actionListener() {serialPortOperate.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if ("打开串口".equals(serialPortOperate.getText())&& serialport == null) {openSerialPort(e);} else {closeSerialPort(e);}}});sendData.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {sendData(e);}});}/*** 打开串口* * @param evt*            点击事件*/private void openSerialPort(java.awt.event.ActionEvent evt) {// 获取串口名称String commName = (String) commChoice.getSelectedItem();// 获取波特率int baudrate = 9600;String bps = (String) baudrateChoice.getSelectedItem();baudrate = Integer.parseInt(bps);// 检查串口名称是否获取正确if (commName == null || commName.equals("")) {ShowUtils.warningMessage("没有搜索到有效串口!");} else {try {serialport = SerialPortManager.openPort(commName, baudrate);if (serialport != null) {dataView.setText("串口已打开" + "\r\n");serialPortOperate.setText("关闭串口");}} catch (SerialPortParameterFailure e) {e.printStackTrace();} catch (NotASerialPort e) {e.printStackTrace();} catch (NoSuchPort e) {e.printStackTrace();} catch (PortInUse e) {e.printStackTrace();ShowUtils.warningMessage("串口已被占用!");}}try {SerialPortManager.addListener(serialport, new SerialListener());} catch (TooManyListeners e) {e.printStackTrace();}}/*** 关闭串口* * @param evt*            点击事件*/private void closeSerialPort(java.awt.event.ActionEvent evt) {SerialPortManager.closePort(serialport);dataView.setText("串口已关闭" + "\r\n");serialPortOperate.setText("打开串口");}/*** 发送数据* * @param evt*            点击事件*/private void sendData(java.awt.event.ActionEvent evt) {// 输入框直接输入十六进制字符,长度必须是偶数String data = dataInput.getText().toString();try {SerialPortManager.sendToPort(serialport,ByteUtils.hexStr2Byte(data));} catch (SendDataToSerialPortFailure e) {e.printStackTrace();} catch (SerialPortOutputStreamCloseFailure e) {e.printStackTrace();}}private class SerialListener implements SerialPortEventListener {/*** 处理监控到的串口事件*/public void serialEvent(SerialPortEvent serialPortEvent) {switch (serialPortEvent.getEventType()) {case SerialPortEvent.BI: // 10 通讯中断ShowUtils.errorMessage("与串口设备通讯中断");break;case SerialPortEvent.OE: // 7 溢位(溢出)错误case SerialPortEvent.FE: // 9 帧错误case SerialPortEvent.PE: // 8 奇偶校验错误case SerialPortEvent.CD: // 6 载波检测case SerialPortEvent.CTS: // 3 清除待发送数据case SerialPortEvent.DSR: // 4 待发送数据准备好了case SerialPortEvent.RI: // 5 振铃指示case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 输出缓冲区已清空break;case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据byte[] data = null;try {if (serialport == null) {ShowUtils.errorMessage("串口对象为空!监听失败!");} else {// 读取串口数据data = SerialPortManager.readFromPort(serialport);dataView.append(ByteUtils.byteArrayToHexString(data,true) + "\r\n");}} catch (Exception e) {ShowUtils.errorMessage(e.toString());// 发生读取错误时显示错误信息后退出系统System.exit(0);}break;}}}public static void main(String args[]) {java.awt.EventQueue.invokeLater(new Runnable() {public void run() {new MainFrame().setVisible(true);}});}
}

5.最后

Demo下载

GitHub下载地址

转载大神文章 @容华谢后

java实现串口通信 485协议相关推荐

  1. Java实现串口通信的小样例

    用Java实现串口通信(windows系统下),须要用到sun提供的串口包 javacomm20-win32.zip.当中要用到三个文件,配置例如以下: 1.comm.jar放置到 JAVA_HOME ...

  2. java串口发送十六进制数,本文实例为大家分享了Java实现串口通信的具体代码,供大家参考,具体内容如下1.介绍使用Java实现的串口通信程序,支持十六进制数据的发送与接收。 源码:...

    本文实例为大家分享了Java实现串口通信的具体代码,供大家参考,具体内容如下 1.介绍 使用Java实现的串口通信程序,支持十六进制数据的发送与接收. 源码:SerialPortDemo 效果图如下: ...

  3. java 采用串口通信实现LED屏发送数据中文乱码问题

    java 采用串口通信实现LED屏发送数据中文乱码问题 1.定义:Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(1024)) ...

  4. Java实现串口通信的小例子

    用Java实现串口通信(windows系统下),需要用到sun提供的串口包 javacomm20-win32.zip.其中要用到三个文件,配置如下: 1.comm.jar放置到 JAVA_HOME/j ...

  5. 基于java的串口通信

    文章目录 前言 一.RXTX是什么? 二.环境搭建 引入库 三.代码实现 SerialPortManager类 Tools类 重要代码解析 读取数据 写数据 写EPC号 询查单张标签 CRC校验 测试 ...

  6. 使用Java实现串口通信(二)

    1.写在前面 距离上一篇文章<使用Java实现串口通信>已经过去快两年的时间了,在此期间收到了很多读者的反馈,很高兴可以帮助到这么多人,根据收到的反馈,我对代码逻辑进行了优化整理,并增加了 ...

  7. stm32板间串口通信escape协议

    最近有使用串口的需求,用于两块板间的TTL串口通信,目前常见的串口通信协议可以归纳为两种模式 使用串口和一个定时器的通信协议[严格限制时间,常见协议为Modbus RTU] 使用单个串口的通信协议[存 ...

  8. Java 如何串口通信以及常见报错解决

    文章目录 一.Java 串口通信部署 准备 部署 1. 配置 Java 环境 2. 新建项目,引入依赖. 3. 代码(网上荡的) 运行 二.Java 串口通信报错 1. JDK 有关错误 2. dll ...

  9. java 连接 usb串口_树莓派 3 java usb串口通讯485

    0 参考链接 https://blog.csdn.net/qq_43725844/article/details/97682424 https://blog.csdn.net/fhqlongteng/ ...

  10. Java通过串口通信实现温度监测

    开发环境  JDK1.8 + Rxtx2.1.7 + Eclipse 一: 首先,你需要下载一个额外的支持Java串口通信操作的jar包,由于java.comm比较老了,而且不支持64位系统,这里推荐 ...

最新文章

  1. super返回不过来
  2. 广东深圳计算机学校排名2015年,2015年深圳小学综合排名 各区小学最新排名
  3. 【深度学习】深度学习在视觉搜索和匹配中的应用
  4. i节点详解以及软连接和硬链接的区别
  5. 我的专业博客启动了!
  6. supersocket缓冲区_使用Socket从Client传输文件到Server对文件缓冲区大小有限制么?...
  7. 使用file_get_contents下载图片
  8. Spring IOC的三种主要注入方式?
  9. WindowsXP、Windows2003本地密码清除方法
  10. Redis的lua脚本
  11. 《Using OpenRefine》翻译~2
  12. 网络工程师考试历年真题汇总及教程第5版pdf
  13. 微信小程序的服务器有什么要求
  14. 船讯网|爬虫COOKIE重定向反爬处理
  15. Linux之python版本升级
  16. 老王卖西瓜python_python 老王装货
  17. 常用的curl命令及参数详解
  18. 公众号接收用户消息—《微信公众平台开发实战与应用案例》—陈小龙
  19. here-document at line 40 delimited by end-of-file (wanted `EOF‘)
  20. 2021年如何选购华强北AirPods(一次翻车到下车的经历总结的经验)

热门文章

  1. 非线性光纤光学相关学习
  2. 求解平稳分布matlab,生灭过程的拟平稳分布
  3. 2020,ToB 生态全景解读
  4. EverNote 极致的免费笔记资料管理软件 (数据网络同步、支持PC、Mac与手机多平台) 转自:http://www.iplaysoft.com/evernote.html
  5. Ubuntu 16.04-codeblocks 汉化
  6. 用计算机发传真,用电脑怎么发传真
  7. blp和biba属于哪种访问控制_技术分享 | 访问控制在工控安全中的应用
  8. CFA2019notes的PDF版本,热乎乎的百度网盘分享
  9. lavas一定是个不错的架构,利用VUE的PWA。是否可以取代APP?
  10. ros pppoe服务器性能,ROS软路由中最详细的PPPOE服务器设置教程