java 与串口通讯

10-15 1871人

package com.fota.serial;

import gnu.io.*;

import java.io.*;
import java.util.*;

import com.fota.util.Bytes;

public class SerialUtil extends Observable implements SerialPortEventListener {
 InputStream inputStream;
 OutputStream outputStream;
 static SerialPort serialPort;
 // 端口是否打开了
 boolean isOpen = false;
 // 端口读入数据事件触发后,等待n毫秒后再读取,以便让数据一次性读完
 Object readWriteLock = new Object();
 private SerialCallBack serialCallBack;

 public boolean isOpen() {
 return isOpen;
 }

 /**
 * 初始化端口操作的参数.
 * 
 * @throws SerialPortException
 * 
 * @see
 */
 public SerialUtil(SerialCallBack serialCallBack) {
 isOpen = false;
 this.serialCallBack = serialCallBack;
 }

 public void close() {
 if (isOpen) {
 try {
 serialPort.notifyOnDataAvailable(false);
 serialPort.removeEventListener();
 inputStream.close();
 serialPort.close();
 isOpen = false;
 serialCallBack.close(0, "关闭成功!");
 } catch (IOException ex) {
 // "关闭串口失败";
 serialCallBack.close(-1, "关闭失败!");
 }
 }
 }

 /**
 * BI -通讯中断.   CD -载波检测.   CTS -清除发送.   DATA_AVAILABLE -有数据到达.   DSR
 * -数据设备准备好.   FE -帧错误.   OE -溢位错误.   OUTPUT_BUFFER_EMPTY -输出缓冲区已清空.   PE
 * -奇偶校验错. RI - 振铃指示.
 */
 // 如果串口有数据上报则主动调用此方法
 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:
 receivedComm();
 break;
 default:
 break;
 }
 }

 /**
 * 读取返回数据
 */
 public void receivedComm() {
 try {
 Thread.sleep(200);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 try {
 int available = inputStream.available();
 byte[] b = new byte[available];
 inputStream.read(b);
 serialCallBack.receivedComm(0, b);
 } catch (IOException ex) {
 ex.printStackTrace();
 serialCallBack.serialRemoved(-2, "串口被拔出!");
 close();
 } catch (Exception ex) {

 ex.printStackTrace();
 serialCallBack.receivedComm(-1, null);
 }

 }

 /**
 * 发送命令
 * 
 * @param outbyte
 */
 public void sendComm(byte[] outbyte) {

 synchronized (readWriteLock) {
 try {
 if (outbyte.length == 0) {
 return;
 }
 outputStream.write(outbyte);
 String hex = Bytes.bytesToHexString(outbyte);
 serialCallBack.sendComm(hex);
 } catch (IOException ex) {

 }
 }
 }

 static String getPortTypeName(int portType) {
 switch (portType) {
 case CommPortIdentifier.PORT_I2C:
 return "I2C";
 case CommPortIdentifier.PORT_PARALLEL:
 return "Parallel";
 case CommPortIdentifier.PORT_RAW:
 return "Raw";
 case CommPortIdentifier.PORT_RS485:
 return "RS485";
 case CommPortIdentifier.PORT_SERIAL:
 return "Serial";
 default:
 return "unknown type";
 }
 }

 /**
 * 获取本地串口
 * 
 * @return
 */
 private List<CommPortIdentifier> getAvailableSerialPorts() {
 List<CommPortIdentifier> h = new ArrayList<CommPortIdentifier>();
 Enumeration thePorts = CommPortIdentifier.getPortIdentifiers();
 while (thePorts.hasMoreElements()) {
 CommPortIdentifier com = (CommPortIdentifier) thePorts
 .nextElement();
 switch (com.getPortType()) {
 case CommPortIdentifier.PORT_SERIAL:
 try {
 // CommPort thePort = com.open("FotaSerialUtil", 100);
 // thePort.close();
 h.add(com);
 } catch (Exception e) {
 System.out.println("Port, " + com.getName()
 + ", is in use.");
 }
 }
 }
 return h;
 }

 public List<String> getAvailableSerialPortsName() {
 List<String> names = new ArrayList<>();
 List<CommPortIdentifier> availableSerialPorts = getAvailableSerialPorts();
 for (CommPortIdentifier commPortIdentifier : availableSerialPorts) {
 names.add(commPortIdentifier.getName());
 }
 return names;
 }

 public interface SerialCallBack {

 void open(int status, String msg);

 void close(int status, String msg);

 void receivedComm(int status, byte[] comm);

 void sendComm(String comm);

 void serialRemoved(int status, String msg);

 }

 /**
 * 打开串口
 * 
 * @param commName
 * @return
 */
 public void openSerial(String commName) {
 CommPortIdentifier comm = null;
 if (null == commName) {
 serialCallBack.open(2, "串口名称为null");
 return;
 }
 List<CommPortIdentifier> availableSerialPorts = getAvailableSerialPorts();
 if (availableSerialPorts.size() == 0) {
 serialCallBack.open(3, "没有检测到串口,请刷新");
 return;
 }
 for (CommPortIdentifier commPortIdentifier : availableSerialPorts) {

 if (commPortIdentifier.getName().equals(commName)) {
 comm = commPortIdentifier;
 }
 }
 if (comm == null) {
 serialCallBack.open(4, "该串口已经被移除,请刷新");
 return;
 }
 try {
 if (isOpen()) {
 close();
 }
 if (null != comm) {
 serialPort = (SerialPort) comm.open("FotaSerialUtil", 100);
 inputStream = serialPort.getInputStream();
 serialPort.addEventListener(this);
 serialPort.notifyOnDataAvailable(true);
 serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
 SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
 outputStream = serialPort.getOutputStream();
 outputStream.write("H".getBytes());// 打开就唤醒
 isOpen = true;
 serialCallBack.open(0, serialPort.getName() + ":打开成功!");
 }
 } catch (Exception e) {
 System.out.println(e.toString());
 serialCallBack.open(1, "打开失败");
 }
 }
}
  •   

  • 
    
    	
    色迷迷 哭 呕吐 大笑 口水 微笑 啵一个 发怒

    Hi,您需要填写昵称和邮箱!

    • 必填项
    • 必填项