这篇文章主要为大家详细介绍了java使用Rxtx实现简单串口通信调试工具,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了java使用rxtx实现串口通信调试工具的具体代码,供大家参考,具体内容如下
最终效果如下图:
1、把rxtxparallel.dll、rxtxserial.dll拷贝到:c:\windows\system32下。
2、rxtxcomm.jar 添加到项目类库中。
代码:package serialport;
import java.io.ioexception;
import java.io.inputstream;
import java.io.outputstream;
import java.util.arraylist;
import java.util.enumeration;
import java.util.list;
import java.util.toomanylistenersexception;
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;
/**串口服务类,提供打开、关闭串口,读取、发送串口数据等服务
*/
public class serialtool {
private static serialtool serialtool = null;
static {
//在该类被classloader加载时就初始化一个serialtool对象
if (serialtool == null) {
serialtool = new serialtool();
}
}
//私有化serialtool类的构造方法,不允许其他类生成serialtool对象
private serialtool() {}
/**
* 获取提供服务的serialtool对象
* @return serialtool
*/
public static serialtool getserialtool() {
if (serialtool == null) {
serialtool = new serialtool();
}
return serialtool;
}
/**
* 查找所有可用端口
* @return 可用端口名称列表
*/
public static final list<string> findport() {
//获得当前所有可用串口
@suppresswarnings("unchecked")
enumeration<commportidentifier> portlist = commportidentifier.getportidentifiers();
list<string> portnamelist = new arraylist<>();
//将可用串口名添加到list并返回该list
while (portlist.hasmoreelements()) {
string portname = portlist.nextelement().getname();
portnamelist.add(portname);
}
return portnamelist;
}
/**
* 打开串口
* @param portname 端口名称
* @param baudrate 波特率
* @return 串口对象
* @throws unsupportedcommoperationexception
* @throws portinuseexception
* @throws nosuchportexception
*/
public static final serialport openport(string portname, int baudrate) throws unsupportedcommoperationexception, portinuseexception, nosuchportexception {
//通过端口名识别端口
commportidentifier portidentifier = commportidentifier.getportidentifier(portname);
//打开端口,并给端口名字和一个timeout(打开操作的超时时间)
commport commport = portidentifier.open(portname, 2000);
//判断是不是串口
if (commport instanceof serialport) {
serialport serialport = (serialport) commport;
//设置一下串口的波特率等参数
serialport.setserialportparams(baudrate, serialport.databits_8, serialport.stopbits_1, serialport.parity_none);
return serialport;
}
return null;
}
/**
* 关闭串口
* @param serialport 待关闭的串口对象
*/
public static void closeport(serialport serialport) {
if (serialport != null) {
serialport.close();
serialport = null;
}
}
/**
* 往串口发送数据
* @param serialport 串口对象
* @param order 待发送数据
* @throws ioexception
*/
public static void sendtoport(serialport serialport, byte[] order) throws ioexception {
outputstream out = null;
out = serialport.getoutputstream();
out.write(order);
out.flush();
out.close();
}
/**
* 从串口读取数据
* @param serialport 当前已建立连接的serialport对象
* @return 读取到的数据
* @throws ioexception
*/
public static byte[] readfromport(serialport serialport) throws ioexception {
inputstream in = null;
byte[] bytes = null;
try {
in = serialport.getinputstream();
int bufflenth = in.available(); //获取buffer里的数据长度
while (bufflenth != 0) {
bytes = new byte[bufflenth]; //初始化byte数组为buffer中数据的长度
in.read(bytes);
bufflenth = in.available();
}
} catch (ioexception e) {
throw e;
} finally {
if (in != null) {
in.close();
in = null;
}
}
return bytes;
}
/**添加监听器
* @param port 串口对象
* @param listener 串口监听器
* @throws toomanylistenersexception
*/
public static void addlistener(serialport port, serialporteventlistener listener) throws toomanylistenersexception {
//给串口添加监听器
port.addeventlistener(listener);
//设置当有数据到达时唤醒监听接收线程
port.notifyondataavailable(true);
//设置当通信中断时唤醒中断线程
port.notifyonbreakinterrupt(true);
}
}
package serialport;
import java.awt.color;
import java.awt.font;
import java.awt.image;
import java.awt.toolkit;
import java.awt.event.actionevent;
import java.awt.event.actionlistener;
import java.awt.event.mouseadapter;
import java.awt.event.mouseevent;
import java.io.ioexception;
import java.time.instant;
import java.time.localdatetime;
import java.time.zoneid;
import java.time.format.datetimeformatter;
import java.util.list;
import java.util.timer;
import java.util.timertask;
import java.util.toomanylistenersexception;
import javax.swing.jbutton;
import javax.swing.jcombobox;
import javax.swing.jframe;
import javax.swing.jlabel;
import javax.swing.joptionpane;
import javax.swing.jscrollpane;
import javax.swing.jtextarea;
import javax.swing.border.titledborder;
import gnu.io.nosuchportexception;
import gnu.io.portinuseexception;
import gnu.io.serialport;
import gnu.io.serialportevent;
import gnu.io.serialporteventlistener;
import gnu.io.unsupportedcommoperationexception;
/**
* 监测数据显示类
* @author zhong
*
*/
public class serialview extends jframe {
/**
*/
private static final long serialversionuid = 1l;
//设置window的icon
toolkit toolkit = gettoolkit();
image icon = toolkit.getimage(serialview.class.getresource("computer.png"));
datetimeformatter df= datetimeformatter.ofpattern("yyyy-mm-dd hh:mm:ss.sss");
private jcombobox<string> commchoice;
private jcombobox<string> bpschoice;
private jbutton openserialbutton;
private jbutton sendbutton;
private jtextarea sendarea;
private jtextarea receivearea;
private jbutton closeserialbutton;
private list<string> commlist = null; //保存可用端口号
private serialport serialport = null; //保存串口对象
/**类的构造方法
* @param client
*/
public serialview() {
init();
timertask task = new timertask() {
@override
public void run() {
commlist = serialtool.findport(); //程序初始化时就扫描一次有效串口
//检查是否有可用串口,有则加入选项中
if (commlist == null || commlist.size()<1) {
joptionpane.showmessagedialog(null, "没有搜索到有效串口!", "错误", joptionpane.information_message);
}else{
commchoice.removeallitems();
for (string s : commlist) {
commchoice.additem(s);
}
}
}
};
timer timer = new timer();
timer.scheduleatfixedrate(task, 0, 10000);
listen();
}
/**
*/
private void listen(){
//打开串口连接
openserialbutton.addactionlistener(new actionlistener() {
public void actionperformed(actionevent e) {
//获取串口名称
string commname = (string) commchoice.getselecteditem();
//获取波特率
string bpsstr = (string) bpschoice.getselecteditem();
//检查串口名称是否获取正确
if (commname == null || commname.equals("")) {
joptionpane.showmessagedialog(null, "没有搜索到有效串口!", "错误", joptionpane.information_message);
}else {
//检查波特率是否获取正确
if (bpsstr == null || bpsstr.equals("")) {
joptionpane.showmessagedialog(null, "波特率获取错误!", "错误", joptionpane.information_message);
}else {
//串口名、波特率均获取正确时
int bps = integer.parseint(bpsstr);
try {
//获取指定端口名及波特率的串口对象
serialport = serialtool.openport(commname, bps);
serialtool.addlistener(serialport, new seriallistener());
if(serialport==null) return;
//在该串口对象上添加监听器
closeserialbutton.setenabled(true);
sendbutton.setenabled(true);
openserialbutton.setenabled(false);
string time=df.format(localdatetime.ofinstant(instant.ofepochmilli(system.currenttimemillis()),zoneid.of("asia/shanghai")));
receivearea.append(time+" ["+serialport.getname().split("/")[3]+"] : "+" 连接成功..."+"\r\n");
receivearea.setcaretposition(receivearea.gettext().length());
} catch (unsupportedcommoperationexception | portinuseexception | nosuchportexception | toomanylistenersexception e1) {
e1.printstacktrace();
}
}
}
}
});
//发送数据
sendbutton.addmouselistener(new mouseadapter() {
@override
public void mouseclicked(mouseevent e) {
if(!sendbutton.isenabled())return;
string message= sendarea.gettext();
//"fe0400030001d5c5"
try {
serialtool.sendtoport(serialport, hex2byte(message));
} catch (ioexception e1) {
e1.printstacktrace();
}
}
});
//关闭串口连接
closeserialbutton.addmouselistener(new mouseadapter() {
@override
public void mouseclicked(mouseevent e) {
if(!closeserialbutton.isenabled())return;
serialtool.closeport(serialport);
string time=df.format(localdatetime.ofinstant(instant.ofepochmilli(system.currenttimemillis()),zoneid.of("asia/shanghai")));
receivearea.append(time+" ["+serialport.getname().split("/")[3]+"] : "+" 断开连接"+"\r\n");
receivearea.setcaretposition(receivearea.gettext().length());
openserialbutton.setenabled(true);
closeserialbutton.setenabled(false);
sendbutton.setenabled(false);
}
});
}
/**
* 主菜单窗口显示;
* 添加jlabel、按钮、下拉条及相关事件监听;
*/
private void init() {
this.setbounds(wellcomview.loc_x, wellcomview.loc_y, wellcomview.width, wellcomview.height);
this.settitle("串口调试");
this.seticonimage(icon);
this.setbackground(color.gray);
this.setlayout(null);
font font =new font("微软雅黑", font.bold, 16);
receivearea=new jtextarea(18, 30);
receivearea.seteditable(false);
jscrollpane receivescroll = new jscrollpane(receivearea);
receivescroll.setborder(new titledborder("接收区"));
//滚动条自动出现 fe0400030001d5c5
receivescroll.sethorizontalscrollbarpolicy(
jscrollpane.horizontal_scrollbar_as_needed);
receivescroll.setverticalscrollbarpolicy(
jscrollpane.vertical_scrollbar_as_needed);
receivescroll.setbounds(52, 20, 680,340);
this.add(receivescroll);
jlabel chuankou=new jlabel(" 串口选择: ");
chuankou.setfont(font);
chuankou.setbounds(50, 380, 100,50);
this.add(chuankou);
jlabel botelv=new jlabel(" 波 特 率: ");
botelv.setfont(font);
botelv.setbounds(290, 380, 100,50);
this.add(botelv);
//添加串口选择选项
commchoice = new jcombobox<string>(); //串口选择(下拉框)
commchoice.setbounds(145, 390, 100, 30);
this.add(commchoice);
//添加波特率选项
bpschoice = new jcombobox<string>(); //波特率选择
bpschoice.setbounds(380, 390, 100, 30);
bpschoice.additem("1500");
bpschoice.additem("2400");
bpschoice.additem("4800");
bpschoice.additem("9600");
bpschoice.additem("14400");
bpschoice.additem("19500");
bpschoice.additem("115500");
this.add(bpschoice);
//添加打开串口按钮
openserialbutton = new jbutton("连接");
openserialbutton.setbounds(540, 390, 80, 30);
openserialbutton.setfont(font);
openserialbutton.setforeground(color.darkgray);
this.add(openserialbutton);
//添加关闭串口按钮
closeserialbutton = new jbutton("关闭");
closeserialbutton.setenabled(false);
closeserialbutton.setbounds(650, 390, 80, 30);
closeserialbutton.setfont(font);
closeserialbutton.setforeground(color.darkgray);
this.add(closeserialbutton);
sendarea=new jtextarea(30,20);
jscrollpane sendscroll = new jscrollpane(sendarea);
sendscroll.setborder(new titledborder("发送区"));
//滚动条自动出现
sendscroll.sethorizontalscrollbarpolicy(
jscrollpane.horizontal_scrollbar_always);
sendscroll.setverticalscrollbarpolicy(
jscrollpane.vertical_scrollbar_always);
sendscroll.setbounds(52, 450, 500,100);
this.add(sendscroll);
sendbutton = new jbutton("发 送");
sendbutton.setbounds(610, 520, 120, 30);
sendbutton.setfont(font);
sendbutton.setforeground(color.darkgray);
sendbutton.setenabled(false);
this.add(sendbutton);
this.setresizable(false); //窗口大小不可更改
this.setdefaultcloseoperation(jframe.exit_on_close);
this.setvisible(true);
}
/**字符串转16进制
* @param hex
* @return
*/
private byte[] hex2byte(string hex) {
string digital = "0123456789abcdef";
string hex1 = hex.replace(" ", "");
char[] hex2char = hex1.tochararray();
byte[] bytes = new byte[hex1.length() / 2];
byte temp;
for (int p = 0; p < bytes.length; p++) {
temp = (byte) (digital.indexof(hex2char[2 * p]) * 16);
temp += digital.indexof(hex2char[2 * p + 1]);
bytes[p] = (byte) (temp & 0xff);
}
return bytes;
}
/**字节数组转16进制
* @param b
* @return
*/
private string printhexstring(byte[] b) {
stringbuffer sbf=new stringbuffer();
for (int i = 0; i < b.length; i++) {
string hex = integer.tohexstring(b[i] & 0xff);
if (hex.length() == 1) {
hex = '0' + hex;
}
sbf.append(hex.touppercase()+" ");
}
return sbf.tostring().trim();
}
/**
* 以内部类形式创建一个串口监听类
* @author zhong
*/
class seriallistener implements serialporteventlistener {
/**
* 处理监控到的串口事件
*/
public void serialevent(serialportevent serialportevent) {
switch (serialportevent.geteventtype()) {
case serialportevent.bi: // 10 通讯中断
joptionpane.showmessagedialog(null, "与串口设备通讯中断", "错误", joptionpane.information_message);
break;
case serialportevent.oe: // 7 溢位(溢出)错误
break;
case serialportevent.fe: // 9 帧错误
break;
case serialportevent.pe: // 8 奇偶校验错误
break;
case serialportevent.cd: // 6 载波检测
break;
case serialportevent.cts: // 3 清除待发送数据
break;
case serialportevent.dsr: // 4 待发送数据准备好了
break;
case serialportevent.ri: // 5 振铃指示
break;
case serialportevent.output_buffer_empty: // 2 输出缓冲区已清空
break;
case serialportevent.data_available: // 1 串口存在可用数据
string time=df.format(localdatetime.ofinstant(instant.ofepochmilli(system.currenttimemillis()),zoneid.of("asia/shanghai")));
byte[] data;//fe0400030001d5c5
try {
data = serialtool.readfromport(serialport);
receivearea.append(time+" ["+serialport.getname().split("/")[3]+"] : "+ printhexstring(data)+"\r\n");
receivearea.setcaretposition(receivearea.gettext().length());
} catch (ioexception e) {
e.printstacktrace();
}
break;
default:
break;
}
}
}
}
package serialport;
import java.awt.color;
import java.awt.font;
import java.awt.image;
import java.awt.toolkit;
import java.awt.event.keyadapter;
import java.awt.event.keyevent;
import javax.swing.jframe;
import javax.swing.jlabel;
/**
* @author bh
* 如果运行过程中抛出 java.lang.unsatisfiedlinkerror 错误,
* 请将rxtx解压包中的 rxtxparallel.dll,rxtxserial.dll 这两个文件复制到 c:\windows\system32 目录下即可解决该错误。
*/
public class wellcomview {
/** 程序界面宽度*/
public static final int width = 800;
/** 程序界面高度*/
public static final int height = 620;
/** 程序界面出现位置(横坐标) */
public static final int loc_x = 200;
/** 程序界面出现位置(纵坐标)*/
public static final int loc_y = 70;
private jframe jframe;
/**主方法
* @param args //
*/
public static void main(string[] args) {
new wellcomview();
}
public wellcomview() {
init();
listen();
}
/**
*/
private void listen() {
//添加键盘监听器
jframe.addkeylistener(new keyadapter() {
public void keyreleased(keyevent e) {
int keycode = e.getkeycode();
if (keycode == keyevent.vk_enter) { //当监听到用户敲击键盘enter键后执行下面的操作
jframe.setvisible(false); //隐去欢迎界面
new serialview(); //主界面类(显示监控数据主面板)
}
}
});
}
/**
* 显示主界面
*/
private void init() {
jframe=new jframe("串口调试");
jframe.setbounds(loc_x, loc_y, width, height); //设定程序在桌面出现的位置
jframe.setlayout(null);
//设置window的icon(这里我自定义了一下windows窗口的icon图标,因为实在觉得哪个小咖啡图标不好看 = =)
toolkit toolkit = jframe.gettoolkit();
image icon = toolkit.getimage(wellcomview.class.getresource("computer.png"));
jframe.seticonimage(icon);
jframe.setbackground(color.white); //设置背景色
jlabel huanyin=new jlabel("欢迎使用串口调试工具");
huanyin.setbounds(170, 80,600,50);
huanyin.setfont(new font("微软雅黑", font.bold, 40));
jframe.add(huanyin);
jlabel banben=new jlabel("version:1.0 powered by:cyq");
banben.setbounds(180, 390,500,50);
banben.setfont(new font("微软雅黑", font.italic, 26));
jframe.add(banben);
jlabel enter=new jlabel("————点击enter键进入主界面————");
enter.setbounds(100, 480,600,50);
enter.setfont(new font("微软雅黑", font.bold, 30));
jframe.add(enter);
jframe.setresizable(false); //窗口大小不可更改
jframe.setdefaultcloseoperation(jframe.exit_on_close);
jframe.setvisible(true); //显示窗口
}
} 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持CodeAE代码之家。
原文链接:https://blog.csdn.net/cuiyaoqiang/article/details/54928627
|