本文实例讲述了Java实现的串口通信功能。分享给大家供大家参考,具体如下:
用Java实现串口通信(windows系统下),需要用到sun提供的串口包 javacomm20-win32.zip。其中要用到三个文件,配置如下:
1.comm.jar放置到 JAVA_HOME/jre/lib/ext;
2.win32com.dll放置到 JAVA_HOME/bin;
3.javax.comm.properties 两个地方都要放
jre/lib(也就是在JAVA文件夹下的jre)
JAVA_HOME/jre/lib
说一下我应用的环境。电子秤称重时,计算机通过串口给称重控制显示器发送一次命令“R”,控制显示器则发送一次重量数据给串口,计算机再读取将数据显示在网页上。这样就构成了一个实时称重系统。
读写串口的代码如下:
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
|
package com.chengzhong.tools;
import java.io.*;
import javax.comm.CommPortIdentifier;
import javax.comm.*;
/**
*
* This bean provides some basic functions to implement full duplex
* information exchange through the serial port.
*
*/
public class SerialBean
{
public static String PortName;
public static CommPortIdentifier portId;
public static SerialPort serialPort;
public static OutputStream out;
public static InputStream in;
//保存读数结果
public static String result= "" ;
public static int openSignal= 1 ;
/**
*
* Constructor
*
* @param PortID the ID of the serial to be used. 1 for COM1,
* 2 for COM2, etc.
*
*/
public SerialBean( int PortID)
{
PortName = "COM" +PortID;
}
/**
*
* This function initialize the serial port for communication. It starts a
* thread which consistently monitors the serial port. Any signal captured
* from the serial port is stored into a buffer area.
*
*/
public int Initialize()
{
openSignal= 1 ;
try
{
portId = CommPortIdentifier.getPortIdentifier(PortName);
try
{
serialPort = (SerialPort)
portId.open( "Serial_Communication" , 2000 );
} catch (PortInUseException e)
{
if (!SerialBean.portId.getCurrentOwner().equals( "Serial_Communication" ))
{
openSignal= 2 ; //该串口被其它程序占用
} else if (SerialBean.portId.getCurrentOwner().equals( "Serial_Communication" )){
openSignal= 1 ;
return openSignal;
}
return openSignal;
}
//Use InputStream in to read from the serial port, and OutputStream
//out to write to the serial port.
try
{
in = serialPort.getInputStream();
out = serialPort.getOutputStream();
} catch (IOException e)
{
openSignal= 3 ; //输入输出流错误
return openSignal;
}
//Initialize the communication parameters to 9600, 8, 1, none.
try
{
serialPort.setSerialPortParams( 9600 ,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e)
{
openSignal= 4 ; //参数不正确
return openSignal;
}
} catch (NoSuchPortException e)
{
portId= null ;
openSignal= 5 ; //没有该串口
return openSignal;
}
// when successfully open the serial port, create a new serial buffer,
// then create a thread that consistently accepts incoming signals from
// the serial port. Incoming signals are stored in the serial buffer.
// return success information
return openSignal;
}
/**
*
* This function returns a string with a certain length from the incoming
* messages.
*
* @param Length The length of the string to be returned.
*
*/
public static void ReadPort()
{
SerialBean.result= "" ;
int c;
try {
if (in!= null ){
while (in.available()> 0 )
{
c = in.read();
Character d = new Character(( char ) c);
SerialBean.result=SerialBean.result.concat(d.toString());
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
*
* This function sends a message through the serial port.
*
* @param Msg The string to be sent.
*
*/
public static void WritePort(String Msg)
{
try
{
if (out!= null ){
for ( int i = 0 ; i < Msg.length(); i++)
out.write(Msg.charAt(i));
}
} catch (IOException e) {
return ;
}
}
/**
*
* This function closes the serial port in use.
*
*/
public void ClosePort()
{
serialPort.close();
}
}
|
这样通过 SerialBean.result
就可得到读数结果。
至于把数据放到网页上,就要用到Ajax了,这里用到了一个Ajax框架dwr, dwr类Put.java 如下:
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
|
package com.chengzhong.dwr;
import java.io.IOException;
import com.chengzhong.tools.Arith;
import com.chengzhong.tools.SerialBean;
public class Put {
//2011.9.17
public String write(){
//发送指令R,仪器发送一次净重数据
SerialBean.WritePort( "R" );
//读取数据
SerialBean.ReadPort();
String temp=SerialBean.result.trim(); //我这里temp是形如 wn125.000kg 的数据
if (!temp.equals( "" ) && temp.length()== 11 )
{
return (change(temp)).toString();
} else {
return "" ;
}
}
//响应开始称重
public String startWeight(String num){
int n=Integer.parseInt(num.trim());
SerialBean SB = new SerialBean(n);
SB.Initialize();
return SerialBean.openSignal+ "" ; //返回初始化信息
}
//响应停止称重
public void endWeight(){
try {
//关闭输入、输出流
SerialBean.in.close();
SerialBean.out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (SerialBean.serialPort!= null ){
SerialBean.serialPort.close(); //关闭串口
}
SerialBean.serialPort= null ;
SerialBean.portId= null ;
SerialBean.result= "" ;
}
/**
* 将形如 wn125.000kg 格式的重量转换为 125.000 (kg)(四舍五入,小数点后保留两位)
*/
public String change(String source){
Double result= 0.0 ;
String s1=source.substring( 2 , 9 );
try {
result=Double.parseDouble(s1);
result=Arith.round(result, 2 );
} catch (Exception e){
e.printStackTrace();
return "" ;
}
return result.toString();
}
}
|
注:Arith.java是一个java 的高精度计算文件。
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
|
package com.chengzhong.tools;
import java.math.BigDecimal;
/**
* 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精
* 确的浮点数运算,包括加减乘除和四舍五入。
*/
public class Arith{
//默认除法运算精度
private static final int DEF_DIV_SCALE = 10 ;
//这个类不能实例化
private Arith(){
}
/**
* 提供精确的加法运算。
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add( double v1, double v2){
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的减法运算。
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double sub( double v1, double v2){
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算。
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double mul( double v1, double v2){
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
* 小数点以后10位,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double div( double v1, double v2){
return div(v1,v2,DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
* 定精度,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div( double v1, double v2, int scale){
if (scale< 0 ){
throw new IllegalArgumentException(
"The scale must be a positive integer or zero" );
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理。
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round( double v, int scale){
if (scale< 0 ){
throw new IllegalArgumentException(
"The scale must be a positive integer or zero" );
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal( "1" );
return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
}
}
|
网页页面上:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<script type= "text/javascript" src= "/ChengZhong/dwr/engine.js" ></script>
<script type= "text/javascript" src= "/ChengZhong/dwr/util.js" ></script>
<script type= 'text/javascript' src= '/ChengZhong/dwr/interface/ss.js' ></script>
<script type= 'text/javascript' >
var ID;
function begin(){
ID=window.setInterval( 'get()' ,500); //每隔半秒自动调用 get(),取得毛重数据填入文本框中
}
function get()
{
ss.write(readIt); //调用dwr类 Put.java 中的write方法
}
function readIt(Data){
if (Data!= null && Data!= "" )
{
document.getElementById( "mzBF" ).value=Data;
}
}
</script>
|
dwr的使用就不说了
希望本文所述对大家java程序设计有所帮助。
原文链接:http://blog.csdn.net/zhutulang/article/details/6876676