使用Java實現串口通訊_java

來源:互聯網
上載者:User

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_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並返回該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<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() {   @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("串口已開啟" + "\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.寫在最後

源碼下載地址:http://download.csdn.net/detail/kong_gu_you_lan/9611343

歡迎同學們吐槽評論,如果你覺得本篇部落格對你有用,那麼就留個言或者頂一下吧(^-^)

感謝:http://www.jb51.net/article/100269.htm

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.