Java串口通信(RXTX)

这几天要用到串口通信,而我最会的Java,所以我就去学了一下怎么用Java进行串口通信

用的jar包是RXTX官网:http://rxtx.qbang.org/

下载地址:http://fizzed.com/oss/rxtx-for-java

下载好Jar包后,首先需要配置,这里我用的Eclipse

Window->Preferences->Java->Build Path->User Library

添加一个库,然后添加RXTX的jar包,下载好在lib目录

然后将Native Library修改为lib目录

配置完成 接下来开始写代码

在项目中添加此Library,AddLibrary->userLibrary 选中刚新建的Library

在这 我奉上我记录的API

gnu.io包
	CommPortIdentifier类
		getPortIdentifiers();					返回一个Enumeration
		getPortIdentifiers(String s);			返回一个CommPortIdentifier,通过指定的COM名
		getName();								返回当前通讯端口标识符名
		open(String appName,int timeOut);		返回一个CommPort,通过名称和超时,可强转成SerialPort
		
		
	SerialPort抽象类(串行端口)
		setSerialPortParams(波特率,数据位,停止位,奇偶效验);	设置串口的参数
		getInputStream();						获取输入流
		getOutputStream();						获取输出流
		addEventListener(SerialPortEvent);		给打开的串口添加一个监听
		notifyOnDataAvailable(boolean);			是否打开监听
		
	SerialPortEvent类(串行端口事件)
		BI					Break Interrupt 通讯中断
		OE					Overrun Error 溢位错误
		FE					Framing Error 传帧错误
		PE					Parity Error 效验错误
		CD					Carrier Detect 载波检测
		CTS					Clear To Send 清除发送
		DSR					Data Set Ready 数据设备就绪
		RI					Ring Indicator 响铃指示
		OUTPUT_BUFFER_EMPTY	输出缓冲区清空
		DATA_AVAILABLE		端口有可用数据
		
		serialEvent(ServialPortEvent);		监听,调用此方法

一个简单的串口通信 --

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.TooManyListenersException;

import com.utils.Protocal;
import com.utils.Serial;

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

public class MyTest implements SerialPortEventListener {
	//串口
	private static SerialPort serialPort = null;
	private static CommPortIdentifier comm = null;
	private static BufferedInputStream bufferInput;
	public MyTest() {
		try {
			//获取通信端口标识符
			comm = Serial.getCommPortIdentifierByName("COM1");
			//打开串口
			serialPort = (SerialPort) comm.open("Read",2000);
			//设置串口的参数 波特率 数据位 停止位 奇偶效验
			serialPort.setSerialPortParams(Serial.getBaudRate(),Serial.getDataBits(),Serial.getStopBits(),Serial.getParity());
			//如果串口不为空的话 则监听获取信息 否则报错
			OutputStream output = null;
			if (serialPort != null) {
				try {
					//获取输入输出流
					bufferInput = new BufferedInputStream(serialPort.getInputStream());
					output = serialPort.getOutputStream();
					//添加监听
					serialPort.addEventListener(this);
					serialPort.notifyOnDataAvailable(true);
					//发送数据
					char[] hex = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
			        Serial.sendData(output,Protocal.getDataHead(),"52 52 52 01",crc,Protocal.getDataTail());
									System.out.println(crc);
								}
							}
						}
					}
				} catch (TooManyListenersException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else {
				throw new RuntimeException("串口获取失败-serialPort为null");
			}
		} catch (NoSuchPortException e) {
			e.printStackTrace();
		} catch (PortInUseException e) {
			e.printStackTrace();
		} catch (UnsupportedCommOperationException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		new MyTest();
	}
	
	/**
	 * -串口的监听
	 */
	@Override
	public void serialEvent(SerialPortEvent ev) {
		//判断数据类型
		switch (ev.getEventType()) {
		//通讯中断 Break Interrupt
		case SerialPortEvent.BI:
			System.out.println("BI");
			break;
		//溢位错误 Overrun Error
		case SerialPortEvent.OE:
			System.out.println("OE");
			break;
		//传帧错误 Framing Error
		case SerialPortEvent.FE:
			System.out.println("FE");
			break;
		//效验错误 Parity Error
		case SerialPortEvent.PE:
			System.out.println("PE");
			break;
		//载波检测 Carrier Detect
		case SerialPortEvent.CD:
			System.out.println("CD");
			break;
		//清除发送 Clear To Send
		case SerialPortEvent.CTS:
			System.out.println("CTS");
			break;
		//数据设备就绪 Data Set Ready
		case SerialPortEvent.DSR:
			System.out.println("DSR");
			break;
		//响铃指示 Ring Indicator
		case SerialPortEvent.RI:
			System.out.println("RI");
			break;
		//输出缓冲区清空 Output Buffer Empty
		case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
			System.out.println("output");
			break;
		//端口有可用数据 Data Available
		case SerialPortEvent.DATA_AVAILABLE:
			//读取数据
			try {
				byte[] bytes = null;
				byte[] tempBytes = new byte[1024];
				int len = -1;
				while ((len = bufferInput.read(tempBytes)) != -1) {
					//将数据写入bytes中 并更改bytes的长度
					if (bytes != null) {
						byte[] b = bytes;
						bytes = new byte[bytes.length + len];
						for (int i = 0;i < bytes.length;i++) {
							if (i < len) {
								bytes[i] = b[i];
							} else {
								bytes[i] = tempBytes[i];
							}
						}
					} else {
						bytes = new byte[len];
						for (int i = 0;i < bytes.length;i++) {
							bytes[i] = tempBytes[i];
						}
					}
				}
				//输出数据
				System.out.println("字符串形式:"+ new String(bytes));
				System.out.println("16进制形式:"+ Protocal.switchByteToHexadecimal(bytes));
			} catch (IOException e) {
				e.printStackTrace();
			}
			break;
		}
		
	}
}

奉上我的两个工具类

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.SerialPort;

/**
 * -串口通讯工具类
 * @author Shendi
 *
 */
public class Serial {
	private static int baudRate = 19200;//波特率 默认为19200
	private static int dataBits = SerialPort.DATABITS_8;//数据位 默认为8
	private static int stopBits = SerialPort.STOPBITS_1;//停止位 默认为1
	private static int parity = SerialPort.PARITY_NONE;//奇偶效验 默认为无
	
	
	public static int getBaudRate() {
		return baudRate;
	}
	public static void setBaudRate(int baudRate) {
		Serial.baudRate = baudRate;
	}
	public static int getDataBits() {
		return dataBits;
	}
	public static void setDataBits(int dataBits) {
		Serial.dataBits = dataBits;
	}
	public static int getStopBits() {
		return stopBits;
	}
	public static void setStopBits(int stopBits) {
		Serial.stopBits = stopBits;
	}
	public static int getParity() {
		return parity;
	}
	public static void setParity(int parity) {
		Serial.parity = parity;
	}

	/**
	 * -获取通信端口标识符通过端口名
	 * @param commName 端口名
	 * @return 实例通讯端口标识符
	 * @throws NoSuchPortException 
	 */
	public static CommPortIdentifier getCommPortIdentifierByName(String commName) throws NoSuchPortException {
		//如果名称为空 则返回null
		if ("".equals(commName)) {
			return null;
		}
		CommPortIdentifier comm = CommPortIdentifier.getPortIdentifier(commName);
		return comm;
	}
	
	/**
	 * -发送数据
	 * @param serialPortOutput 输出流
	 * @param dataHead 数据头
	 * @param data 数据
	 * @param CRC 校验位
	 * @param dataTail 数据尾
	 */
	public static void sendData(OutputStream serialPortOutput,String dataHead,String data,String CRC,String dataTail) {
		//组合字符串 数据头+数据+校验位+数据尾
		StringBuffer str = new StringBuffer();
		if (dataHead != null) {
			str.append(dataHead);
		}
		if (data != null) {
			str.append(data);
		}
		if (CRC != null) {
			str.append(CRC);
		}
		if (dataTail != null) {
			str.append(dataTail);
		}
		System.out.println(str.toString());
		//将字符串变成16进制存进byte中
		byte[] bytes = Protocal.switchStringToHexadecimal(str.toString());
		//发送数据
		try {
			serialPortOutput.write(bytes);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
}
-----------------------------------------------------
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;

/**
 * -协议工具类
 * @author Shendi
 *
 */
public class Protocal {
	//数据头 数据尾
	private static String dataHead = "7B 01 00 16 31 33 39 31 34 30 30 30 31 37 39 42 42 42 42 42 42 42 42 42 53";
	private static String dataTail = "45";
	private static String CRC = "40 55 ";//CRC效验码 默认为 40 55
	
	/**
	 * -将字符串转换为byte数组 16进制
	 * @param str 要转换的字符串
	 * @return 如果为null 则转换失败 否则返回byte数组
	 */
	public static byte[] switchStringToHexadecimal(String str) {
		//将空格清除
		str = str.replaceAll(" ","");
		//将字符串按照2个一组拆分 存入byte中
		byte[] bytes = new byte[str.length()/2];
		for (int i = 0;i < bytes.length;i++) {
			bytes[i] = (byte) Integer.parseInt(str.substring(i+i, i+i+2),16);
			System.out.print(bytes[i]+" ");
		}
		System.out.println("\n");
		return bytes;
	}
	
	public static String switchByteToHexadecimal(byte[] bytes) {
		StringBuffer data = new StringBuffer();
		char[] hex = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		for (int i = 0;i < bytes.length;i++) {
			int num = bytes[i];
			String str = "";
			if (num == 0) {
				str = "00";
			} else {
				while (num != 0) {
					str = hex[num % 16]+str;
					num /= 16;
				}
			}
			//如果字符串长度不等于2的话 则添加一位0
			if (str.length() < 2) {
				str = "0"+str;
			}
			//获取16进制
			data.append(str+" ");
		}
		return data.toString();
	}
	
	public static String getDataHead() {
		return dataHead;
	}
	public static String getDataTail() {
		return dataTail;
	}
	public static String getCRC() {
		return CRC;
	}
	
	
	
}

大概就是这样了,关注我,获取更多~

发布了38 篇原创文章 · 获赞 23 · 访问量 9077

猜你喜欢

转载自blog.csdn.net/qq_41806966/article/details/93402891
今日推荐