java串口通信总结

我本身对与串口也是一知半解,从去年开始老师一直让我们自己写一个属于自己的串口助手。

开始我也觉得很难,后面发现其实用java写一个串口助手只是耐性的问题。

有句话说的好----“搜索引擎是最好的老师”

串口通信指的是通过接口获取数据,或者通过接口发送数据,当然其中可以实现的功能有很多,但其实就是发送数据,接收数据。

刚开始启蒙写的是java串口程序,一下贴一段我自己本身常用的串口程序:

//main类,主函数

1 import dealdata.SerialPortWindows;
2 
3 public class main {
4     public static void main(String[] args) {
5         new SerialPortWindows();
6     }
7 }

//SerialPortWindows类(本想写一个GUI窗口,你没时间就没写了...)

 
 3 import java.io.BufferedOutputStream;
 4 import java.io.BufferedReader;
 5 import java.io.InputStream;
 6 import java.io.InputStreamReader;
 7 import java.io.OutputStream;
 8 import java.util.Enumeration;
 9 
10 import processing.serial.Serial;
11 import ennity.Sensordatainfo;
12 import gnu.io.CommPortIdentifier;
13 import gnu.io.SerialPort;
14 import gnu.io.SerialPortEvent;
15 import gnu.io.SerialPortEventListener;
16 
17 public class SerialPortWindows {
18     public final static int RATE = 9600;//波特率
19     public final static int DATABITS = SerialPort.DATABITS_8;//载波位
20     public final static int STOPBIT = SerialPort.STOPBITS_1;//停止位
21     public final static int PARITY = SerialPort.PARITY_NONE;//校验位
22     public final static String PORT = "COM9";//端口号
23     BufferedOutputStream comWriter;//发送流
24     BufferedReader comReader;//接收流
25     public SerialPortWindows() {
26         CommPortIdentifier portID = null;
27         SerialPort port = null;
28         try {
29             // 获取端口
30             portID = CommPortIdentifier.getPortIdentifier(PORT);
31             // 打开端口
32             port = (SerialPort) portID.open("portApp", 5000);
33             //设置端口参数
34             port.setSerialPortParams(RATE, DATABITS,STOPBIT, PARITY);
35             port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
36             // 获取接受流
37             comReader = new BufferedReader(new InputStreamReader(port.getInputStream()));
38             // 获取发送流
39             comWriter = new BufferedOutputStream(port.getOutputStream());
40             // 进行写操作
41             // comWriter.write("送信内容。。。".getBytes());// /写入时使用byte
42             // comWriter.flush();//
43             // port.close();
44             // 进行读操作
45             port.addEventListener(new Listener(port));
46             port.notifyOnDataAvailable(true);// 设置监听模式为当有数据到达时唤醒监听线程
47 
48         } catch (Exception ex) {
49             ex.printStackTrace();
50         }
51     }
52 }
53 
54 class Listener implements SerialPortEventListener {
55     private SerialPort port;
56     private byte[] buf;
57     private InputStream read;
58     private OutputStream out;
59     Sensordatainfo info;
60 
61     public Listener(SerialPort port) {
62         this.port = port;
63         buf = new byte[1024];
64         info = new Sensordatainfo();
65         try {
66             read = port.getInputStream();
67             out = port.getOutputStream();
68         } catch (Exception e) {
69             e.printStackTrace();
70         }
71     }
72 
73     public void serialEvent(SerialPortEvent arg0) {
74 
75         if (arg0.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
76             synchronized (this) {
77                 try {
78                     int length = read.read(buf);
79                     String isoString = new String(buf, "UTF-8");//将取得的数据以UTF-8的形式显示
80                     System.out.println(isoString);
81                     Thread.sleep(1000);
82                 } catch (Exception e) {
83                     e.printStackTrace();
84                 }
85             }
86         }
87     }
88 }

这些是我经常用到的代码,不过一般没有用到写入的部分,所以写入并没有验证是否可以实现。在串口传输的过程当中都是使用byte[]来接收和发送数据的,这样子的话我们首先要定义byte[]来存储数据。

收到数据的时候:

接通串口,打开串口之后,收集到来自串口的数据位byte[]然后我们要将其转化为字符串,很据需求要转为十六进制字符串得到数据:一下贴出转化的函数

 1     public static String toHex(byte[] data, int off, int length) {
 2         StringBuffer buf = new StringBuffer(data.length * 2);
 3         for (int i = off; i < length; i++) {
 4             if (((int) data[i] & 0xff) < 0x10) {
 5                 buf.append("0");
 6             }
 7             buf.append(Long.toString((int) data[i] & 0xff, 16));
 8             if (i < data.length - 1) {
 9                 buf.append(" ");
10             }
11         }
12         return buf.toString();
13     }

以上代码可以完成byte[]转化为十六进制字符串。

也有可能直接转化为int类型

 1     public static int byte2Int(byte[] buf, int begin, int end) // 将收到的字节转换为int型整数,并返回改int型数值
 2     {
 3         int result, i;
 4         result = (int) buf[begin];
 5         for (i = begin + 1; i <= end; i++) {
 6             System.out.println(buf[i] + " ");
 7             result = result * (1 << 8) + (int) buf[i];
 8         }
 9         return result;
10 
11     }

以上是转化为int类型的代码。

我在写串口程序的过程当中主要是花在转化的这部分时间比较多,第一次写,所以无从下手。

在写入的时候我们需要将字符串转为byte[]

 1     public static byte[] hexStringToBytes(String hexString) {
 2         String buf = "0123456789ABCDEF";
 3         if ((hexString == null) || (hexString.equals(""))) {
 4             return null;
 5         }
 6         hexString = hexString.toUpperCase();
 7         int length = hexString.length() / 2;
 8         char[] hexChars = hexString.toCharArray();
 9         byte[] d = new byte[length];
10         for (int i = 0; i < length; ++i) {
11             int pos = i * 2;
12             d[i] = (byte) (buf.indexOf(hexChars[pos]) << 4 | buf.indexOf(hexChars[(pos + 1)]));
13         }
14         return d;
15     }

以上是将十六进制字符串转为byte[]的代码.

老师一直让我用C语言来编写串口程序,虽然有些不明白,但是相比较于C语言来说JAVA语言的串口程序写起来更容易一些,所以我就以java语言为入门写一点点串口程序。

虽然“搜索引擎是我的老师“,自己整理了一下代码,在以后也很有用处。

 

 

 

posted @ 2014-06-02 21:50  Monkey菜苗  阅读(253)  评论(0)    收藏  举报