Java串口通信(16进制)

/**
字节流读取底层发来的16进制数据时,当Java是按照ASCII码的方式转换,当字符超过“80”时会出现乱码,所以要将字节流数据转换为十六进制的形式读取(即和底层发来的数据一致)。然后,再按照协议进行转换。
向底层发送16进制数据时,要先将16进制字符串转换为byte[]形式再进行发送,和底层进行通信。
例:SerialTool.write(HexString2Bytes(“00 00 11 11 99 ff”));
注:如果使用MyEclipse作为编译空间,导入的comm.jar,win32com.dll,javax.comm.properties文件不仅要导入JavaJDK,还要在MyEclipse相同位置进行插入。
*/

package dbUtils;

import java.io.BufferedInputStream;
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 javax.comm.CommPortIdentifier;
import javax.comm.SerialPort;
import javax.servlet.http.HttpServletRequest;

/**
 * 串口服务类,提供打开、关闭串口,读取、发送串口数据等服务(采用单例设计模式
 * 
 */
public class SerialTool implements Runnable {
    private static CommPortIdentifier portId;
    private static SerialPort serialPort;
    private static OutputStream outputStream;
    private static InputStream inputStream;
    private static Object obj = new Object();
    private static Object obj1 = new Object();
    Thread readThread;
    /**
     * 16进制数字字符集
     */
    private static String hexString = "0123456789ABCDEF";

    /*
     * 将字符串编码成16进制数字,适用于所有字符(包括中文)
     */
    public static String encode(byte[] str) {
        // 根据默认编码获取字节数组
        byte[] bytes = str;
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        // 将字节数组中每个字节拆解成2位16进制整数
        for (int i = 0; i < bytes.length; i++) {
            sb.append(hexString.charAt((bytes[i] & 0xf0) >> 4));
            sb.append(hexString.charAt((bytes[i] & 0x0f) >> 0));
        }
        return sb.toString();
    }

    /**
     * @方法名称: ReadData()
     * @return encode(readBuffer) 十六进制显示的字符串型数据
     * @throws IOException
     * @功能描述:对端口通信发送来的数据进行读取
     * @返回值类型:String
     */
    public static String ReadData() throws IOException {
        BufferedInputStream bis = new BufferedInputStream(inputStream);
        synchronized (obj) {
            while (true) {
                byte[] readBuffer = new byte[23];
                int length = 0;
                try {
                    if (bis.available() > 0) {
                        while ((length = bis.read(readBuffer)) == 23) {
                            for (int i = 0; i < length; i++) {
                                return encode(readBuffer);
                            }
                        }
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } finally {
                    inputStream.close();
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TinODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 将ReadData()方法中字符串以空格切割加入String数组中,获取命令符(通道)
     * 
     * @param int
     *            i=10或11
     * @return 第i个数据
     * @throws IOException
     */
    public static List<Object> DataProcess() throws IOException {
        synchronized (obj) {
        String dataHex = ReadData();
        String head = dataHex.substring(6, 8);
        String channel1 = dataHex.substring(20, 22);
        String frequency1 = dataHex.substring(22, 24);
        String Plush11 = dataHex.substring(24, 26);
        String Plush12 = dataHex.substring(26, 28);
        String Plush1 = Plush12 + Plush11;
        String voltage11 = dataHex.substring(28, 30);
        String voltage12 = dataHex.substring(30, 32);
        String voltage1 = voltage12 + voltage11;

        String frequency2 = dataHex.substring(32, 34);
        String Plush21 = dataHex.substring(34, 36);
        String Plush22 = dataHex.substring(36, 38);
        String Plush2 = Plush22 + Plush21;
        String voltage21 = dataHex.substring(38, 40);
        String voltage22 = dataHex.substring(40, 42);
        String voltage2 = voltage22 + voltage21;
        //Float curr = Float.parseFloat(SerialReadCurr.ReadCurrData().substring(
                //1, 4)) / 10;
        // 通道值
        int chs = Integer.parseInt(channel1, 16);
        // 频率
        int freq1 = Integer.parseInt(frequency1, 16);
        // 脉宽
        int plush1 = Integer.parseInt(Plush1, 16);
        // 强度
        float volt1 = Integer.parseInt(voltage1, 16);
        int freq2 = Integer.parseInt(frequency2, 16);
        // 脉宽
        int plush2 = Integer.parseInt(Plush2, 16);
        // 强度
        float volt2 = Integer.parseInt(voltage2, 16);
        String ch1 = "";
        String ch2 = "";
        if (chs == 2) {
            ch1 = "CH1";
            ch2 = "CH2";
        } else if (chs == 1) {
            ch1 = "NG";
            ch2 = "NG";
        }
        List<Object> list = new ArrayList<Object>();
        list.add(ch1);
        list.add(volt1 / 10);
        list.add(plush1);
        list.add(freq1);
        list.add(ch2);
        list.add(volt2 / 10);
        list.add(plush2);
        list.add(freq2);
        //list.add(curr);
        //HttpServletRequest request = null;
        //request.setAttribute("list",list);
        return list;
        }
    }

    // 初始化串口对象,端口等待时间2000ms,数据位8,停止位1,校验位none;
    public static void initComm(String comm) {
        try {
            portId = CommPortIdentifier.getPortIdentifier(comm);
            serialPort = (SerialPort) portId.open(comm, 2000);
            outputStream = serialPort.getOutputStream();
            inputStream = serialPort.getInputStream();
            // 设置初始化参数;
            serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            /*
             * serialPort.addEventListener(this);
             * serialPort.notifyOnDataAvailable(true);//设置监听模式为当有数据到达时唤醒监听线程。
             */} catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭串口
     * 
     * @param serialport
     *            待关闭的串口对象
     */
    public static void closePort() {
        if (serialPort != null) {
            serialPort.close();
            serialPort = null;
        }
    }

    /**
     * @方法描述:向所连接的端口发送数据
     * @param:cmd
     */
    public static byte[] writeComm(byte[] cmd) {
        try {
            outputStream.write(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return cmd;
    }

    // 字符串转成十六进制byte[] 类型数组;
    public static byte[] HexString2Bytes(String src) {
        if (null == src || 0 == src.length()) {
            return null;
        }
        byte[] ret = new byte[src.length() / 2];
        byte[] tmp = src.getBytes();
        for (int i = 0; i < (tmp.length / 2); i++) {
            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
        }
        return ret;
    }

    // byte类型数据,转成十六进制形式;
    public static byte uniteBytes(byte src0, byte src1) {
        byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))
                .byteValue();
        _b0 = (byte) (_b0 << 4);
        byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))
                .byteValue();
        byte ret = (byte) (_b0 ^ _b1);
        return ret;
    }

    public void run() {

    }
/*  public static void main(String arg[]){

    }*/
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值