java实现串口.docx
《java实现串口.docx》由会员分享,可在线阅读,更多相关《java实现串口.docx(18页珍藏版)》请在冰点文库上搜索。
![java实现串口.docx](https://file1.bingdoc.com/fileroot1/2023-6/11/49b20647-6a59-458d-b931-01358bb6f1be/49b20647-6a59-458d-b931-01358bb6f1be1.gif)
java实现串口
∙Java实现对Windows串口的读写
2007-06-1814:
48:
49
大中小
Jm简介
Jm是Sun公司提供的,用于开发平台独立的通讯应用程序的扩展API。
(ps:
这里javax的x很准确地表明了它是一个扩展包,而不是核心包(corepackage),但由于历史原因,javax下的并不都是扩展包,比如swing包已经是Java核心架构的一部分了,不过为了与Java1.1编码兼容,仍使用javax.swing。
)m可以访问RS232接口(串口)及有限制地访问IEEE-1284(并口)。
下载
需要到其官方主页
安装
这里的所谓安装就是把三个重要的文件放到指定的目录下。
将下载的文件解压缩后,在\javacomm20-win32\commapi目录下有必需的三个文件comm.jar,m.properties和win32comm.dll。
将文件comm.jar拷贝到%JAVA_HOME%\jre\lib\ext;文件m.properties拷贝到%JAVA_HOME%\jre\lib;文件win32comm.dll拷贝到%JAVA_HOME%\bin。
注意%JAVA_HOME%是jdk的路径,而非jre。
API
在m下有13个类和接口,分别是
4个接口
CommDriver可负载设备(theloadabledevice)驱动程序接口的一部分
CommPortOwnershipListener传递各种通讯端口的所有权事件
ParallelPortEventListener传递并行端口事件
SerialPortEventListener传递串行端口事件
6个类
CommPort通讯端口
CommPortIdentifier通讯端口管理
ParallelPort并行通讯端口
ParallelPortEvent并行端口事件
SerialPortRS-232串行通讯端口
SerialPortEvent串行端口事件
3个异常类
NoSuchPortException当驱动程序不能找到指定端口时抛出
PortInUseException当碰到指定端口正在使用中时抛出
UnsupportedCommOperationException驱动程序不允许指定操作时抛出
实例
同API一起下载的还有一个examples文件,里面有6个程序。
首先看最简单的读、写程序。
读串口的例程
importjava.io.*;
importjava.util.*;
importm.*;
publicclassSimpleReadimplementsRunnable,SerialPortEventListener{
staticCommPortIdentifierportId;
staticEnumerationportList;//枚举类
InputStreaminputStream;
SerialPortserialPort;
ThreadreadThread;
publicstaticvoidmain(String[]args){
portList=CommPortIdentifier.getPortIdentifiers();/*不带参数的getPortIdentifiers方法获得一个枚举对象,该对象又包含了系统中管理每个端口的CommPortIdentifier对象。
注意这里的端口不仅仅是指串口,也包括并口。
这个方法还可以带参数。
getPortIdentifiers(CommPort)获得与已经被应用程序打开的端口相对应的CommPortIdentifier对象。
getPortIdentifier(StringportName)获取指定端口名(比如“COM1”)的CommPortIdentifier对象。
*/
while(portList.hasMoreElements()){
portId=(CommPortIdentifier)portList.nextElement();
if(portId.getPortType()==CommPortIdentifier.PORT_SERIAL)/*getPortType方法返回端口类型*/{
//if(portId.getName().equals("COM1"))/*找Windows下的第一个串口*/{
if(portId.getName().equals("/dev/term/a"))/*找Unix-like系统下的第一个串口*/{
SimpleReadreader=newSimpleRead();
}
}
}
}
publicSimpleRead(){
try{
serialPort=(SerialPort)portId.open("SimpleReadApp",2000);/*open方法打开通讯端口,获得一个CommPort对象。
它使程序独占端口。
如果端口正被其他应用程序占用,将使用CommPortOwnershipListener事件机制,传递一个PORT_OWNERSHIP_REQUESTED事件。
每个端口都关联一个InputStream何一个OutputStream。
如果端口是用open方法打开的,那么任何的getInputStream都将返回相同的数据流对象,除非有close被调用。
有两个参数,第一个为应用程序名;第二个参数是在端口打开时阻塞等待的毫秒数。
*/
}catch(PortInUseExceptione){}
try{
inputStream=serialPort.getInputStream();/*获取端口的输入流对象*/
}catch(IOExceptione){}
try{
serialPort.addEventListener(this);/*注册一个SerialPortEventListener事件来监听串口事件*/
}catch(TooManyListenersExceptione){}
serialPort.notifyOnDataAvailable(true);/*数据可用*/
try{
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);/*设置串口初始化参数,依次是波特率,数据位,停止位和校验*/
}catch(UnsupportedCommOperationExceptione){}
readThread=newThread(this);
readThread.start();
}
publicvoidrun(){
try{
Thread.sleep(20000);
}catch(InterruptedExceptione){}
}
//串口事件
publicvoidserialEvent(SerialPortEventevent){
switch(event.getEventType()){
caseSerialPortEvent.BI:
/*Breakinterrupt,通讯中断*/
caseSerialPortEvent.OE:
/*Overrunerror,溢位错误*/
caseSerialPortEvent.FE:
/*Framingerror,传帧错误*/
caseSerialPortEvent.PE:
/*Parityerror,校验错误*/
caseSerialPortEvent.CD:
/*Carrierdetect,载波检测*/
caseSerialPortEvent.CTS:
/*Cleartosend,清除发送*/
caseSerialPortEvent.DSR:
/*Datasetready,数据设备就绪*/
caseSerialPortEvent.RI:
/*Ringindicator,响铃指示*/
caseSerialPortEvent.OUTPUT_BUFFER_EMPTY:
/*Outputbufferisempty,输出缓冲区清空*/
break;
caseSerialPortEvent.DATA_AVAILABLE:
/*Dataavailableattheserialport,端口有可用数据。
读到缓冲数组,输出到终端*/
byte[]readBuffer=newbyte[20];
try{
while(inputStream.available()>0){
intnumBytes=inputStream.read(readBuffer);
}
System.out.print(newString(readBuffer));
}catch(IOExceptione){}
break;
}
}
}
(PS:
不推荐Thread的这种用法,详见《CoreJavaVolumeII》)
写串口的例程
把字符串"Hello,world!
\n"写到系统的第一个串口
importjava.io.*;
importjava.util.*;
importm.*;
publicclassSimpleWrite{
staticEnumerationportList;
staticCommPortIdentifierportId;
staticStringmessageString="Hello,world!
\n";
staticSerialPortserialPort;
staticOutputStreamoutputStream;
publicstaticvoidmain(String[]args){
portList=CommPortIdentifier.getPortIdentifiers();
while(portList.hasMoreElements()){
portId=(CommPortIdentifier)portList.nextElement();
if(portId.getPortType()==CommPortIdentifier.PORT_SERIAL){
//if(portId.getName().equals("COM1")){
if(portId.getName().equals("/dev/term/a")){
try{
serialPort=(SerialPort)
portId.open("SimpleWriteApp",2000);
}catch(PortInUseExceptione){}
try{
outputStream=serialPort.getOutputStream();
}catch(IOExceptione){}
try{
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
}catch(UnsupportedCommOperationExceptione){}
try{
outputStream.write(messageString.getBytes());
}catch(IOExceptione){}
}
}
}
}
}
上面两个例程都经过了简化,在打开端口,并且传输结束后没有关闭数据流和串口。
在例程中我们看到CommPortIdentifier提供了打开通讯端口的方法open,但却没有相应关闭端口的方法,关闭端口需要调用m.CommPort类的close()。
CommPort是这个包中的一个高级抽象,它定义了端口可作的各种事情:
获取I/O数据流对象,控制缓冲区大小,调整输入的处理。
Java串行端口通讯技术
作者:
陈先波(turbochen@)
写于:
2004/4/28
主页:
JavaG
了解串行通讯
串行通讯协议有很多种,像RS232,RS485,RS422,甚至现今流行的USB等都是串行通讯协议。
而串行通讯技术的应用无处不在。
可能大家见的最多就是电脑的串口与Modem的通讯。
记得在PC机刚开始在中国流行起来时(大约是在90年代前五年),那时甚至有人用一条串行线进行两台电脑之间的数据共享。
除了这些,手机,PDA,USB鼠标、键盘等等都是以串行通讯的方式与电脑连接。
而笔者工作性质的关系,所接触到的就更多了,像多串口卡,各种种类的具有串口通讯接口的检测与测量仪器,串口通讯的网络设备等。
虽然串行通讯有很多种,但笔者所知的在整个电子通讯产品方面,以RS232的通讯方式最为多见。
虽然USB接口的电子产品也是层出不穷,但了解一下Java在串行通讯方面的技术还有有必要的,说不定有哪位读者还想用此技术写一个PDA与电脑之间数据共享的程序呢。
本文主要以RS232为主来讲解JAVA的串行通讯技术。
RS232通讯基础
RS-232-C(又称EIARS-232-C,以下简称RS232)是在1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。
RS232是一个全双工的通讯协议,它可以同时进行数据接收和发送的工作。
RS232的端口通常有两种:
9针(DB9)和25针(DB25)。
DB9和DB25的常用针脚定义
9针串口(DB9)
25针串口(DB25)
针号
功能说明
缩写
针号
功能说明
缩写
1
数据载波检测
DCD
8
数据载波检测
DCD
2
接收数据
RXD
3
接收数据
RXD
3
发送数据
TXD
2
发送数据
TXD
4
数据终端准备
DTR
20
数据终端准备
DTR
5
信号地
GND
7
信号地
GND
6
数据设备准备好
DSR
6
数据准备好
DSR
7
请求发送
RTS
4
请求发送
RTS
8
清除发送
CTS
5
清除发送
CTS
9
振铃指示
RI
22
振铃指示
RI
常见的边线方式
常见的通讯方式是三线式,这种方式是将两个RS232设备的发送端(TXD)和接收端(RXD)及接地端(GND)互相连接,也是许多读者所知道的连接方式:
(9针)
2(RXD)
---------
3(TXD)
3(TXD)
---------
2(TXD)
5(GND)
---------
5(GND)
(25针)
2(RXD)
---------
3(TXD
3(TXD)
---------
2(RXD)
7(GND)
---------
7(GND)
这种方式分别将两端的RS232接口的2--3,3---2,5(7)---5(7)针脚连接起来。
其中2是数据接收线(RXD),3是数据发送线(TXD),5(7)是接地(RND)。
如果有一台式PC,和一部NoteBook电脑,就可以用这种方式连线了。
用三线式可以将大多数的RS232设备连接起来。
但如果你认死了2--3,3--2,5(7)--5(7)对接这个理,会发现在连某些RS232设备时并不奏效。
这是因为有些设备在电路内部已将2和3线调换过来了,你只要2,3,5(7)针一一对应就行了。
小技巧:
如何辨别TXD和RXD端口?
搞电子的人手边应该常备一个电表,用来测测电压,电阻什么的会很有用。
你只要分别测一下RS232端口的2--5或3--5针脚之间的电压,通常TXD针脚与GND之间会有3~15V左右的负电压,表示它是TXD针脚。
安装JavaCommunicationsAPI
Sun的J2SE中并没有直接提供以上提到的任何一种串行通讯协议的开发包,而是以独立的jar包形式发布在网站上(从这里下载)----即comm.jar,称之为JavatmCommunicationsAPI,它是J2SE的标准扩展。
comm.jar并不是最近才有,早在1998年时,sun就已经发布了这个开发包。
comm.jar分别提供了对常用的RS232串行端口和IEEE1284并行端口通讯的支持。
目前sun发布的comm.jar只有Windows和Solaris平台两个版本,如果你需要Linux平台下的,可以在
在使用comm.jar之前,必须知道如何安装它。
这也是困扰许多初学javaRS232通讯者的一个难题。
如果我们电脑上安装了JDK,它将同时为我们安装一份JRE(JavaRuntimeEntironment),通常我们运行程序时都是以JRE来运行的。
所以以下的安装适用于JRE。
如果你是用JDK来运行程序的,请将相应的改成。
下载了comm.jar开发包后,与之一起的还有两个重要的文件,win32com.dll和m.properties。
comm.jar提供了通讯用的javaAPI,而win32com.dll提供了供comm.jar调用的本地驱动接口。
而m.properties是这个驱动的类配置文件。
首先将comm.jar复制到\lib\ext目录。
再将win21com.dll复制到你的RS232应用程序运行的目录,即user.dir。
然后将m.properties复制到\lib目录。
通讯前的准备
如果你手头上没有现成的提供了标准RS232串口的设备,你可以将自己的电脑模拟成两台不同的串口设备。
通常电脑主机后面的面板提供了两个9针的串口,请将这两个串口的2,3,5脚按前面介绍的方法连接。
电子市场都有现成的连接头卖,请不要买那种封装的严严实实的接头,而要买用螺丝封装可以拆开的连接头,这样可以方便自己根据需要连接各个针脚。
CommAPI基础
我无意于在此详细描述CommAPI每个类和接口的用法,但我会介绍CommAPI的类结构和几个重要的API用法。
所有的commAPI位于m包下面。
从CommAPI的javadoc来看,它介绍给我们的只有区区以下13个类或接口:
m.CommDriver
m.CommPort
m.ParallelPort
m.SerialPort
m.CommPortIdentifier
m.CommPortOwnershipListener
m.ParallelPortEvent
m.SerialPortEvent
m.ParallelPortEventListener(extendsjava.util.EventListener)
m.SerialPortEventL