一.需要的工具和文件
1.eclipse 版本:3.0以上即可。
2.rxtx-2.1-7-bins-r2 .zip 出处:http://users.frii.com/jarvi/rxtx/download.html。
3.JDK 版本:我用的是1.5版,但是我认为更低的版本也没有问题。
二.环境搭建的步骤
step1.在eclipse中新建一个工程(根据你自己的需要,Applet,tomcat,java工程等均可)。
step2.在工程下建一个lib文件夹。
step3.将rxtx-2.1-7-bins-r2 .zip解压缩,得到文件夹[rxtx-2.1-7-bins-r2]。
step4.将[rxtx-2.1-7-bins-r2]/RXTXcomm.jar这个文件copy到step2创建的lib中。
step5.将[rxtx-2.1-7-bins-r2]/Windows/i368-mingw32目录下的两个dll文件copy到step2创建的lib中。
step6.在工程上右键 -> Properties -> Java Builder Path -> Libraries -> Add JARs -> 选择step2中创建的lib目录下的RXTXcomm.jar -> OK。
step7.最关键的一步。点RXTXcomm.jar前面的小加号(+) -> 选择Native library location -> 点右边一列按钮中的Edit… -> 选择step2中创建的lib目录 -> OK。
补充:如果你的代码需要调用本地dll,你可以通过同样的方式设置Native library location。
三.环境配置完了以后,可以写一个程序来测试一下了。以下是我的test程序。
- import gnu.io.CommPortIdentifier;
- import java.util.Enumeration;
- public class CommTest {
- static CommPortIdentifier portId;
- static Enumeration portList;
- static int bauds[] = { 9600, 19200, 57600, 115200 };
- public static void main(String[] args) {
- portList = CommPortIdentifier.getPortIdentifiers();
- while (portList.hasMoreElements()) {
- portId = (CommPortIdentifier) portList.nextElement();
- if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
- System.out.println("Find CommPort: " + portId.getName());
- }
- }
- }
- }
import gnu.io.CommPortIdentifier; import java.util.Enumeration; public class CommTest { static CommPortIdentifier portId; static Enumeration portList; static int bauds[] = { 9600, 19200, 57600, 115200 }; public static void main(String[] args) { portList = CommPortIdentifier.getPortIdentifiers(); while (portList.hasMoreElements()) { portId = (CommPortIdentifier) portList.nextElement(); if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) { System.out.println("Find CommPort: " + portId.getName()); } } } }
正确的运行结果应该像下面这样:
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
Find CommPort: COM1
四.总结
用Java进行串口通讯程序的开发,总的说有三种途径。
1.用sun提供的开发包javacomm。但是sun已经停止了对这个包的维护了。它只能适用于较低版本的JDK。而且它的配置很麻烦。
2.用rxtx开发包。
3.用Delphi或者C++等更易于操作底层硬件的开发语言开发本地代码。借助JNI技术,用Java调用本地代码。根据我的理解,实际上rxtx开发包也是用的第三种途径。压缩文件中的两个dll文件就是最好的证据。
4.如果你的工程最终可能在其他操作系统上,你应该将[rxtx-2.1-7-bins-r2]文件夹下对应操作系统目录中的文件copy到你的工程lib目录中。比如,你要在linux下运行,那就应该把linux文件夹下的so文件copy到工程lib文件夹中。rxtx可以根据操作系统环境,选择需要加载的本地文件。这样就能真正做到跨系统,跨平台了。
代码本身很简单:
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;
public class ComTest {
/**
* @param args
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
String port = "COM5";
for (Enumeration<CommPortIdentifier> e = CommPortIdentifier
.getPortIdentifiers(); e.hasMoreElements();) {
CommPortIdentifier portId = e.nextElement();
if (portId.getName().equals(port)) {
System.out.println("\r");
System.out.println("找到端口: " + port);
sendAtTest(portId);
}
}
}
private static void sendAtTest(CommPortIdentifier portId)
throws PortInUseException, UnsupportedCommOperationException,
TooManyListenersException, IOException, InterruptedException {
System.out.println("打开端口 …");
final SerialPort serialPort = (SerialPort) portId.open("wavecom", 100);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);
serialPort.setSerialPortParams(115200,// 波特率
SerialPort.DATABITS_8,// 数据位数
SerialPort.STOPBITS_1, // 停止位
SerialPort.PARITY_NONE);// 奇偶位
System.out.println("端口已打开。\n发送AT指令 …");
InputStream inputStream=serialPort.getInputStream();
OutputStream outputStream=serialPort.getOutputStream();
outputStream.write("AT\r".getBytes());
Thread.sleep(1000);
byte[] data=new byte[1024];
for(int i=inputStream.read(data);;i=inputStream.read(data)){
if(i>0){
System.out.println(new String(data,0,i));
System.out.println("成功收到指令返回值。");
break;
}
}
serialPort.close();
System.out.println("关闭端口。");
}
}
这是一个简单的测试,以前也没用过AT指令集,慢慢边测试边使用。运行结果:
基本上,RxTx就是对java comm包的仿制,除了包名不一样,类和行为都是一样的。
打开串口以后,可以操作一个输入流,一个输出流,输入命令,输出结果。
上面实例很简单,使用了直接的方式接收命令,这样不适合复杂的应用。还有一种监听器的方式,稍后再做测试。
*****************************************************************************************************************************
java读写串口要用到的是javax扩展类库javacomm,它是一系列的标准,该类库在sun的官网上只提供linux版本。由于我所应用的平台是win32,所以找了个win32的实现。在此过程中遇到了一系列的问题,后来终于解决问题并完成了通过读写串口进行通信的功能。在此对其java读写串口的情况做个简要说明:
首先下载javacomm包,然后将其解压,解压后需要做的就是配置串口通信相关东西,下面是自己使用的时候的配置:
1.把javax.comm.properties文件拷贝到Java运行时环境的lib目录中,即:
C:\Program Files\Java\jdk1.5.0_12\lib\javax.comm.properties
C:\Program Files\Java\jdk1.5.0_12\jre\lib\javax.comm.properties
2.把win32com.dll拷贝到C:\windows\system32\ 和 C:\Program Files\Java\jdk1.5.0_12\jre\bin\下
3.把comm.jar放到Java运行时环境的lib目录中,即C:\Program Files\Java\jdk1.5.0_12\lib\comm.jar
4.在"环境变量"的CLASSPATH中添加comm.jar,如:%JAVA_HOME%\lib\comm.jar;
然后通过COM的API来实现串口的读写,其实API相当简单,如下代码:
Java代码
CommPortIdentifier serialPortId = CommPortIdentifier.getPortIdentifier(“COM2”);
SerialPort port = (SerialPort) serialPortId.open(“Read”, 30);//打开COM2串口,其中30参数是用来设置打开串口的超时时间。
port.setSerialPortParams(1200, 8, 1, 0);//设置COM2的波特率,数据位,停止位,校验方式等
//从串口中得到输入输出流了
OutputStream out = port.getOutputStream();
out .write(buffer);
out .flush();
InputStream in = port.getInputStream();
in.read(data);//data是一个byte[]
CommPortIdentifier serialPortId = CommPortIdentifier.getPortIdentifier(“COM2”); SerialPort port = (SerialPort) serialPortId.open(“Read”, 30);//打开COM2串口,其中30参数是用来设置打开串口的超时时间。 port.setSerialPortParams(1200, 8, 1, 0);//设置COM2的波特率,数据位,停止位,校验方式等 //从串口中得到输入输出流了 OutputStream out = port.getOutputStream(); out .write(buffer); out .flush(); InputStream in = port.getInputStream(); in.read(data);//data是一个byte[]
如果COM1通信要求的波特率是1200,而系统默认的波特率是9600,在系统的设备管理器中修改了COM1的波特率为1200,那么这个时候修改后程序不报错误,但是在串口里获取不到任何信息,也就是在设备管理器修改COM1的波特率是没有用的,必须通过port.setSerialPortParams(1200, 8, 1, 0)来设置其波特率。