您的位置:首页 > 编程语言 > Java开发

我的小工具,java版串口读写卡测试工具

2014-04-10 22:42 465 查看
工作过程中,经常需要和卡片打交道,如何快速的读写卡,提高些工作效率呢?业余时间,搞了个读写卡测试工具,

通过串口操作读卡器。我把车载机改造为串口的读卡器,配合这个工具就可以使用了。如果有网友想使用这个工具,得自己

做个下位机读卡器了。指令是透传的,监控发出来的指令就可以做个下位机。可在我的资源中下载使用(通过工具打包成exe了,若运行不起来注意java的环境配置)。我的qq534117529

先附个截图:



准备工作:

首先到SUN官网下载一个zip包:javacomm20-win32.zip

其中重要的有这几个文件:

win32com.dll

comm.jar

javax.comm.properties

按照说明配置好环境,如下:

将win32com.dll复制到<JDK>\bin目录下;将comm.jar复制到<JDK>\lib;把 javax.comm.properties也同样拷贝到<JDK>\lib目录下。然而在真正运行使用串口包的时候,仅作这些是不够的。因 为通常当运行“java MyApp”的时候,是由JRE下的虚拟机启动MyApp的。而我们只复制上述文件到JDK相应目录下,所以应用程序将会提示找不到串口。解决这个问题的 方法很简单,我们只须将上面提到的文件放到JRE相应的目录下就可以了

到这一个可以java 串口开发环境就搭建完成了。

串口读写代码

CommPortIdentifier portID = CommPortIdentifier.getPortIdentifier(com);//1,先拿到Identifier

//其中com是String类型的,传入的是串口名com="COM1";

SerialPort port = (SerialPort)portID.open("MyComm", 100000000);//2,打开串口

//"MyComm"是串口名,100000000是串口过期时间(ms)。

port.setSerialPortParams(rate, databits,stopbit, parity);//3,设置串口属性

//rate 波特率(默认9600),databits载波位(默认8),stopbit停止位(默认1),parity校验位(默认0无校验)

port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);//4(可选)设置数据流控制模式,默认为无

port.close();//关闭串口

3、串口读入写出流。

OutputStream os=port.getOutputStream();//拿到写出流。写出流就随便写就行。

port.getOutputStream().flush();//写完要记得做一次冲一下缓冲区

InputStream is= port.getInputStream();//拿到读入流。

is.read();//每次读入一个int,这个是个阻塞函数,在无数据的时候会中断。

4、串口读入轮询模式

一种读取的方式是每次做

         byte b[]=new byte[1024];

         is.read(b);

如果返回的是-1表示无数据。可以中断几毫秒然后再去读。

比较低效的一种读取模式,但是在使用阻塞函数的时候还是很好用的。

5、串口的监听模式

//5.1首先建立监听类

public class CommListener implements SerialPortEventListener

//继承自javax.comm.SerialPortEventListener;

//实现监听方法public void serialEvent(SerialPortEvent arg0){}

当有新数据进入的时候会被调用,传入javax.comm.SerialPortEvent对象参数。

if (arg0.getEventType()==SerialPortEvent.DATA_AVAILABLE)//如果是有效数据的话就做read

{

        //read();

}

//5.2建立好监听类以后要在port上添加。

port.addEventListener(commListener);

//其中port是上文打开的串口端口,commListener是上文的监听器实例

port.notifyOnDataAvailable(true);//设置监听模式为当有数据到达时唤醒监听线程。

要想更好的使用串口,最好再对comm.jar的串口包在封装出来一个串口类。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;
import java.util.ArrayList;
import javax.comm.CommPortIdentifier;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
/**
* @项目名称 :illegalsms
* @文件名称 :SerialPort.java
* @所在包 :org.serial
* @功能描述 :
* @创建者 :
* @创建日期 :
* @修改记录 :
*/
public class DSerialPort implements Runnable, SerialPortEventListener {

private String appName = "串口通讯测试";
private int timeout = 0;//open 端口时的等待时间
private int threadTime = 0;
public ArrayList listPort;
public String revStr="";
public String revStr1="";
private CommPortIdentifier commPort;
private SerialPort serialPort;
private InputStream inputStream;
private OutputStream outputStream;

public DSerialPort()
{
listPort=new ArrayList();
}
/**
* @方法名称 :listPort
* @功能描述 :列出所有可用的串口
* @返回值类型 :void
*/
@SuppressWarnings("rawtypes")
public void listPort(){
CommPortIdentifier cpid;
Enumeration en = CommPortIdentifier.getPortIdentifiers();

log("now to list all Port of this PC:" +en);

while(en.hasMoreElements()){
cpid = (CommPortIdentifier)en.nextElement();
if(cpid.getPortType() == CommPortIdentifier.PORT_SERIAL){
log(cpid.getName() + ", " + cpid.getCurrentOwner());
listPort.add(cpid.getName());
}
}
}

/**
* @方法名称 :selectPort
* @功能描述 :选择一个端口,比如:COM1
* @返回值类型 :void
*	@param portName
*/
@SuppressWarnings("rawtypes")
public boolean selectPort(String portName){

this.commPort = null;
CommPortIdentifier cpid;
Enumeration en = CommPortIdentifier.getPortIdentifiers();

while(en.hasMoreElements()){
cpid = (CommPortIdentifier)en.nextElement();
if(cpid.getPortType() == CommPortIdentifier.PORT_SERIAL
&& cpid.getName().equals(portName)){
this.commPort = cpid;
break;
}
}

return openPort();
}

/**
* @方法名称 :openPort
* @功能描述 :打开SerialPort
* @返回值类型 :void
*/
private boolean openPort(){
if(commPort == null)
{
log(String.format("无法找到名字为'%1$s'的串口!", commPort.getName()));
return false;
}
else{
log("端口选择成功,当前端口:"+commPort.getName()+",现在实例化 SerialPort:");

try{
serialPort = (SerialPort)commPort.open(appName, timeout);
log("实例 SerialPort 成功!");

// return true;

}catch(PortInUseException e){
log(String.format("端口'%1$s'正在使用中!",
commPort.getName()));
return false;
}
try
{
serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
}
catch(UnsupportedCommOperationException e)
{
log(String.format("端口'%1$s'参数不合法!",
commPort.getName()));
return false;
}
return true;

}
}

/**
* @方法名称 :checkPort
* @功能描述 :检查端口是否正确连接
* @返回值类型 :void
*/
private void checkPort(){
if(commPort == null)
throw new RuntimeException("没有选择端口,请使用 " +
"selectPort(String portName) 方法选择端口");

if(serialPort == null){
throw new RuntimeException("SerialPort 对象无效!");
}
}

/**
* @方法名称 :write
* @功能描述 :向端口发送数据,请在调用此方法前 先选择端口,并确定SerialPort正常打开!
* @返回值类型 :void
*	@param message
*/
public void write(String message) {
checkPort();

try{
outputStream = new BufferedOutputStream(serialPort.getOutputStream());
}catch(IOException e){
throw new RuntimeException("获取端口的OutputStream出错:"+e.getMessage());
}

try{
outputStream.write(message.getBytes());
log("信息发送成功!");
}catch(IOException e){
throw new RuntimeException("向端口发送信息时出错:"+e.getMessage());
}finally{
try{
outputStream.close();
}catch(Exception e){
}
}
}

/**
* @方法名称 :startRead
* @功能描述 :开始监听从端口中接收的数据
* @返回值类型 :void
*	@param time  监听程序的存活时间,单位为秒,0 则是一直监听
*/
public void startRead(int time){
checkPort();

try{
inputStream = new BufferedInputStream(serialPort.getInputStream());
}catch(IOException e){
throw new RuntimeException("获取端口的InputStream出错:"+e.getMessage());
}

try{
serialPort.addEventListener(this);
}catch(TooManyListenersException e){
throw new RuntimeException(e.getMessage());
}

serialPort.notifyOnDataAvailable(true);

log(String.format("开始监听来自'%1$s'的数据--------------", commPort.getName()));
if(time > 0){
this.threadTime = time*1000;
Thread t = new Thread(this);
t.start();
log(String.format("监听程序将在%1$d秒后关闭。。。。", threadTime));
}
}

/**
* @方法名称 :close
* @功能描述 :关闭 SerialPort
* @返回值类型 :void
*/
public void close(){
if(serialPort!=null)
{
serialPort.close();
serialPort = null;
commPort = null;
}
}

/**
*
* @param msg
*/
public void log(String msg){
System.out.println(appName+" --> "+msg);
}
public void log2(String msg){
System.out.println(appName+" --> "+msg);
}

/**
* 数据接收的监听处理函数
*/
@Override
public void serialEvent(SerialPortEvent arg0) {
switch(arg0.getEventType()){
case SerialPortEvent.BI:/*Break interrupt,通讯中断*/
case SerialPortEvent.OE:/*Overrun error,溢位错误*/
case SerialPortEvent.FE:/*Framing error,传帧错误*/
case SerialPortEvent.PE:/*Parity error,校验错误*/
case SerialPortEvent.CD:/*Carrier detect,载波检测*/
case SerialPortEvent.CTS:/*Clear to send,清除发送*/
case SerialPortEvent.DSR:/*Data set ready,数据设备就绪*/
case SerialPortEvent.RI:/*Ring indicator,响铃指示*/
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty,输出缓冲区清空*/
break;
case SerialPortEvent.DATA_AVAILABLE:/*Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端*/
byte[] readBuffer = new byte[1024];
String readStr="";
String s2 = "";
revStr="";
try {

while (inputStream.available() > 0) {
inputStream.read(readBuffer);
readStr += new String(readBuffer).trim();
}

s2 = new String(readBuffer).trim();
revStr=s2;
revStr1="接收到端口返回数据(长度为"+readStr.length()+"):"+readStr;
//log2("接收到端口返回数据(长度为"+readStr.length()+"):"+readStr);
log2(s2);
} catch (IOException e) {
}
}
}

@Override
public void run() {
try{
Thread.sleep(threadTime);
serialPort.close();
log(String.format("端口''监听关闭了!", commPort.getName()));
}catch(Exception e){
e.printStackTrace();
}
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息