|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
但是一些大型开发或者是保密型比较高的项目都会用java,原因有2点,一:java是开源的,不怕别人留后门,偷我工具,.net就不一样了,保持微软的一向风格,源代码不公开懂得串行通信
串行通信协定有良多种,像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的经常使用针脚界说
罕见的边线体例
罕见的通信体例是三线式,这类体例是将两个RS232设备的发送端(TXD)和吸收端(RXD)及接地端(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包情势公布在java.sun.com网站上(从这里下载)----即comm.jar,称之为JavatmCommunicationsAPI,它是J2SE的尺度扩大。comm.jar并非比来才有,早在1998年时,sun就已公布了这个开辟包。comm.jar分离供应了对经常使用的RS232串行端口和IEEE1284并行端口通信的撑持。今朝sun公布的comm.jar只要Windows和Solaris平台两个版本,假如你必要Linux平台下的,能够在http://www.geeksville.com/~kevinh/linuxcomm.html找到。
在利用comm.jar之前,必需晓得怎样安装它。这也是困扰很多初学javaRS232通信者的一个困难。假如我们电脑上安装了JDK,它将同时为我们安装一份JRE(JavaRuntimeEntironment),一般我们运转程序时都是以JRE来运转的。以是以下的安装合用于JRE。假如你是用JDK来运转程序的,请将响应的改成。
下载了comm.jar开辟包后,与之一同的另有两个主要的文件,win32com.dll和javax.comm.properties。comm.jar供应了通信用的javaAPI,而win32com.dll供应了供comm.jar挪用的当地驱动接口。而javax.comm.properties是这个驱动的类设置文件。起首将comm.jar复制到libext目次。再将win21com.dll复制到你的RS232使用程序运转的目次,即user.dir。然后将javax.comm.properties复制到lib目次。
通信前的筹办
假如你手头上没有现成的供应了尺度RS232串口的设备,你能够将本人的电脑摹拟成两台分歧的串口设备。一般电脑主机前面的面板供应了两个9针的串口,请将这两个串口的2,3,5脚按后面先容的办法毗连。电子市场都有现成的毗连头卖,请不要买那种封装的结结实实的讨论,而要买用螺丝封装能够拆开的毗连头,如许能够便利本人依据必要毗连各个针脚。
CommAPI基本
我偶然于在此具体形貌CommAPI每一个类和接口的用法,但我会先容CommAPI的类布局和几个主要的API用法。
一切的commAPI位于javax.comm包上面。从CommAPI的javadoc来看,它先容给我们的只要戋戋以下13个类或接口:
javax.comm.CommDriver
javax.comm.CommPort
javax.comm.ParallelPort
javax.comm.SerialPort
javax.comm.CommPortIdentifier
javax.comm.CommPortOwnershipListener
javax.comm.ParallelPortEvent
javax.comm.SerialPortEvent
javax.comm.ParallelPortEventListener(extendsjava.util.EventListener)
javax.comm.SerialPortEventListener(extendsjava.util.EventListener)
javax.comm.NoSuchPortException
javax.comm.PortInUseException
javax.comm.UnsupportedCommOperationException
上面解说一下几个次要类或接口。
1.列举出体系一切的RS232端口
在入手下手利用RS232端口通信之前,我们想晓得体系有哪些端口是可用的,以下代码列出体系中一切可用的RS232端口:
Enumerationen=CommPortIdentifier.getPortIdentifiers();
CommPortIdentifierportId;
while(en.hasMoreElements())
{
portId=(CommPortIdentifier)en.nextElement();
/*假如端口范例是串口,则打印出其端口信息*/
if(portId.getPortType()==CommPortIdentifier.PORT_SERIAL)
{
System.out.println(portId.getName());
}
}
在我的电脑上以上程序输入以下了局:
COM1
COM2
CommPortIdentifier类的getPortIdentifiers办法能够找到体系一切的串口,每一个串口对应一个CommPortIdentifier类的实例。
2.翻开端口
假如你利用端口,必需先翻开它。
try{
CommPortserialPort=portId.open("MyApp",60);
/*从端口中读取数据*/
InputStreaminput=serialPort.getInputStream();
input.read(...);
/*往端口中写数据*/
OutputStreamoutput=serialPort.getOutputStream();
output.write(...)
...
}catch(PortInUseExceptionex)
{...}
经由过程CommPortIdentifier的open办法能够前往一个CommPort对象。open办法有两个参数,第一个是String,一般设置为你的使用程序的名字。第二个参数是工夫,即开启端口超时的毫秒数。当端口被别的的使用程序占用时,将抛出PortInUseException非常。
在这里CommPortIdentifier类和CommPort类有甚么区分呢?实在它们二者是逐一对应的干系。CommPortIdentifier次要卖力端口的初始化和开启,和办理它们的占据权。而CommPort则是跟实践的输出和输入功效有关的。经由过程CommPort的getInputStream()能够获得端口的输出流,它是java.io.InputStream接口的一个实例。我们能够用尺度的InputStream的操纵接口来读取流中的数据,就像经由过程FileInputSteam读取文件的内容一样。响应的,CommPort的getOutputStream能够取得端口的输入流,如许就能够往串口输入数据了。
3.封闭端口
利用完的端口,必需记得将其封闭,如许可让别的的程序无机会利用它,否则别的程序利用该端口时大概会抛出端口正在利用中的毛病。很奇异的是,CommPortIdentifier类只供应了开启端口的办法,而要封闭端口,则要挪用CommPort类的close()办法。
通信体例
CommPort的输出流的读取体例与文件的输出流有些纷歧样,那就是你大概永久不知这个InputStream什么时候停止,除非对方的OutputStream向你发送了一个特定命据暗示发送停止,你收到这个特定字符后,再行封闭你的InputStream。而comm.jar供应了两种天真的体例让你读取数据。
1.轮询体例(Polling)
举个例子,你同GF相约一同出门往看影戏,但你的GF好妆扮,这一妆扮大概就是半小时乃至一小时以上。这时候你就耐不住了,每两分钟就催问一次“好了没?”,云云如许,直到你的GF说OK了才算完。这个就叫轮询(Polling)。
在程序中,轮询一般计划成一个关闭的轮回,当满意某个前提时即停止轮回。方才谁人例子中,你的GF说“OK了!”,这个就是停止你轮询的前提。在单线程的程序中,当轮回一向实行某项义务而又没法预知它什么时候停止时,此时你的程序看起来大概就像逝世机一样。在VB程序中,这个成绩能够用在轮回布局中拔出一个doEvent语句来办理。而Java中,最好的体例是利用线程,就像以下代码片段一样。
publicTestPortextendThread
{
...
InputStreaminput=serialPort.getInputStream();
StringBufferbuf=newStringBuffer();
booleanstopped=false;
...
publicvoidrun()
{
try{
while(!stopped)
intch=input.read();
if(ch==q||ch==Q)
{
/*停止读取,封闭端口...*/
stopped=true;
...
}
else
{
buf.append((char)ch);
...
}
}catch(InterruptedExceptione){}
}
}
2.监听体例(listening)
CommAPI撑持尺度的JavaBean型的事务模子。也就是说,你可使用相似AddXXXListener如许的办法为一个串口注册本人的监听器,以监听体例举行数据读取。
如要对端口监听,你必需先获得CommPortIdentifier类的一个实例,
CommPortserialPort=portId.open("MyApp",60);
从而获得SerialPort,再挪用它的addEventListener办法为它增加监听器,
serialPort.addEventListener(newMyPortListener());
SerialPort的监听器必需承继于SerialPortEventListener接口。当有任何SerialPort的事务产生时,将主动挪用监听器中的serialEvent办法。SerialEvent有以下几品种型:
BI-通信中止.
CD-载波检测.
CTS-扫除发送.
DATA_AVAILABLE-无数据抵达.
DSR-数据设备筹办好.
FE-帧毛病.
OE-溢位毛病.
OUTPUT_BUFFER_EMPTY-输入缓冲区已清空.
PE-奇偶校验错.
RI- 振铃唆使.
上面是一个监听器的示例:
publicvoidMyPortListenerimplementsSerialPortEventListener
{
publicvoidserialEvent(SerialPortEventevt)
{
switch(evt.getEventType())
{
caseSerialPortEvent.CTS:
System.out.println("CTSeventoccured.");
break;
caseSerialPortEvent.CD:
System.out.println("CDeventoccured.");
break;
caseSerialPortEvent.BI:
System.out.println("BIeventoccured.");
break;
caseSerialPortEvent.DSR:
System.out.println("DSReventoccured.");
break;
caseSerialPortEvent.FE:
System.out.println("FEeventoccured.");
break;
caseSerialPortEvent.OE:
System.out.println("OEeventoccured.");
break;
caseSerialPortEvent.PE:
System.out.println("PEeventoccured.");
break;
caseSerialPortEvent.RI:
System.out.println("RIeventoccured.");
break;
caseSerialPortEvent.OUTPUT_BUFFER_EMPTY:
System.out.println("OUTPUT_BUFFER_EMPTYeventoccured.");
break;
caseSerialPortEvent.DATA_AVAILABLE:
System.out.println("DATA_AVAILABLEeventoccured.");
intch;
StringBufferbuf=newStringBuffer();
InputStreaminput=serialPort.getInputStream
try{
while((ch=input.read())>0){
buf.append((char)ch);
}
System.out.print(buf);
}catch(IOExceptione){}
break;
}
}
这个监听器只是复杂打印每一个产生的事务称号。而关于年夜多半使用程序来讲,一般体贴是DATA_AVAILABLE事务,当数据从内部设备传送到端口下去时将触发此事务。此时就能够利用后面提到过的办法,serialPort.getInputStream()来从InputStream中读取数据了。
通过视频学习比传统的大课堂学习更适合成人化的学习规律。有人说大课堂气氛好,学习氛围浓,热闹,可以认识很多人。 |
|