很久以前写的一个java串口通讯程序,用的是comm.jar。用java搞串口通讯就是用菜刀削水果-虽然也能做到,但是很麻烦。
贴下核心类:
package com.jzdf.odu.serial;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.TooManyListenersException;
import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
import org.eclipse.swt.widgets.Display;
import com.jzdf.odu.constant.Constants;
import com.jzdf.odu.dto.Packet;
import com.jzdf.odu.util.AsciiToHex;
import com.jzdf.odu.view.MainShell;
/**
* 串口工具类,负责串口的打开,发送数据,接收数据,关闭等
*
* @author liu
*/
public class SerialOperate implements SerialPortEventListener {
public SerialPort serialPort;
private CommPortIdentifier portId;
private InputStream inputStream;
private OutputStream outputStream;
private static final SerialOperate serialOperate = new SerialOperate();
// private MainShell shell = MainShell.getMainShell();
/**
* 构造器:打开串口,并获得输入输出流, 与主界面类(MainView)构造依赖
*
* @param MainShell
* The main view of the program.
* @param portName
* The serial port name of the local computer. such as
* "COM1","COM2" etc.
* @throws PortInUseException
* @throws NoSuchPortException
*/
private SerialOperate() {
}
/**
* 单列模式
*
* @return the only instance of the class.
*/
public static SerialOperate getInstance() {
return serialOperate;
}
/**
* 打开串口和输入输出流
*
* @throws IOException
*
*/
public boolean openPort(String portName) throws NoSuchPortException,
PortInUseException, IOException {
portId = CommPortIdentifier.getPortIdentifier(portName);
serialPort = (SerialPort) portId.open("ODU", 50);
try {
inputStream = new BufferedInputStream(serialPort.getInputStream());
outputStream = new BufferedOutputStream(serialPort
.getOutputStream());
return true;
} catch (IOException e) {
inputStream.close();
return false;
}
}
/**
* 设置串口读写参数(分别为波特率:115200, 数据位:8,停止位:1,校验码:无)
*
*/
public boolean setParameter() {
try {
// serialPort.setSerialPortParams(Integer.valueOf(shell.comboBaud.getText()),Integer.valueOf(shell.comboDataBit.getText()),
// Integer.valueOf(shell.comboStopBit.getText()),
// Integer.valueOf(shell.comboCheck.getText()));
serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
return true;
} catch (UnsupportedCommOperationException e) {
return false;
}
}
// public byte read() {
// int newData = 0;
// byte data = 0;
// try {
// if ((newData = inputStream.read()) != -1) {
// data = (byte) newData;
// }
// } catch (IOException e) {
// }
// return data;
// }
/**
* 以包为单位返回数据
*/
static int flag = 0;
public int no = 0;// 包的编号
public Packet readPacket() throws IOException {//TODO
final Packet pack = new Packet();
final ArrayList<String> content = new ArrayList<String>();
int newData;
while ((newData = inputStream.read()) != -1) {
byte data = (byte) newData;
if (data != 0x7E && flag != 0) {
content.add(String.valueOf(data));// 包的数据
flag++;
continue;
} else if (data == 0x7E && flag > 1) {// 包尾
content.add("126");
flag = 0;
pack.setId(no++);
System.out.println("No:" + no);
pack.setType(AsciiToHex.decToHex(content.get(1)));
Display.getDefault().syncExec(new Runnable() {
public void run() {
// 如果包类型为要过滤的类型,则清空包,重新计数
if (MainShell.getMainShell().getFilterList().contains(
pack.getType())) {
content.clear();
flag = 0;
no--;
} else {
String[] temp1 = new String[content.size()];
String[] temp2 = AsciiToHex.decToHex(content
.toArray(temp1));
content.clear();
for (String str : temp2) {
content.add(str);
}
pack.setData(content);
pack.setLength(content.size());
/* 显示接收到的数据包数及所用时间 */
if (MainShell.getMainShell().startTime != 0) {
MainShell.getMainShell().lblInfo
.setText("正在接收数据,已收到"
+ no
+ "个数据包!用时:"
+ (System.currentTimeMillis() - MainShell
.getMainShell().startTime)
+ "ms.");
} else {
MainShell.getMainShell().lblInfo
.setText("正在接收数据,已收到" + no + "个数据包!");
}
/* Write a packet to the txt file. */
FileOutputStream fos;
try {
fos = new FileOutputStream(new File(
Constants.dataFile + ".txt"), true);
fos.write(String.valueOf(no).getBytes());
fos.write(32);
fos.write(content.get(1).getBytes());
fos.write(32);
fos.write(content.toString().trim().getBytes());
fos.write(32);
fos.write(String.valueOf(content.size())
.getBytes());
String newLine = "\r\n";
fos.write(newLine.getBytes());
fos.close();// Must!!!
} catch (Exception e) {
}
content.clear();// Must!!!
/* End write */
flag = 0;
}
}
});
continue;
} else if (data == 0x7E && flag == 0) {// 包头
content.add("126");
flag++;
continue;
} else if (data == 0x7E && flag == 1) {// 7E 7E
content.clear();
content.add("126");
flag = 1;
continue;
}
}
return pack;
}
/**
* 以十进制整型发送数据
*
* @param dataToSend
*/
public void send(String dataToSend) {
try {
outputStream.write(Integer.parseInt(dataToSend, 16));
outputStream.flush();
} catch (IOException e) {
}
}
/**
* 发送"发送区"中的数据
*/
public void sendAll() {
ArrayList<String> data = (ArrayList<String>) MainShell.getMainShell()
.getSendPacket();
for (String byteHex : data) {
send(byteHex);
}
}
/**
* 关闭串口
*/
public void closePort() {
if (serialPort != null) {
serialPort.close();
}
}
/**
* 串口监听器,监听是否有数据及传输是否正常
*/
public void listening() {
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
}
serialPort.notifyOnDataAvailable(true);
}
@Override标签:SerialPortEvent,Java,String,fos,编程,content,串口,import,public From: https://blog.51cto.com/u_15045304/5967948
public void serialEvent(SerialPortEvent event) {
switch (event.getEventType()) {
case SerialPortEvent.BI:/* Break interrupt,通讯中断 */
case SerialPortEvent.OE:/* Overrun error,溢位错误 */
case SerialPortEvent.FE:/* Framing error,传帧错误 */
case SerialPortEvent.PE:/* Parity error,校验错误 */
case SerialPortEvent.CD:/* Carrier detect,载波检测 */
case SerialPortEvent.CTS:/* Clear to send,清除发送 */
case SerialPortEvent.DSR:/* Data set ready,数据设备就绪 */
case SerialPortEvent.RI:/* Ring indicator,响铃指示 */
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/* 输出缓冲区已清空 */
break;
case SerialPortEvent.DATA_AVAILABLE:/* 端口有数据时 */
try {
readPacket();// 按包读取数据,包按7E开头,7E结尾
} catch (IOException e1) {
}
break;
}
}
}