栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

使用Java实现串口通信

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Java实现串口通信

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

1.介绍

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

效果图如下:

2.RXTXcomm

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

内含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;


public class SerialPortManager {

 
 @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;
 }

 
 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();
 }
 }

 
 public static void closePort(SerialPort serialPort) {
 if (serialPort != null) {
  serialPort.close();
  serialPort = null;
 }
 }

 
 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();
  }
 }
 }

 
 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;
 }

 
 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.程序主窗口



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;


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);
  }
 });
 }

 
 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();
 }
 }

 
 private void closeSerialPort(java.awt.event.ActionEvent evt) {
 SerialPortManager.closePort(serialport);
 dataView.setText("串口已关闭" + "rn");
 serialPortOperate.setText("打开串口");
 }

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

源码下载地址:SerialPortDemo

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

感谢:基于Java编写串口通信工具

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/148386.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号