本文实例为大家分享了Java实现串口通信的具体代码,供大家参考,具体内容如下

1.介绍

使用Java实现的串口通信程序,支持十六进制数据的发送与接收。

源码:SerialPortDemo

效果图如下:

2.RXTXcomm

内含32位与64位版本

使用方法:

拷贝 RXTXcomm.jar 到 JAVA_HOMEjrelibext目录中;

拷贝 rxtxSerial.dll 到 JAVA_HOMEjrebin目录中;

拷贝 rxtxParallel.dll 到 JAVA_HOMEjrebin目录中;

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 findPort() {

// 获得当前所有可用串口

Enumeration portList = CommPortIdentifier

.getPortIdentifiers();

ArrayList portNameList = new ArrayList();

// 将可用串口名添加到List并返回该List

while (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 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() {

@Override

public void actionPerformed(ActionEvent e) {

if ("打开串口".equals(serialPortOperate.getText())

&& serialport == null) {

openSerialPort(e);

} else {

closeSerialPort(e);

}

}

});

sendData.addActionListener(new ActionListener() {

@Override

public 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("串口已打开" + "rn");

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("串口已关闭" + "rn");

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) + "rn");

}

} 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.写在最后

欢迎同学们吐槽评论,如果你觉得本篇博客对你有用,那么就留个言或者顶一下吧(^-^)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

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

  1. java生成随机6个数字和字母_java_Java生成含字母和数字的6位随机字符串,本文实例为大家分享了Java生成 - phpStudy...

    Java生成含字母和数字的6位随机字符串 本文实例为大家分享了Java生成6位随机字符串的实现代码,具体内容如下 package com.amos.tools; import java.util.Ar ...

  2. python学习-综合练习三(斐波那契数列、阿姆斯特朗数、//和/、十进制转二进制bin、八进制oct、十六进制hex、进制转换源码、python中::和:的区别)

    文章目录 斐波那契数列 阿姆斯特朗数 十进制转二进制bin.八进制oct.十六进制hex 补充进制转换源码 python中::和:的区别 说明:本篇博文的知识点大部分来自 Python3 实例 斐波那 ...

  3. php使用自定义alert,IOS_iOS自定义alertView提示框实例分享,本文实例为大家分享iOS自定义a - phpStudy...

    iOS自定义alertView提示框实例分享 本文实例为大家分享iOS自定义alertView提示框,先上图,弹框的背景色,按钮背景色,提示的消息的字体颜色都可以改变 利用单例实现丰富的自定义接口 / ...

  4. UCML-领先的B/S应用快速开发工具,基于组件重用和应用框架重用,支持.NET体系,直接生成C#源码;

    UCML-领先的B/S应用快速开发工具,基于组件重用和应用框架重用,支持.NET体系,直接生成C#源码:UCML涵盖了一个WEB应用系统业务开发的全过程,包括数据访问层(O/R映射)定义.业务框架开发 ...

  5. android 保险密码效果,本文实例为大家分享了android仿支付宝密码输入框展示的具体代码,供大家参考,具体内容如下这个没什么好分析的,就是一些基本的绘制什么线,矩形什么的,看代码更...

    本文实例为大家分享了android仿支付宝密码输入框展示的具体代码,供大家参考,具体内容如下 这个没什么好分析的,就是一些基本的绘制什么线,矩形什么的,看代码更具体 布局文件: android:lay ...

  6. macOS 音频编辑剪切软件源码支持mp3等格式(教程含源码)

    实战需求 macOS 音频编辑剪切软件源码支持mp3等格式(教程含源码) 本文价值与收获 看完本文后,您将能够作出下面的界面 看完本文您将掌握的技能 支持剪切音频 支持复制音频 支持删除音频 支持un ...

  7. 【LSTM时间序列数据】基于matlab LSTM时间序列数据预测【含Matlab源码 1949期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[LSTM时间序列数据]基于matlab LSTM时间序列数据预测[含Matlab源码 1949期] 获取代码方式2: 付费专栏Matla ...

  8. 74套大数据可视化大屏模板源码下载

    锦鲤已测|74套大数据可视化大屏模板源码下载,直接下载,使用浏览器访问静态页面即可. 最近在做一个市政的项目,用到了大数据可视化界面(装逼,无其他用途) 顺手分享一下给大家吧,有需要可以下载试试.

  9. python 抓取解析接口数据_[干货]用python抓取摩拜单车API数据并做可视化分析(源码)...

    原标题:[干货]用python抓取摩拜单车API数据并做可视化分析(源码) 在APP中能看到很多单车,但走到那里的时候,才发现车并不在那里.有些车不知道藏到了哪里:有些车或许是在高楼的后面,由于有GP ...

最新文章

  1. A Comprehensive Analysis of Sequence Alignment Algorithms for LongRead Sequencing
  2. ARP***原理与解决方法《一》
  3. 基本套接字总结(@function)
  4. 知乎高赞:这个开挂神器简直了!
  5. sql 查询优化小计
  6. 王国权辞任中国电信股份有限公司执行副总裁
  7. pip安装其他包报错
  8. mysql 循环 索引值,mysql:循环遍历表和alter table添加索引
  9. tensorflow 2.5.0 ( keras )搭建wgan-gp 和 div
  10. excel常用函数大全及示例(一)
  11. 计算机辅助设计和计算机动画,计算机辅助设计与制造(第2版)
  12. 基于Python实现的HTTP代理服务器设计
  13. 【Qt5】关于Qt5对xp的兼容说明
  14. 自媒体新人怎么写文章赚钱?哪个平台收益高?教你快速通过新手期!
  15. css中overflow属性失效,页面始终不能滚动显示溢出的内容
  16. 华为鸿蒙os状态栏,华为再推新版鸿蒙OS系统!UI外观设计大变样 多达19款机型可升级...
  17. 08第3周回顾:Sun成开源梦幻企业 甲骨文结束并购长征
  18. 计算机蓝屏故障一般在什么情况会发生,1、通过蓝屏信息找到故障根源 如果你的电脑经常遇到蓝屏的问题...
  19. ubuntu20.04设置xxxx_server为开机自启动服务
  20. 刚开始做 飞鸽传书2007 很兴奋

热门文章

  1. 花生壳动态域名解析工具原理
  2. HDOJ 1698 Just a Hook(线段树成段更新)
  3. Tellico-经管你的收藏品
  4. Zabbix 如何动态执行监控采集脚本
  5. 1 常用Windows命令大全
  6. Cannot connect to the database. –Error connecting to database.
  7. Linux经常使用到的操作
  8. HBuilder/Mui开发ios使用上拉刷新导致滚动条无法使用的解决方法
  9. Django中加载static无法成功的解决方法
  10. HttpClient连接池抛出大量ConnectionPoolTimeoutException: Timeout waiting for connection异常排查