java串口通信与打卡器交互

             java与串口通信之前首先要将串口的环境配置好(链接:http://pan.baidu.com/share/link?shareid=2561488444&uk=120962509 密码:8gpv)配置相关自己看api好了,一定要记得使用Jre7,不然无法完成配置。下面给向读卡器里写数据的方法,网上这方面只是略谈了下,但其实这里的数据需要转化。

    

package test;

/*
 * @(#)SimpleWrite.java    1.12 98/06/25 SMI..0
 *
 * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license 
 * to use, modify and redistribute this software in source and binary
 * code form, provided that i) this copyright notice and license appear
 * on all copies of the software; and ii) Licensee does not utilize the
 * software in a manner which is disparaging to Sun.
 *
 * This software is provided "AS IS," without a warranty of any kind.
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND
 * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
 * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE
 * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS
 * BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,
 * HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING
 * OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control
 * of aircraft, air traffic, aircraft navigation or aircraft
 * communications; or in the design, construction, operation or
 * maintenance of any nuclear facility. Licensee represents and
 * warrants that it will not use or redistribute the Software for such
 * purposes.
 */

import java.io.*;
import java.util.*;

import javax.comm.*;

public class SimpleWrite {
    static Enumeration portList;
    static CommPortIdentifier portId;
    static String messageString = "FEF1000F0000000000000FFF";
    static SerialPort serialPort;
    static OutputStream outputStream;

    public static void main(String[] args) {
        portList = CommPortIdentifier.getPortIdentifiers();
        // 将字符串转化为16进制的方法
        List<byte[]> bytes = new ArrayList<byte[]>();
        for (int i = 0; i < messageString.length(); i += 2) {
            String hex = messageString.substring(i, i + 2);
            byte[] bnew = CardReaderUtil.hexStringToBytes(hex);
            bytes.add(bnew);
        }
        byte[] newByte = CardReaderUtil.sysCopy(bytes);
        while (portList.hasMoreElements()) {
            portId = (CommPortIdentifier) portList.nextElement();

            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                if (portId.getName().equals("COM1")) {
                    try {
                        serialPort = (SerialPort) portId.open("SimpleWriteApp",
                                2000);
                    } catch (PortInUseException e) {
                    }
                    try {
                        outputStream = serialPort.getOutputStream();
                    System.out.println("lalalla");
                    } catch (IOException e) {
                    }
                    try {
                        serialPort.setSerialPortParams(38400,
                                SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
                                SerialPort.PARITY_NONE);
                    } catch (UnsupportedCommOperationException e) {
                    }
                    try {
                        outputStream.write(newByte);
                        System.out.println("lolololo");
                    } catch (IOException e) {
                    }
                }
            }
        }
    }
}

可以看到注释的地方说明了下面的方法是将输入指令转化为十六进制,再给出转化的工具类:

package test;

import java.util.List;
/**
 * 处理写入字符的工具类
 * @author 
 *
 */
public class CardReaderUtil {

    //根据字符转换位相应的16进制
     private static byte charToByte(char c) {  
            return (byte) "0123456789ABCDEF".indexOf(c);  
        }  
     //将2位16进制字符串转换成字节数组
    public static byte[] hexStringToBytes(String hexString) {  
        if (hexString == null || hexString.equals("")) {  
            return null;  
        }  
        hexString = hexString.toUpperCase();  
        int length = hexString.length() / 2;  
        char[] hexChars = hexString.toCharArray();  
        byte[] d = new byte[length];  
        for (int i = 0; i < length; i++) {  
            int pos = i * 2;  
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));  
        }  
        return d;  
    } 
    //合并字节数组
    public static byte[] sysCopy(List<byte[]> srcArrays) {
          int len = 0;
          for (byte[] srcArray:srcArrays) {
           len+= srcArray.length;
          }
             byte[] destArray = new byte[len];   
             int destLen = 0;
             for (byte[] srcArray:srcArrays) {
                 System.arraycopy(srcArray, 0, destArray, destLen, srcArray.length);   
                 destLen += srcArray.length;   
             }   
             return destArray;
         }  
    
}

    下面说明下这个工具类,首先将输入的字符串按照两两的字符转化,串口通信全部需要字节流,所以相应的字符要转化为字节,我们知道一个字节有8位,这里字符表示的十六进制是4位二进制,那么自然需要用两个这样的字符转化为一个字节(这里需要注意下这里的字符不是java的基本数据char,因为char是两个字节,所以先使用charToByte的方法将这个十六进制转化为整数,直接用int强转会按照asicc码转化,明显不符合我们的规定),回到上面,把两个字符转化为一个字节之后得到的是一个具有两个长度的字节数组,我们一次性传入读卡器里的指令需要是一串指令,所以这里又使用sysCopy的方法拼接了所有转化好的字节数组,最后使用输出流写入到打卡器里面。是不是so easy?

原文地址:https://www.cnblogs.com/wq123/p/3218984.html