Java串口编程.pdf

上传人:asd****56 文档编号:70322808 上传时间:2023-01-19 格式:PDF 页数:24 大小:269.56KB
返回 下载 相关 举报
Java串口编程.pdf_第1页
第1页 / 共24页
Java串口编程.pdf_第2页
第2页 / 共24页
点击查看更多>>
资源描述

《Java串口编程.pdf》由会员分享,可在线阅读,更多相关《Java串口编程.pdf(24页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、一个使用一个使用 JavaJava 读取串口的程序读取串口的程序作者:qyjohn以下是我写的用 Java 读取串口的程序,应一些网友的要求在这里贴出来。这个程序里面还有一些问题,也希望有经验的网友能够给我提点意见。这个简单的程序包括以下文件:IMU.java(主程序)ReadBuffer.java(从缓冲区读取一个消息)ReadSerial.java(读取串口数据并放入缓冲区)SerialBuffer.java(缓冲区)WriteSerial.java(不断的往串口送星号*)测试程序:SendCom.java(将一个数据文件往串口发送)SEND.TXT(供测试用的数据文件)在这个通讯程序中使

2、用了一个简单的协议,既不同的消息之间用星号*作为分隔。这个程序中的问题是ReadSerial 进程和 WriteSerial 进程不能够同时启动,出错信息是不能够打开串口,因为同样一个串口不能够同时被打开两次(在 ReadSerial 中声明了 FileReader测试程序:SendCom.java(将一个数据文件往串口发送)SEND.TXT(供测试用的数据文件)在这个通讯程序中使用了一个简单的协议,既不同的消息之间用星号*作为分隔。这个程序中的问题是ReadSerial 进程和 WriteSerial 进程不能够同时启动,出错信息是不能够打开串口,因为同样一个串口不能够同时被打开两次(在 R

3、eadSerial 中声明了 FileReader 和在 WriteSerial 中声明了 FileWriter)。这样是不能够实现全双工通讯的。不知道有没有做过的大侠能够讲讲处理的办法。/*IMU.java 1.0*Main Program for Serial Communication*Created:March 27,2001*Author:Qingye Jiang(John)*American GNC Corporation*888 Easy St,Simi Valley CA 93065-1812*Contact:(805)582-0582(Tel),(805)582-0098(F

4、ax)*qjiangtsinghua.edu*/import java.io.*;class IMUpublic static void main(String args)/TO DO:Add your JAVA codes hereFile ComPort=new File(COM1);SerialBuffer SB=new SerialBuffer();ReadSerial r1=new ReadSerial(SB,ComPort);ReadBuffer r2=new ReadBuffer(SB);WriteSerial r3=new WriteSerial(ComPort);r1.sta

5、rt();r2.start();r3.start();/*ReadBuffer.java 1.0*Program to Read the Serial Buffer*Created:March 27,2001*Author:Qingye Jiang(John)*American GNC Corporation*888 Easy St,Simi Valley CA 93065-1812*Contact:(805)582-0582(Tel),(805)582-0098(Fax)*qjiangtsinghua.edu*/import java.io.*;public class ReadBuffer

6、 extends Threadprivate SerialBuffer ComBuffer;public ReadBuffer(SerialBuffer SB)ComBuffer=SB;public void run()String Msg;while(true)Msg=ComBuffer.GetMsg();System.out.println(Msg);/*ReadSerial.java 1.0*Program to read characters from the serial port and put it*to the buffer*Created:March 27,2001*Auth

7、or:Qingye Jiang(John)*American GNC Corporation*888 Easy St,Simi Valley CA 93065-1812*Contact:(805)582-0582(Tel),(805)582-0098(Fax)*qjiangtsinghua.edu*/import java.io.*;public class ReadSerial extends Threadprivate SerialBuffer ComBuffer;private File ComPort;public ReadSerial(SerialBuffer SB,File Por

8、t)ComBuffer=SB;ComPort=Port;public void run()int c;tryFileReader in=new FileReader(ComPort);while(true)c=in.read();ComBuffer.PutChar(c);tryFileReader in=new FileReader(ComPort);while(true)c=in.read();ComBuffer.PutChar(c);catch(IOException e)/*SerialBuffer.java 1.0*Class that implements the serial bu

9、ffer*Created:March 27,2001*Author:Qingye Jiang(John)*American GNC Corporation*888 Easy St,Simi Valley CA 93065-1812*Contact:(805)582-0582(Tel),(805)582-0098(Fax)*qjiangtsinghua.edu*/public class SerialBufferprivate String Content=;private String CurrentMsg,TempContent;private boolean available=false

10、;public synchronized String GetMsg()int SepMark;if(SepMark=Content.indexOf(*)=-1)available=false;while(available=false)trywait();catch(InterruptedException e)SepMark=Content.indexOf(*);CurrentMsg=Content.substring(0,SepMark);TempContent=Content.substring(SepMark+1);Content=TempContent;notifyAll();re

11、turn CurrentMsg;public synchronized void PutChar(int c)Character d=new Character(char)c);Content=Content.concat(d.toString();if(c=*)available=true;notifyAll();/*WriteSerial.java 1.0*Program to send a character to the serial port*Created:March 27,2001*Author:Qingye Jiang(John)*American GNC Corporatio

12、n*888 Easy St,Simi Valley CA 93065-1812*Contact:(805)582-0582(Tel),(805)582-0098(Fax)*qjiangtsinghua.edu*/import java.io.*;public class WriteSerial extends Threadprivate SerialBuffer ComBuffer;private File ComPort;public WriteSerial(File Port)ComPort=Port;public void run()int c;tryFileWriter out=new

13、 FileWriter(ComPort);while(true)out.write(*);catch(IOException e)System.out.println(e.getMessage();import java.io.*;public class SendCompublic static void main(String args)File OutFile=new File(SEND.TXT);File ComPort=new File(COM2);int c;tryFileReader in=new FileReader(OutFile);FileWriter out=new Fi

14、leWriter(ComPort);while(c=in.read()!=-1)out.write(c);in.close();out.close();catch(IOException e)SEND.TXT*This is a sample of the data file for program testing.*It should be in the same directory as the SendCom.class file.*When you run this sample program,connect your COM1 and COM2 with aserial cable

15、 so that you can test this program on one machine.Ifyou have two machines,you can connect the two machine via a serialcable and test it.Modified the definition of ComPort in the programif necessary.*Thank you for testing this program.If you have any suggestions pleasekindly let me know.*一个嵌入式系统通常需要通

16、过串口与其主控系统进行全双工通讯,譬如一个流水线控制系统需要不断的接受从主控系统发送来的查询和控制信息,并将执行结果或查询结果发送回主控系统。本文介绍了一个简单的通过串口实现全双工通讯的 Java 类库,该类库大大的简化了对串口进行操作的过程。本类库主要包括:SerialBean.java(与其他应用程序的接口),SerialBuffer.java(用来保存从串口所接收数据的缓冲区),ReadSerial.java(从串口读取数据的程序)。另外本类库还提供了一个例程 SerialExample.java 作为示范。在下面的内容中将逐一对这几个部分进行详细介绍。1.SerialBeanSeria

17、lBean 是本类库与其他应用程序的接口。该类库中定义了 SerialBean 的构造方法以及初始化串口,从串口读取数据,往串口写入数据以及关闭串口的函数。具体介绍如下:public SerialBean(int PortID)本函数构造一个指向特定串口的 SerialBean,该串口由参数 PortID 所指定。PortID=1 表示 COM1,PortID=2 表示 COM2,由此类推。public int Initialize()本函数初始化所指定的串口并返回初始化结果。如果初始化成功返回 1,否则返回-1。初始化的结果是该串口被SerialBean 独占性使用,其参数被设置为 9600

18、,N,8,1。如果串口被成功初始化,则打开一个进程读取从串口传入的数据并将其保存在缓冲区中。public String ReadPort(int Length)本函数从串口(缓冲区)中读取指定长度的一个字符串。参数 Length 指定所返回字符串的长度。public void WritePort(String Msg)本函数向串口发送一个字符串。参数 Msg 是需要发送的字符串。public void ClosePort()本函数停止串口检测进程并关闭串口。SerialBean 的源代码如下:package serial;import java.io.*;import java.util.*;

19、import m.*;/*This bean provides some basic functions to implement full dulplex*information exchange through the srial port.*/public class SerialBeanstatic String PortName;CommPortIdentifier portId;SerialPort serialPort;static OutputStream out;static InputStream in;SerialBuffer SB;ReadSerial RT;/*Con

20、structor*param PortID the ID of the serial to be used.1 for COM1,*2 for COM2,etc.*/public SerialBean(int PortID)PortName=COM+PortID;/*This function initialize the serial port for communication.It starts a*thread which consistently monitors the serial port.Any signal captured*from the serial port is

21、stored into a buffer area.*/public int Initialize()int InitSuccess=1;int InitFail=-1;tryportId=CommPortIdentifier.getPortIdentifier(PortName);tryserialPort=(SerialPort)portId.open(Serial_Communication,2000);catch(PortInUseException e)return InitFail;/Use InputStream in to read from the serial port,a

22、nd OutputStream/out to write to the serial port.tryin=serialPort.getInputStream();out=serialPort.getOutputStream();catch(IOException e)return InitFail;/Initialize the communication parameters to 9600,8,1,none.tryserialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPo

23、rt.PARITY_NONE);catch(UnsupportedCommOperationException e)return InitFail;catch(NoSuchPortException e)return InitFail;/when successfully open the serial port,create a new serial buffer,/then create a thread that consistently accepts incoming signals from/the serial port.Incoming signals are stored i

24、n the serial buffer.SB=new SerialBuffer();RT=new ReadSerial(SB,in);RT.start();/return success informationreturn InitSuccess;/*This function returns a string with a certain length from the incoming*messages.*param Length The length of the string to be returned.*/public String ReadPort(int Length)Stri

25、ng Msg;Msg=SB.GetMsg(Length);return Msg;/*This function sends a message through the serial port.*param Msg The string to be sent.*/public void WritePort(String Msg)int c;tryfor(int i=0;i Msg.length();i+)out.write(Msg.charAt(i);catch(IOException e)/*This function closes the serial port in use.*/publi

26、c void ClosePort()RT.stop();serialPort.close();Java 串行端口通讯技术串行端口通讯技术作者:陈先波()写于:2004/4/28主页:JavaG了解串行通讯了解串行通讯串行通讯协议有很多种,像 RS232,RS485,RS422,甚至现今流行的 USB 等都是串行通讯协议。而串行通讯技术的应用无处不在。可能大家见的最多就是电脑的串口与 Modem 的通讯。记得在 PC 机刚开始在中国流行起来时(大约是在 90 年代前五年),那时甚至有人用一条串行线进行两台电脑之间的数据共享。除了这些,手机,PDA,USB 鼠标、键盘等等都是以串行通讯的方式与电脑

27、连接。而笔者工作性质的关系,所接触到的就更多了,像多串口卡,各种种类的具有串口通讯接口的检测与测量仪器,串口通讯的网络设备等。虽然串行通讯有很多种,但笔者所知的在整个电子通讯产品方面,以 RS232 的通讯方式最为多见。虽然 USB 接口的电子产品也是层出不穷,但了解一下 Java 在串行通讯方面的技术还有有必要的,说不定有哪位读者还想用此技术写一个 PDA 与电脑之间数据共享的程序呢。本文主要以 RS232 为主来讲解 JAVA 的串行通讯技术。RS232 通讯基础通讯基础RS-232-C(又称 EIA RS-232-C,以下简称 RS232)是在 1970 年由美国电子工业协会(EIA)联

28、合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。RS232 是一个全双工的通讯协议,它可以同时进行数据接收和发送的工作。RS232 的端口通常有两种:9 针(DB9)和 25 针(DB25)。DB9 和 DB25 的常用针脚定义9 针串口(DB9)25 针串口(DB25)针号功能说明缩写 针号功能说明缩写1数据载波检测 DCD8数据载波检测 DCD2接收数据RXD3接收数据RXD3发送数据TXD2发送数据TXD4数据终端准备 DTR20数据终端准备 DTR5信号地GND7信号地GND6数据设备准备好 DSR6数据准备好DSR7请求发送RTS4请求发送RTS8清除发送

29、CTS5清除发送CTS9振铃指示RI22振铃指示RI常见的边线方式常见的通讯方式是三线式,这种方式是将两个 RS232 设备的发送端(TXD)和接收端(RXD)及接地端(GND)互相连接,也是许多读者所知道的连接方式:(9 针)2(RXD)-3(TXD3(TXD)-2(TXD)5(GND)-5(GND)(25 针)2(RXD)-3(TXD3(TXD)-2(RXD)7(GND)-7(GND)这种方式分别将两端的 RS232 接口的 2-3,3-2,5(7)-5(7)针脚连接起来。其中 2 是数据接收线(RXD),3 是数据发送线(TXD),5(7)是接地(RND)。如果有一台式 PC,和一部 N

30、oteBook 电脑,就可以用这种方式连线了。用三线式可以将大多数的 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 之间会有 315V 左右的负电压,表示它是 TXD 针脚。安装安装 Java Commu

31、nications APISun 的 J2SE 中并没有直接提供以上提到的任何一种串行通讯协议的开发包,而是以独立的 jar 包形式发布在 网站上(从这里下载)-即 comm.jar,称之为 JavatmCommunications API,它是 J2SE的标准扩展。comm.jar 并不是最近才有,早在 1998 年时,sun 就已经发布了这个开发包。comm.jar 分别提供了对常用的 RS232 串行端口和 IEEE1284 并行端口通讯的支持。目前 sun 发布的 comm.jar 只有Windows 和 Solaris 平台两个版本,如果你需要 Linux 平台下的,可以在http:

32、/ 找到。在使用 comm.jar 之前,必须知道如何安装它。这也是困扰许多初学 java RS232 通讯者的一个难题。如果我们电脑上安装了 JDK,它将同时为我们安装一份 JRE(Java Runtime Entironment),通常我们运行程序时都是以 JRE 来运行的。所以以下的安装适用于 JRE。如果你是用 JDK 来运行程序的,请将相应的改成。下载了 comm.jar 开发包后,与之一起的还有两个重要的文件,win32com.dll 和 m.properties。comm.jar 提供了通讯用的 java API,而 win32com.dll 提供了供 comm.jar 调用的本

33、地驱动接口。而m.properties 是这个驱动的类配置文件。首先将 comm.jar 复制到libext 目录。再将 win21com.dll 复制到你的 RS232 应用程序运行的目录,即 user.dir。然后将 m.properties 复制到lib 目录。通讯前的准备通讯前的准备如果你手头上没有现成的提供了标准 RS232 串口的设备,你可以将自己的电脑模拟成两台不同的串口设备。通常电脑主机后面的面板提供了两个 9 针的串口,请将这两个串口的 2,3,5 脚按前面介绍的方法连接。电子市场都有现成的连接头卖,请不要买那种封装的严严实实的接头,而要买用螺丝封装可以拆开的连接头,这样可以

34、方便自己根据需要连接各个针脚。Comm API 基础基础我无意于在此详细描述 Comm API 每个类和接口的用法,但我会介绍 Comm API 的类结构和几个重要的 API 用法。所有的 comm API 位于 m 包下面。从 Comm API 的 javadoc 来看,它介绍给我们的只有区区以下 13 个类或接口:m.CommDm.CommPm.ParallelPm.SerialPm.CommPortIm.CommPortOwnershipLm.ParallelPortEm.SerialPortEm.ParallelPortEventListener(extends java.util.E

35、ventListener)m.SerialPortEventListener(extends java.util.EventListener)m.NoSuchPortEm.PortInUseEm.UnsupportedCommOperationException下面讲解一下几个主要类或接口。1.枚举出系统所有的 RS232 端口在开始使用 RS232 端口通讯之前,我们想知道系统有哪些端口是可用的,以下代码列出系统中所有可用的 RS232 端口:Enumeration en=CommPortIdentifier.getPortIdentifiers();CommPortIdentifier p

36、ortId;while(en.hasMoreElements()portId=(CommPortIdentifier)en.nextElement();/*如果端口类型是串口,则打印出其端口信息*/if(portId.getPortType()=CommPortIdentifier.PORT_SERIAL)System.out.println(portId.getName();在我的电脑上以上程序输出以下结果:COM1COM2CommPortIdentifier 类的 getPortIdentifiers 方法可以找到系统所有的串口,每个串口对应一个CommPortIdentifier 类的实

37、例。2.打开端口如果你使用端口,必须先打开它。tryCommPort serialPort=portId.open(My App,60);/*从端口中读取数据*/InputStream input=serialPort.getInputStream();input.read(.);/*往端口中写数据*/OutputStream output=serialPort.getOutputStream();output.write(.).catch(PortInUseException ex).通过 CommPortIdentifier 的 open 方法可以返回一个 CommPort 对象。open

38、 方法有两个参数,第一个是 String,通常设置为你的应用程序的名字。第二个参数是时间,即开启端口超时的毫秒数。当端口被另外的应用程序占用时,将抛出 PortInUseException 异常。在这里 CommPortIdentifier 类和 CommPort 类有什么区别呢?其实它们两者是一一对应的关系。CommPortIdentifier 主要负责端口的初始化和开启,以及管理它们的占有权。而 CommPort 则是跟实际的输入和输出功能有关的。通过 CommPort 的 getInputStream()可以取得端口的输入流,它是java.io.InputStream 接口的一个实例。我

39、们可以用标准的 InputStream 的操作接口来读取流中的数据,就像通过 FileInputSteam 读取文件的内容一样。相应的,CommPort 的 getOutputStream 可以获得端口的输出流,这样就可以往串口输出数据了。3.关闭端口使用完的端口,必须记得将其关闭,这样可以让其它的程序有机会使用它,不然其它程序使用该端口时可能会抛出端口正在使用中的错误。很奇怪的是,CommPortIdentifier 类只提供了开启端口的方法,而要关闭端口,则要调用 CommPort 类的 close()方法。通讯方式通讯方式CommPort 的输入流的读取方式与文件的输入流有些不一样,那就

40、是你可能永远不知这个 InputStream何时结束,除非对方的 OutputStream 向你发送了一个特定数据表示发送结束,你收到这个特定字符后,再行关闭你的 InputStream。而 comm.jar 提供了两种灵活的方式让你读取数据。1.轮询方式(Polling)举个例子,你同 GF 相约一起出门去看电影,但你的 GF 好打扮,这一打扮可能就是半小时甚至一小时以上。这时你就耐不住了,每两分钟就催问一次“好了没?”,如此这样,直到你的 GF 说 OK 了才算完。这个就叫轮询(Polling)。在程序中,轮询通常设计成一个封闭的循环,当满足某个条件时即结束循环。刚才那个例子中,你的GF

41、说“OK 了!”,这个就是结束你轮询的条件。在单线程的程序中,当循环一直执行某项任务而又无法预知它何时结束时,此时你的程序看起来可能就像死机一样。在 VB 程序中,这个问题可以用在循环结构中插入一个 doEvent 语句来解决。而 Java 中,最好的方式是使用线程,就像以下代码片断一样。public TestPort extend Thread.InputStream input=serialPort.getInputStream();StringBuffer buf=new StringBuffer();boolean stopped=false;.public void run()try

42、 while(!stopped)int ch=input.read();if(ch=q|ch=Q)/*结束读取,关闭端口.*/stopped=true;.elsebuf.append(char)ch);.catch(InterruptedException e)2.监听方式(listening)Comm API 支持标准的 Java Bean 型的事件模型。也就是说,你可以使用类似 AddXXXListener 这样的方法为一个串口注册自己的监听器,以监听方式进行数据读取。如要对端口监听,你必须先取得 CommPortIdentifier 类的一个实例,CommPort serialPort=

43、portId.open(My App,60);从而取得 SerialPort,再调用它的 addEventListener 方法为它添加监听器,serialPort.addEventListener(new MyPortListener();SerialPort 的监听器必须继承于 SerialPortEventListener 接口。当有任何 SerialPort 的事件发生时,将自动调用监听器中的 serialEvent 方法。Serial Event 有以下几种类型:BI-通讯中断.CD-载波检测.CTS-清除发送.DATA_AVAILABLE-有数据到达.DSR-数据设备准备好.FE-

44、帧错误.OE-溢位错误.OUTPUT_BUFFER_EMPTY-输出缓冲区已清空.PE-奇偶校验错.RI-振铃指示.下面是一个监听器的示例,public void MyPortListener implements SerialPortEventListenerpublic void serialEvent(SerialPortEvent evt)switch(evt.getEventType()case SerialPortEvent.CTS:System.out.println(CTS event occured.);break;case SerialPortEvent.CD:System

45、.out.println(CDevent occured.);break;case SerialPortEvent.BI:System.out.println(BIevent occured.);break;case SerialPortEvent.DSR:System.out.println(DSRevent occured.);break;case SerialPortEvent.FE:System.out.println(FEevent occured.);break;case SerialPortEvent.OE:System.out.println(OEevent occured.)

46、;break;case SerialPortEvent.PE:System.out.println(PEevent occured.);break;case SerialPortEvent.RI:System.out.println(RIevent occured.);break;case SerialPortEvent.OUTPUT_BUFFER_EMPTY:System.out.println(OUTPUT_BUFFER_EMPTYevent occured.);break;case SerialPortEvent.DATA_AVAILABLE:System.out.println(DAT

47、A_AVAILABLEevent occured.);int ch;StringBuffer buf=new StringBuffer();InputStream input=serialPort.getInputStreamtry while(ch=input.read()0)buf.append(char)ch);System.out.print(buf);catch(IOException e)break;这个监听器只是简单打印每个发生的事件名称。而对于大多数应用程序来说,通常关心是DATA_AVAILABLE 事件,当数据从外部设备传送到端口上来时将触发此事件。此时就可以使用前面提到过

48、的方法,serialPort.getInputStream()来从 InputStream 中读取数据了。完整的程序完整的程序为节省篇幅,本文只提供了一些代码片断来帮助读者来理解 Comm API 的用法。你可以从 Comm API的开发包中取得完整的可运行的演示程序。请先下载了 comm API 的开发包,解压之后有一个名为 Sample的目录,里面有几个演示程序,分别是:1)BlackBox:A Serial Port BlackBox application.2)ParallelBlackBox:A Parallel Port BlackBox application3)SerialDe

49、mo:A simpler SerialPort sample application4)Simple:A very simple comm application5)NullDriver:A template for driver writers.Can be used as the starting pointto write a driver for the Comm API.6)porting:A template CommPortIdentifier java file for people interestedin porting the Comm API to a new platform.其中,第 1),3),4)是关于 rs232 通讯的演示程序。而其它的,2)是并行端口的演示程序。5)和 6)是开发自己的端口驱动程序的模板程序,有兴趣的读者可以自行研究。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁