以前经常用C语言操作串口,实现一些发送接收之类的小功能,最近项目中也用到了串口通信,不过语言变成了Java,这个搞起来略蛋疼。
Java说起来就是各种库各种引用,所以得到某些需求先google搜一把~~比如之前搞半天的读取网页内容,自己边琢磨边写,又是charset,又是proxy,又是什么browsertype的,晕头转向,最后拿Jsoup一会儿就搞定了……不过使用之前要充分考虑可扩展性和API的丰富程度,不然后面程序体积变大集成起来很蛋疼。好了废话不说,讲讲串口的问题……
总述
Java常用的(我用到的)串口工具有俩:javacomm和RXTX,前者只支持win32,后者32和64位和其他版本都有。使用方法类似,所以就放到一起说:
下载到压缩包会看到readme之类的提示,然后把对应的dll文件和jar文件分别拷贝到/bin和/lib目录下,然后在出问题的时候继续查看readme。接着跑一下附带的例程。
具体使用过程就是:配置端口波特率、校验位等信息;打开串口;写数据;读输出;关闭。这一系列步骤在写程序的时候一定不要弄颠倒了。
串口配置
需要配置的有4项:
波特率(baudrate)— 一般9600、115200即可
(数据位)dataBits— 一般8 bits
DATABITS_5:5 bits
DATABITS_6:6 bits
DATABITS_7:7 bits
DATABITS_8:8 bits
(停止位)stopBits — 一般1 stop bit
STOPBITS_1:1 stop bit
STOPBITS_2:2 stop bits
STOPBITS_1_5:1.5 stop bits
(校验位)parity — 不需校验位的话,选择SerialPort.PARITY_NONE
PARITY_NONE:no parity
PARITY_ODD:odd parity
PARITY_EVEN:even parity
PARITY_MARK:mark parity
PARITY_SPACE:space parity
流量控制模式(FlowControlMode) — 一般FLOWCONTROL_NONE
FLOWCONTROL_NONE: no flow control
FLOWCONTROL_RTSCTS_IN: RTS/CTS (hardware) flow control for input
FLOWCONTROL_RTSCTS_OUT:RTS/CTS (hardware) flow control for output
FLOWCONTROL_XONXOFF_IN:XON/XOFF (software) flow control for input
FLOWCONTROL_XONXOFF_OUT:XON/XOFF (software) flow control for output
事件监听
addEventListener(SerialPortEventListener lsnr)
用于监听串口事件(SerialEvents),可监听的事件有:
BI(Break interrupt)
CD(Carrier detect)
CTS(Clear to send)
DATA_AVAILABLE(Data available at the serial port)
DSR(Data set ready)
eventType(Deprecated. Replaced by getEventType method)
FE(Framing error)
OE(Overrun error)
OUTPUT_BUFFER_EMPTY(Output buffer is empty)
PE(Parity error)
RI(Ring indicator)
读数据
通过SerialPortEventListener来,读取到DATA_AVAILABLE,保存并处理串口内容。
写数据
使用getOutputStream来向串口发送数据,是发送数据的唯一方法。使用时,向OutPutStream中写入byte串即可,之后用SerialPortEventListener获取回馈结果。
RXTX例程(来自 这里 ):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
publicclassUSBCommimplementsSerialPortEventListener{
publicstaticfinalStringMESSAGE="MESSAGE TO BE SEND";
/**
* Stream for the storage of incoming data
*/
privateInputStreaminputStream;
/**
* Stream for the dispatching of data
*/
privateOutputStreamoutputStream;
/**
* Timeout of the USB port
*/
privatefinalintPORT_TIMEOUT=2000;
/**
* Representation of the serial port used for the communication
*/
publicSerialPortserialPort;
/**
* Buffer that stores the received bytes from the media
*/
protectedLinkedBlockingQueuereceivedBytes;
/**
* Builds a new manager for the communication via USB port.
* @exception IOException if an error occurred during the opening of the USB port
*/
publicUSBComm(Stringcomm)throwsIOException{
receivedBytes=newLinkedBlockingQueue(100000);
Stringport=comm;//place the right COM port here, OS dependent
//Check that the USB port exists and is recognized:
Enumeration>portList=CommPortIdentifier.getPortIdentifiers();
booleanportFound=false;
CommPortIdentifierportId=null;
while(portList.hasMoreElements()){
portId=(CommPortIdentifier)portList.nextElement();
if(portId.getPortType()==CommPortIdentifier.PORT_SERIAL){
if(portId.getName().equals(port)){
Log.logAndDisplay(LogLevel.INFO,"SerialConnection","Found port: "+port);
portFound=true;
break;
}
}
}
if(!portFound)
thrownewIOException("port "+port+" not found.");
try{
Log.logAndDisplay(LogLevel.INFO,"SerialConnection","USB port "+port+" opening...");
serialPort=(SerialPort)portId.open("USBCommunicator",PORT_TIMEOUT);
inputStream=serialPort.getInputStream();
outputStream=serialPort.getOutputStream();
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
Thread.sleep(1000);
serialPort.setSerialPortParams(serialPort.getBaudRate(),
serialPort.getDataBits(),
serialPort.getStopBits(),
serialPort.getParity());
serialPort.setFlowControlMode(serialPort.getFlowControlMode());
}catch(Exceptione){
System.err.println(e.getMessage());
thrownewIOException(e.getMessage());
}
}
publicvoidcloseUSB(){
//close the streams for serial port:
try{
inputStream.close();
outputStream.close();
}catch(IOExceptione){
System.err.println("Cannot close streams:"+e.getMessage());
}
}
/**
* Listener for USB events
*
* @param event new event occurred on the USB port
*/
publicvoidserialEvent(SerialPortEventevent){
switch(event.getEventType()){
caseSerialPortEvent.BI:
caseSerialPortEvent.OE:
caseSerialPortEvent.FE:
caseSerialPortEvent.PE:
caseSerialPortEvent.CD:
caseSerialPortEvent.CTS:
caseSerialPortEvent.DSR:
caseSerialPortEvent.RI:
caseSerialPortEvent.OUTPUT_BUFFER_EMPTY:
//nothing to do...
break;
caseSerialPortEvent.DATA_AVAILABLE:
bytereceived=-1;
do{
try{
received=(byte)inputStream.read();
}catch(IOExceptione){
System.err.println("Error reading USB:"+e.getMessage());
}
synchronized(receivedBytes){
try{
receivedBytes.add(received);
}catch(IllegalStateExceptionew){
System.err.println(ew.getMessage());
receivedBytes.poll();
receivedBytes.add(received);
}
}
}while(received!=-1);
break;
}
}
publicvoidwrite(byte[]buffer){
try{
outputStream.write(buffer);
//outputStream.flush();
}catch(IOExceptione){
System.err.println("Cannot write:"+e.getMessage());
}
}
publicstaticvoidmain(String[]args){
USBCommusb;
try{
usb=newUSBComm("COM73");// change to your port
byte[]b=MESSAGE.getBytes();
usb.write(b);
usb.serialPort.close();
usb.closeUSB();
}catch(IOExceptione){
System.err.println("IOException:"+e.getMessage());
}
}
}
后记嗯……好像也啥都没写的样子(我会告诉你这篇其实是测试帖代码效果的吗)……总之去看javacomm附带有例程 / RXTX的例程就可以了……