首页编程java编程java通过串口是什么意思?java串口通信

java通过串口是什么意思?java串口通信

编程之家2023-10-13101次浏览

各位老铁们,大家好,今天由我来为大家分享java通过串口是什么意思,以及java串口通信的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

java通过串口是什么意思?java串口通信

java串口通信

java.comm可以在XP下使用,我用JAVA写过串口程序

下载了comm.jar开发包后,与之一起的还有两个重要的文件,win32com.dll和javax.comm.properties。

1 comm.jar提供了通讯用的java API。

java通过串口是什么意思?java串口通信

2 win32com.dll提供了供comm.jar调用的本地驱动接口。

3 javax.comm.properties是这个驱动的类配置文件。

首先将comm.jar复制到<JRE_HOME>\lib\ext目录。

java通过串口是什么意思?java串口通信

接着将win21com.dll复制到你的RS232应用程序运行的目录,即user.dir。

最后将javax.comm.properties复制到<JRE_HOME>\lib目录。

我在Eclipse3.2+JDK1.6开发的时候,在项目中包含comm.jar和win32com.dll

编程技巧:Java串口通信简介

嵌入式系统或传感器网络的很多应用和测试都需要通过PC机与嵌入式设备或传感器节点进行通信其中最常用的接口就是RS串口和并口(鉴于USB接口的复杂性以及不需要很大的数据传输量 USB接口用在这里还是显得过于奢侈况且目前除了SUN有一个支持USB的包之外我还没有看到其他直接支持USB的Java类库) SUN的CommAPI分别提供了对常用的RS串行端口和IEEE并行端口通讯的支持 RS C(又称EIA RS C以下简称RS)是在年由美国电子工业协会(EIA)联合贝尔系统调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准 RS是一个全双工的通讯协议它可以同时进行数据接收和发送的工作

常见的Java串口包

目前常见的Java串口包有SUN在年发布的串口通信API m jar(Windows下) m jar(Linux/Solaris);IBM的串口通信API以及一个开源的实现鉴于在Windows下SUN的API比较常用以及IBM的实现和SUN的在API层面都是一样的那个开源的实现又不像两家大厂的产品那样让人放心这里就只介绍SUN的串口通信API在Windows平台下的使用

串口包的安装(Windows下)

到SUN的网站下载javam win zip包含的东西如下所示

按照其使用说明(l)的说法要想使用串口包进行串口通信除了设置好环境变量之外还要将win dll复制到 \bin目录下;将m jar复制到 \lib;把m properties也同样拷贝到 \lib目录下然而在真正运行使用串口包的时候仅作这些是不够的因为通常当运行 java MyApp的时候是由JRE下的虚拟机启动MyApp的而我们只复制上述文件到JDK相应目录下所以应用程序将会提示找不到串口解决这个问题的方法很简单我们只须将上面提到的文件放到JRE相应的目录下就可以了

值得注意的是在网络应用程序中使用串口API的时候还会遇到其他更复杂问题有兴趣的话你可以查看CSDN社区中关于网页上Applet用javam读取客户端串口的问题的帖子

串口API概览

m CommPort

这是用于描述一个被底层系统支持的端口的抽象类它包含一些高层的IO控制方法这些方法对于所有不同的通讯端口来说是通用的 SerialPort和ParallelPort都是它的子类前者用于控制串行端口而后者用于控这并口二者对于各自底层的物理端口都有不同的控制方法这里我们只关心SerialPort

m CommPortIdentifier

这个类主要用于对串口进行管理和设置是对串口进行访问控制的核心类主要包括以下方法

l确定是否有可用的通信端口

l为IO操作打开通信端口

l决定端口的所有权

l处理端口所有权的争用

l管理端口所有权变化引发的事件(Event)

m SerialPort

这个类用于描述一个RS串行通信端口的底层接口它定义了串口通信所需的最小功能集通过它用户可以直接对串口进行读写及设置工作

串口API实例

大段的文字怎么也不如一个小例子来的清晰下面我们就一起看一下串口包自带的例子 SerialDemo中的一小段代码来加深对串口API核心类的使用方法的认识

列举出本机所有可用串口

voidlistPortChoices(){ CommPortIdentifierportId; Enumerationen=CommPortIdentifier getPortIdentifiers();//iteratethroughtheports while(en hasMoreElements()){ portId=(CommPortIdentifier)en nextElement(); if(portId getPortType()==CommPortIdentifier PORT_SERIAL){ System out println(portId getName());}} portChoice select(parameters getPortName());}

以上代码可以列举出当前系统所有可用的串口名称我的机器上输出的结果是和

串口参数的配置

串口一般有如下参数可以在该串口打开以前配置进行配置

包括波特率输入/输出流控制数据位数停止位和齐偶校验

SerialPortsPort; try{ sPort setSerialPortParams(BaudRate Databits Stopbits Parity);//设置输入/输出控制流 sPort setFlowControlMode(FlowControlIn|FlowControlOut);}catch(UnsupportedCommOperationExceptione){}

串口的读写

对串口读写之前需要先打开一个串口

CommPortIdentifierportId=CommPortIdentifier getPortIdentifier(PortName); try{ SerialPortsPort=(SerialPort)portId open(串口所有者名称超时等待时间);}catch(PortInUseExceptione){//如果端口被占用就抛出这个异常 thrownewSerialConnectionException(e getMessage());}//用于对串口写数据 OutputStreamos=newBufferedOutputStream(sPort getOutputStream()); os write(intdata);//用于从串口读数据 InputStreamis=newBufferedInputStream(sPort getInputStream()); intreceivedData=is read();

读出来的是int型你可以把它转换成需要的其他类型

这里要注意的是由于Java语言没有无符号类型即所有的类型都是带符号的在由byte到int的时候应该尤其注意因为如果byte的最高位是则转成int类型时将用来占位这样原本是的byte类型的数变成int型就成了这是很严重的问题应该注意避免

串口通信的通用模式及其问题

终于唠叨完我最讨厌的基础知识了下面开始我们本次的重点串口应用的研究由于向串口写数据很简单所以这里我们只关注于从串口读数据的情况通常串口通信应用程序有两种模式一种是实现SerialPortEventListener接口监听各种串口事件并作相应处理;另一种就是建立一个独立的接收线程专门负责数据的接收由于这两种方法在某些情况下存在很严重的问题(至于什么问题这里先卖个关子J)所以我的实现是采用第三种方法来解决这个问题

事件监听模型

现在我们来看看事件监听模型是如何运作的

l首先需要在你的端口控制类(例如SManager)加上 implements SerialPortEventListener

l在初始化时加入如下代码

try{ SerialPortsPort addEventListener(SManager);}catch(TooManyListenersExceptione){ sPort close(); thrownewSerialConnectionException( toomanylistenersadded);} sPort notifyOnDataAvailable(true);

l覆写public void serialEvent(SerialPortEvent e)方法在其中对如下事件进行判断

BI通讯中断

CD载波检测

CTS清除发送

DATA_AVAILABLE有数据到达

DSR数据设备准备好

FE帧错误

OE溢位错误

OUTPUT_BUFFER_EMPTY输出缓冲区已清空

PE奇偶校验错

RI振铃指示

一般最常用的就是DATA_AVAILABLE串口有数据到达事件也就是说当串口有数据到达时你可以在serialEvent中接收并处理所收到的数据然而在我的实践中遇到了一个十分严重的问题

首先描述一下我的实验我的应用程序需要接收传感器节点从串口发回的查询数据并将结果以图标的形式显示出来串口设定的波特率是川口每隔毫秒返回一组数据(大约是字节左右)周期(即持续时间)为秒实测的时候在一个周期内应该返回多个字节而用事件监听模型我最多只能收到不到字节不知道这些字节都跑哪里去了也不清楚到底丢失的是那部分数据值得注意的是这是我将serialEvent()中所有处理代码都注掉只剩下打印代码所得的结果数据丢失的如此严重是我所不能忍受的于是我决定采用其他方法

串口读数据的线程模型

这个模型顾名思义就是将接收数据的操作写成一个线程的形式:

publicvoidstartReadingDataThread(){ ThreadreadDataProcess=newThread(newRunnable(){ publicvoidrun(){ while(newData!=){ try{ newData=is read(); System out println(newData);//其他的处理过程………}catch(IOExceptionex){ System err println(ex); return;}} readDataProcess start();}

在我的应用程序中我将收到的数据打包放到一个缓存中然后启动另一个线程从缓存中获取并处理数据两个线程以生产者—消费者模式协同工作数据的流向如下图所示

这样我就圆满解决了丢数据问题然而没高兴多久我就又发现了一个同样严重的问题虽然这回不再丢数据了可是原本一个周期(秒)之后传感器节电已经停止传送数据了但我的串口线程依然在努力的执行读串口操作在控制台也可以看见收到的数据仍在不断的打印原来由于传感器节点发送的数据过快而我的接收线程处理不过来所以InputStream就先把已到达却还没处理的字节缓存起来于是就导致了明明传感器节点已经不再发数据了而控制台却还能看见数据不断打印这一奇怪的现象唯一值得庆幸的是最后收到数据确实是左右字节没出现丢失现象然而当处理完最后一个数据的时候已经快分半钟了这个时间远远大于节点运行周期这一延迟对于一个实时的显示系统来说简直是灾难!

后来我想是不是由于两个线程之间的同步和通信导致了数据接收缓慢呢?于是我在接收线程的代码中去掉了所有处理代码仅保留打印收到数据的语句结果依然如故看来并不是线程间的通信阻碍了数据的接收速度而是用线程模型导致了对于发送端数据发送速率过快的情况下的数据接收延迟这里申明一点就是对于数据发送速率不是如此快的情况下前面者两种模型应该还是好用的只是特殊情况还是应该特殊处理

第三种方法

痛苦了许久(Boss天天催我L)之后偶然的机会我听说TinyOS中(又是开源的)有一部分是和我的应用程序类似的串口通信部分于是我下载了它的 x版的Java代码部分参考了它的处理方法解决问题的方法说穿了其实很简单就是从根源入手根源不就是接收线程导致的吗那好我就干脆取消接收线程和作为中介的共享缓存而直接在处理线程中调用串口读数据的方法来解决问题(什么为什么不把处理线程也一并取消?都取消应用程序界面不就锁死了吗?所以必须保留)于是程序变成了这样

publicbyte[]getPack(){ while(true){//PacketLength为数据包长度 byte[]msgPack=newbyte[PacketLength]; for(inti=;i<PacketLength;i++){ if((newData=is read())!=){ msgPack[i]=(byte)newData; System out println(msgPack[i]);}} returnmsgPack;}}

在处理线程中调用这个方法返回所需要的数据序列并处理之这样不但没有丢失数据的现象行出现也没有数据接收延迟了这里唯一需要注意的就是当串口停止发送数据或没有数据的时候is read()一直都返回如果一旦在开始接收数据的时候发现就不要理它继续接收直到收到真正的数据为止

结束语

lishixinzhi/Article/program/Java/hx/201311/26605

Java串口通信总结

最近在研究一个东西要用到串口的读写通过读取串口获取一个指令然后根据该指令通过配置文件获取其他的信息再通过串口进行做下一步的一系列操作

java读写串口要用到的是javax扩展类库javam它是一系列的标准该类库在sun的官网上只提供linux版本由于我所应用的平台是win所以找了个win的实现在此过程中遇到了一系列的问题后来终于解决问题并完成了通过读写串口进行通信的功能在此对其java读写串口的情况做个简要说明

首先下载javam包然后将其解压解压后需要做的就是配置串口通信相关东西下面是自己使用的时候的配置

把m properties文件拷贝到Java运行时环境的lib目录中即

C:\Program Files\Java\jdk _ \lib\m properties

C:\Program Files\Java\jdk _ \jre\lib\m properties

把win dll拷贝到C:\windows\system \和 C:\Program Files\Java\jdk _ \jre\bin\下

把m jar放到Java运行时环境的lib目录中即C:\Program Files\Java\jdk _ \lib\m jar

在环境变量的CLASSPATH中添加m jar如%JAVA_HOME%\lib\m jar;

然后通过的API来实现串口的读写其实API相当简单如下代码

Java代码

CommPortIdentifier serialPortId= CommPortIdentifier getPortIdentifier();

SerialPort port=(SerialPort) serialPortId open( Read);//打开串口其中参数是用来设置打开串口的超时时间

port setSerialPortParams();//设置的波特率数据位停止位校验方式等

//从串口中得到输入输出流了

OutputStream out= port getOutputStream();

out write(buffer);

out flush();

InputStream in= port getInputStream();

in read(data);//data是一个byte[]

CommPortIdentifier serialPortId= CommPortIdentifier getPortIdentifier(); SerialPort port=(SerialPort) serialPortId open( Read);//打开串口其中参数是用来设置打开串口的超时时间 port setSerialPortParams();//设置的波特率数据位停止位校验方式等//从串口中得到输入输出流了 OutputStream out= port getOutputStream(); out write(buffer); out flush(); InputStream in= port getInputStream(); in read(data);//data是一个byte[]

lishixinzhi/Article/program/Java/hx/201311/26266

文章分享结束,java通过串口是什么意思和java串口通信的答案你都知道了吗?欢迎再次光临本站哦!

焉知非福的焉是什么意思(焉知非福的焉是什么意思 百度网盘)java出来可以做什么 学Java以后可以做什么