使用Java实现简单串口通信

本博文参考自https://www.jb51.net/article/100269.htm

www.jb51.net/article/100269.htm

没想到挺多人需要这个的,很高兴这篇文章能对大家有帮助,主要的工具类博文里已经有了,当然,要小工具源码的留言邮箱即可。 2019.09.05

最近接触到了串口及其读写,在此记录java进行串口读写的过程。

1.导入支持java串口通信的jar包:

在maven项目的pom.xml中添加RXTXcomm的依赖 或者 下载RXTXcomm.jar并导入到项目中。

支持Java串口通信操作的jar包,java.comm比较老,而且不支持64位系统,推荐使用Rxtx这个jar包(32位/64位均支持)。

下载地址:

http://xiazai.jb51.net/201612/yuanma/javamfzrxtx(jb51.net).rar(32位)

http://xiazai.jb51.net/201612/yuanma/javamfzrxtx(jb51.net).rar(64位)

注意:运行过程中抛出java.lang.UnsatisfiedLinkError错误或gnu.io下的类找不到时,将rxtx解压包中的rxtxParallel.dll,rxtxSerial.dll 这两个文件复制到C:\Windows\System32 目录下可解决该错误。

2.编写代码操作串口:

串口必要参数类:包含连接串口所必须的参数,方便在调用串口时设置和传递串口参数

/**
 * 串口必要参数接收类
 * @author: LinWenLi
 * @date: 2018年7月21日 下午4:30:40
 */
public class ParamConfig {

 private String serialNumber;// 串口号
 private int baudRate; // 波特率
 private int checkoutBit; // 校验位
 private int dataBit; // 数据位
 private int stopBit; // 停止位

 public ParamConfig() {}

 /**
 * 构造方法
 * @param serialNumber 串口号
 * @param baudRate 波特率
 * @param checkoutBit 校验位
 * @param dataBit 数据位
 * @param stopBit 停止位
 */
 public ParamConfig(String serialNumber, int baudRate, int checkoutBit, int dataBit, int stopBit) {
 this.serialNumber = serialNumber;
 this.baudRate = baudRate;
 this.checkoutBit = checkoutBit;
 this.dataBit = dataBit;
 this.stopBit = stopBit;
 }
 getter()...
 setter()...
}

串口操作类:(其中包含的CustomException是自定义异常类,仅用于抛出异常原因。)

import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

/**
 * 串口参数的配置 串口一般有如下参数可以在该串口打开以前进行配置: 包括串口号,波特率,输入/输出流控制,数据位数,停止位和奇偶校验。
 */
// 注:串口操作类一定要继承SerialPortEventListener
public class SerialPortUtils implements SerialPortEventListener {
 // 检测系统中可用的通讯端口类
 private CommPortIdentifier commPortId;
 // 枚举类型
 private Enumeration<CommPortIdentifier> portList;
 // RS232串口
 private SerialPort serialPort;
 // 输入流
 private InputStream inputStream;
 // 输出流
 private OutputStream outputStream;
 // 保存串口返回信息
 private String data;
 // 保存串口返回信息十六进制
 private String dataHex;/**
 * 初始化串口
 * @author LinWenLi
 * @date 2018年7月21日下午3:44:16
 * @Description: TODO
 * @param: paramConfig 存放串口连接必要参数的对象(会在下方给出类代码)
 * @return: void
 * @throws
 */
 @SuppressWarnings("unchecked")
 public void init(ParamConfig paramConfig) {
 // 获取系统中所有的通讯端口
 portList = CommPortIdentifier.getPortIdentifiers();
 // 记录是否含有指定串口
 boolean isExsist = false;
 // 循环通讯端口
 while (portList.hasMoreElements()) {
  commPortId = portList.nextElement();
  // 判断是否是串口
  if (commPortId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
  // 比较串口名称是否是指定串口
  if (paramConfig.getSerialNumber().equals(commPortId.getName())) {
   // 串口存在
   isExsist = true;
   // 打开串口
   try {
   // open:(应用程序名【随意命名】,阻塞时等待的毫秒数)
   serialPort = (SerialPort) commPortId.open(Object.class.getSimpleName(), 2000);
   // 设置串口监听
   serialPort.addEventListener(this);
   // 设置串口数据时间有效(可监听)
   serialPort.notifyOnDataAvailable(true);
   // 设置串口通讯参数:波特率,数据位,停止位,校验方式
   serialPort.setSerialPortParams(paramConfig.getBaudRate(), paramConfig.getDataBit(),
    paramConfig.getStopBit(), paramConfig.getCheckoutBit());
   } catch (PortInUseException e) {
   throw new CustomException("端口被占用");
   } catch (TooManyListenersException e) {
   throw new CustomException("监听器过多");
   } catch (UnsupportedCommOperationException e) {
   throw new CustomException("不支持的COMM端口操作异常");
   }
   // 结束循环
   break;
  }
  }
 }
 // 若不存在该串口则抛出异常
 if (!isExsist) {
  throw new CustomException("不存在该串口!");
 }
 }

 /**
 * 实现接口SerialPortEventListener中的方法 读取从串口中接收的数据
 */
 @Override
 public void serialEvent(SerialPortEvent event) {
 switch (event.getEventType()) {
 case SerialPortEvent.BI: // 通讯中断
 case SerialPortEvent.OE: // 溢位错误
 case SerialPortEvent.FE: // 帧错误
 case SerialPortEvent.PE: // 奇偶校验错误
 case SerialPortEvent.CD: // 载波检测
 case SerialPortEvent.CTS: // 清除发送
 case SerialPortEvent.DSR: // 数据设备准备好
 case SerialPortEvent.RI: // 响铃侦测
 case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 输出缓冲区已清空
  break;
 case SerialPortEvent.DATA_AVAILABLE: // 有数据到达
  // 调用读取数据的方法
  readComm();
  break;
 default:
  break;
 }
 }

 /**
 * 读取串口返回信息
 * @author LinWenLi
 * @date 2018年7月21日下午3:43:04
 * @return: void
 */
 public void readComm() {
 try {
  inputStream = serialPort.getInputStream();
  // 通过输入流对象的available方法获取数组字节长度
  byte[] readBuffer = new byte[inputStream.available()];
  // 从线路上读取数据流
  int len = 0;
  while ((len = inputStream.read(readBuffer)) != -1) {         // 直接获取到的数据
  data = new String(readBuffer, 0, len).trim();         // 转为十六进制数据
  dataHex = bytesToHexString(readBuffer);
  System.out.println("data:" + data);
  System.out.println("dataHex:" + dataHex);// 读取后置空流对象
  inputStream.close();
  inputStream = null;
  break;
  }
 } catch (IOException e) {
  throw new CustomException("读取串口数据时发生IO异常");
 }
 }

 /**
 * 发送信息到串口
 * @author LinWenLi
 * @date 2018年7月21日下午3:45:22
 * @param: data
 * @return: void
 * @throws
 */
 public void sendComm(String data) {
 byte[] writerBuffer = null;
 try {
  writerBuffer = hexToByteArray(data);
 } catch (NumberFormatException e) {
  throw new CustomException("命令格式错误!");
 }
 try {
  outputStream = serialPort.getOutputStream();
  outputStream.write(writerBuffer);
  outputStream.flush();
 } catch (NullPointerException e) {
  throw new CustomException("找不到串口。");
 } catch (IOException e) {
  throw new CustomException("发送信息到串口时发生IO异常");
 }
 }

 /**
 * 关闭串口
 * @author LinWenLi
 * @date 2018年7月21日下午3:45:43
 * @Description: 关闭串口
 * @param:
 * @return: void
 * @throws
 */
 public void closeSerialPort() {
 if (serialPort != null) {
  serialPort.notifyOnDataAvailable(false);
  serialPort.removeEventListener();
  if (inputStream != null) {
  try {
   inputStream.close();
   inputStream = null;
  } catch (IOException e) {
   throw new CustomException("关闭输入流时发生IO异常");
  }
  }
  if (outputStream != null) {
  try {
   outputStream.close();
   outputStream = null;
  } catch (IOException e) {
   throw new CustomException("关闭输出流时发生IO异常");
  }
  }
  serialPort.close();
  serialPort = null;
 }
 }

 /**
 * 十六进制串口返回值获取
 */
 public String getDataHex() {
 String result = dataHex;
 // 置空执行结果
 dataHex = null;
 // 返回执行结果
 return result;
 }

 /**
 * 串口返回值获取
 */
 public String getData() {
 String result = data;
 // 置空执行结果
 data = null;
 // 返回执行结果
 return result;
 }

 /**
 * Hex字符串转byte
 * @param inHex 待转换的Hex字符串
 * @return 转换后的byte
 */
 public static byte hexToByte(String inHex) {
 return (byte) Integer.parseInt(inHex, 16);
 }

 /**
 * hex字符串转byte数组
 * @param inHex 待转换的Hex字符串
 * @return 转换后的byte数组结果
 */
 public static byte[] hexToByteArray(String inHex) {
 int hexlen = inHex.length();
 byte[] result;
 if (hexlen % 2 == 1) {
  // 奇数
  hexlen++;
  result = new byte[(hexlen / 2)];
  inHex = "0" + inHex;
 } else {
  // 偶数
  result = new byte[(hexlen / 2)];
 }
 int j = 0;
 for (int i = 0; i < hexlen; i += 2) {
  result[j] = hexToByte(inHex.substring(i, i + 2));
  j++;
 }
 return result;
 }

 /**
 * 数组转换成十六进制字符串
 * @param byte[]
 * @return HexString
 */
 public static final String bytesToHexString(byte[] bArray) {
 StringBuffer sb = new StringBuffer(bArray.length);
 String sTemp;
 for (int i = 0; i < bArray.length; i++) {
  sTemp = Integer.toHexString(0xFF & bArray[i]);
  if (sTemp.length() < 2)
  sb.append(0);
  sb.append(sTemp.toUpperCase());
 }
 return sb.toString();
 }
}

调用串口操作类的代码:

public static void main(String[] args) {
  // 实例化串口操作类对象
  SerialPortUtils serialPort = new SerialPortUtils();
  // 创建串口必要参数接收类并赋值,赋值串口号,波特率,校验位,数据位,停止位
  ParamConfig paramConfig = new ParamConfig("COM4", 9600, 0, 8, 1);
  // 初始化设置,打开串口,开始监听读取串口数据
  serialPort.init(paramConfig);
  // 调用串口操作类的sendComm方法发送数据到串口
  serialPort.sendComm("FEF10A000000000000000AFF");
  // 关闭串口
  serialPort.closeSerialPort();
 }

当执行main方法中的代码且未执行关闭串口时,程序将一直处于开启状态,自动监听,接收读取来自串口的数据。

注意:一个串口只能打开一次,并只支持一个程序调用。

以上所记录的是简单测试java是否能成功操作串口数据,至于本人所写的Web端的读卡器调试功能则是在串口操作类的基础上编写网页界面,通过请求来控制串口的开启关闭及相应的设置,功能比较简单,放个界面记录一下:

到此这篇关于使用Java实现简单串口通信的文章就介绍到这了,更多相关Java实现简单串口通信内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于Java编写串口通信工具

    最近一门课要求编写一个上位机串口通信工具,我基于Java编写了一个带有图形界面的简单串口通信工具,下面详述一下过程,供大家参考 ^_^ 一: 首先,你需要下载一个额外的支持Java串口通信操作的jar包,由于java.comm比较老了,而且不支持64位系统,这里推荐Rxtx这个jar包(32位/64位均支持). 官方下载地址:http://fizzed.com/oss/rxtx-for-java (注:可能需要FQ才能下载) 不能FQ的童鞋,可以在这里下载: http://xiazai.jb51

  • Java实现的串口通信功能示例

    本文实例讲述了Java实现的串口通信功能.分享给大家供大家参考,具体如下: 用Java实现串口通信(windows系统下),需要用到sun提供的串口包 javacomm20-win32.zip.其中要用到三个文件,配置如下: 1.comm.jar放置到 JAVA_HOME/jre/lib/ext; 2.win32com.dll放置到 JAVA_HOME/bin; 3.javax.comm.properties 两个地方都要放     jre/lib(也就是在JAVA文件夹下的jre)    JA

  • 使用Java实现串口通信

    1.介绍 使用Java实现的串口通信程序,支持十六进制数据的发送与接收. 源码下载地址:http://download.csdn.net/detail/kong_gu_you_lan/9611343 效果图如下: 2.RXTXcomm Java串口通信依赖的jar包RXTXcomm.jar 下载地址:http://download.csdn.net/detail/kong_gu_you_lan/9611334 内含32位与64位版本 使用方法: 拷贝 RXTXcomm.jar 到 JAVA_HO

  • java 串口通信实现流程示例

    1.下载64位rxtx for java 链接:http://fizzed.com/oss/rxtx-for-java 2.下载下来的包解压后按照说明放到JAVA_HOME即JAVA的安装路径下面去 3.在maven的pom.xml下添加 <dependency> <groupId>org.rxtx</groupId> <artifactId>rxtx</artifactId> <version>2.1.7</version&g

  • java 串口通信详细及简单实例

    java 实现串口通信 最近做了一个与硬件相关的项目,刚开始听说用java和硬件打交道,着实下了一大跳.java也可以操作硬件? 后来接触到是用java通过串口通信控制硬件感觉使用起来还不错,也很方便. 特拿出来和大家一起分享一下. 准备工作: 首先到SUN官网下载一个zip包:javacomm20-win32.zip 其中重要的有这几个文件: win32com.dll comm.jar javax.comm.properties 按照说明配置好环境,如下: 将win32com.dll复制到<J

  • java使用Rxtx实现串口通信调试工具

    本文实例为大家分享了java使用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

  • 使用Java实现简单串口通信

    本博文参考自https://www.jb51.net/article/100269.htm www.jb51.net/article/100269.htm 没想到挺多人需要这个的,很高兴这篇文章能对大家有帮助,主要的工具类博文里已经有了,当然,要小工具源码的留言邮箱即可. 2019.09.05 最近接触到了串口及其读写,在此记录java进行串口读写的过程. 1.导入支持java串口通信的jar包: 在maven项目的pom.xml中添加RXTXcomm的依赖 或者 下载RXTXcomm.jar并

  • Java 实现简单Socket 通信的示例

    目录 1. 传输层协议 2. TCP 示例 2.1 示例效果 2.2 服务端程序代码 3. UDP 示例 3.1 服务端程序代码 3.2 客户端程序代码 Java socket 封装了传输层的实现细节,开发人员可以基于 socket 实现应用层.本文介绍了 Java socket 简单用法. 1. 传输层协议 传输层包含了两种协议,分别是 TCP (Transmission Control Protocol,传输控制协议) 和 UDP (User Datagram Protocol,用户数据报协

  • C#实现简单串口通信

    串口通信(Serial Communications)是指外设和计算机间通过数据信号线.地线等按位(bit)进行传输数据的一种通信方式,属于串行通信方式,能够实现远距离通信,长度可达1200米.尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据.串口通信最重要的参数是波特率.数据位.停止位和奇偶校验.对于两个进行通信的端口,这些参数必须匹配. 串口通信的接口标准有很多,有 RS-232C.RS-232.RS-422A.RS-485 等.常用的就是 RS

  • Python3简单实现串口通信的方法

    如下所示: import serial import sys import os import time import re def wait_for_cmd_OK():     while True:         line = ser.readline()         try:             print(line.decode('utf-8'),end='')         except:             pass         if ( re.search(b'

随机推荐