本文實例為大家分享了java使用rxtx實現串口通信調試工具的具體代碼,供大家參考,具體內容如下
最終效果如下圖:
1、把rxtxparallel.dll、rxtxserial.dll拷貝到:c:\windows\system32下。
2、rxtxcomm.jar 添加到項目類庫中。
代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
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 ); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
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 ; } } } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
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 ); //顯示窗口 } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/cuiyaoqiang/article/details/54928627