西安邮电大学串口通信实验报告

时间:2024.5.9

《高级Internet》实验报告

题目: 串口通信

学生姓名: 班 级: 软件工程1202 学 号: 指导老师: 王文浪

西安邮电大学计算机学院

2015 年 6 月 10 日

一、 实验目的

1.了解串口通信的通信的原理

2.串口包的安装(Windows下)

3.解使用java进行串口通信的配置

二、 实验准备

1.首先准备一条串口通信线

2. 在设备上实现Java串口通信,需要用到javacomm20-win32.zip包.目前,常见的Java串口包有SUN在19xx年发布的串口通信API:comm2.0.jar(Windows下)、comm3.0.jar(Linux/Solaris);IBM的串口通信API以及一个开源的实现。鉴于在Windows下SUN的API比较常用以及IBM的实现和SUN的在API层面都是一样的,那个开源的实现又不像两家大厂的产品那样让人放心,这里就只介绍SUN的串口通信API在Windows平台下的使用。

3.到SUN的网站下载

西安邮电大学串口通信实验报告

javacomm20-win32.zip

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

三、 实验过程

1.串口API概览javax.comm.CommPort

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

2. javax.comm.CommPortIdentifier

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

(1)确定是否有可用的通信端口

(2)为IO操作打开通信端口

(3)决定端口的所有权

(4)处理端口所有权的争用

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

3. javax.comm.SerialPort

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

(1)要准备相应的设备:电脑,外设,通过数据线把他们连接起来。

(2)检验外设到底是用的那个COM口和电脑通讯的. 也就是说,他们有没有真确的连接上。可以通过下载串口通讯口测试软件,我用的是"SuperCommTool.exe"的绿色软件,进行测试的。这软件很适应,如果选中的某个COM已经被使用了,它会给你一个相应的提示(端口以被占用)。如果你不知道到底是使用的那个端口,那么你可以通过superCommTool软件一个一个的试,如果正常的话,那么你可以看到有数据显示在数据接收窗口。也许,有些主板的串口坏了,那么就要买一个转接卡,通过PCI插口转接。

(3)查看外设使用说明书知道外设的相关参数. 比如,波特率,数据位,停止位,校验位,等等。只有正确参数,才能显示正确的数据。当然,可以在通讯测试软件上调试这些参数的。比如:波特率 = 2400,数据位 = 8,停止位 = 2 ,校验位 = 1。

(4)准备开发环境:最基本的JDK了,使用自己的IDE,帮助开发。IDE可能自带了JDK,那么 你要把相应的javaComm20-win32放到运行时使用的JDK中。 下载JAVAcomm20-win32。必须把win32com.dll复制到java.home/bin下;把javax.comm.properties复制到java.home/lib下;把comm.jar添加到classPath下。前面两个都是非常重要的。

(5)获取SerialPort sPort对象的方法。

CommPortIdentifier portId = CommPortIdentifier .getPortIdentifier("COM4"); SerialPort sPort = (SerialPort)portId.open("ship ment",1000);

设置串行端口通讯参数:

sPort.setSerialPortParams(2400,SerialPort.DATABITS_8,SerialPort.STOPBITS_2,SerialPort.PARITY_NONE);

获取输入(出)流:

InputStream is = sPort.getInputStream();//从外 设获取数据

OutputStream os = sPort.getOutputStream();// 发送命令到外设

通过监听器就可以得到数据了:

sPort.notifyOnDataAvailable(true);

sPort.notifyOnBreakInterrupt(true);

sPort.enableReceiveTimeout(30);

StringBuffer linkWgt = new StringBuffer ();//存放获取的数据

sPort.addEventListener()

new SerialPortEventListener(){

public void serialEvent(SerialPortE vent e){

int newData = 0;

switch (e.getEventType()) {

case SerialPortEvent.DATA_ AVAILABLE:

while (newData != -1) {

try {

newData = is.read() ;

if (newData == -1) {

break; }

if ('\r' == (char)new Data) { }

else { linkWgt.append(( char)newData); } }

catch (IOException e x) {

System.err.println(e x);

return; }

}

try{

System.out.println("linkW gt

"+Double.valueOf(linkWgt.toString()));

}

catch(Exception ew){

ew.printStackTrace(); }

finally{

try{ //用完了,关闭端 口。

is.close(); sPort.close();

}catch(Exception c)

{

c.printStackTrace();}

} break; ---------|||||

case SerialPortEvent.BI: System.out.println("\n--- BREAK RECEIVED ---\n");

}

}

}

(6)枚举出系统所有的RS232端口

在开始使用RS232端口通讯之前,我们想知道系统有哪些端口是可用的,以下代码列出系统中所有可用的RS232端口:

Enumeration en = CommPortIdentifier.getPortIdentifiers();

CommPortIdentifier portId; while (en.hasMoreElements())

{

portId = (CommPortIdentifier) en.nextElement(); /*如果端口类型是串口,则打印出其端口信息*/

if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)

{

System.out.println(portId.getName());

}

}

在电脑上以上程序输出以下结果:

COM1 COM2

(7)主要程序

程序文件名称:SendComm.java * 功能:从串行口COM1中发送数据 import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.util.*;

import javax.comm.*;

class S_Frame extends Frame implements Runnable,ActionListener {

/*检测系统中可用的通讯端口类 */

static CommPortIdentifier portId;

/*Enumeration 为枚举型类,在util中 */

static Enumeration portList;

OutputStream outputStream;

/*RS-232的串行口 */

SerialPort serialPort;

Thread readThread;

Panel p=new Panel();

TextField in_message=new TextField("打开COM1,波特率9600,数据位8,停止位

1.");

TextArea out_message=new TextArea();

Button btnOpen=new Button("打开串口, 发送数据");

Button btnClose=new Button("关闭串口, 停止发送数据");

byte data[]=new byte[10240];

/*设置判断要是否关闭串口的标志*/ boolean mark;

/*安排窗体*/ S_Frame()

{ super("串口发送数据");

setSize(200,200);

setVisible(true);

add(out_message,"Center");

add(p,"North");

p.add(btnOpen);

p.add(btnClose);

add(in_message,"South");

btnOpen.addActionListener(this);

btnClose.addActionListener(this);

} //R_Frame() end

/*点击按扭打开串口.*/

public void actionPerformed(ActionEvent event)

{ if (event.getSource()==btnClose){ serialPort.close();

//关闭串口

mark=true; //用于中止线程的run()方法

in_message.setText("串口COM1已经关闭,停止发送数据.");

}

else

{ mark=false;

/*从文本区按字节读取数据*/

data=out_message.getText().getBytes(); /*打开串口*/ start();

in_message.setText("串口COM1已经打开,正在每2秒钟发送一次数据.....");

}

} //actionPerformed()

end

/*打开串口,并调用线程发送数据*/

public void start(){

/*获取系统中所有的通讯端口 */

portList=CommPortIdentifier.getPortIdentifiers(); /* 用循环结构找出串口 */

while (portList.hasMoreElements()){ /*强制转换为通讯端口类型*/

portId=(CommPortIdentifier)portList.nextElement();

if(portId.getPortType() == CommPortIdentifier.PORT_SERIAL){ if (portId.getName().equals("COM1")) { /*打开串口 */

try {

serialPort = (SerialPort) portId.open("ReadComm", 2000);

}

catch (PortInUseException e) { } /*设置串口输出流*/

try {

outputStream = serialPort.getOutputStream(); }

catch (IOException e) {}

} //if end

}//if end

} //while end

/*调用线程发送数据*/

try{

readThread = new Thread(this);

//线程负责每发送一次数据,休眠2秒钟

readThread.start(); }

catch (Exception e) { }

} //start() end

/*发送数据,休眠2秒钟后重发*/

public void run() { /*设置串口通讯参数*/ try {

serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

}

catch (UnsupportedCommOperationException e) {

} /*发送数据流(将数组data[]中的数据发送出去)*/

try {

outputStream.write(data); }

catch (IOException e) { }

/*发送数据后休眠2秒钟,然后再重发*/

try { Thread.sleep(2000);

if (mark)

{return; //结束run方法,导致线程死亡 }

start(); }

catch (InterruptedException e) { }

} //run() end

} //类S_Fram end

public class SendComm

{

public static void main(String args[]){

S_Frame S_win=new S_Frame();

S_win.addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e)

{System.exit(0); }

});

S_win.pack();

}

}

程序文件名称:ReadComm.java * 功能:从串行口COM1中接收数据 import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.util.*;

import javax.comm.*;

class R_Frame extends Frame implements

Runnable,ActionListener,SerialPortEventListener {

/* 检测系统中可用的通讯端口类 */

static CommPortIdentifier portId;

/* Enumeration 为枚举型类,在java.util

中 */ static Enumeration portList;

InputStream inputStream;

/* 声明RS-232串行端口的成员变量 */

SerialPort serialPort;

Thread readThread;

String str="";

TextField out_message=new TextField("上面文本框显示接收到的数据");

TextArea in_message=new TextArea();

Button btnOpen=new Button("打开串口");

/*建立窗体*/

R_Frame() {

super("串口接收数据");

setSize(200,200); setVisible(true);

btnOpen.addActionListener(this);

add(out_message,"South");

add(in_message,"Center");

add(btnOpen,"North"); } //R_Frame()

end

/*点击按扭所触发的事件:打开串口,并监听串口. */

public void actionPerformed(ActionEvent event) {

/*获取系统中所有的通讯端口 */

portList=CommPortIdentifier.getPortIdentifiers(); /* 用循环结构找出串口 */

while (portList.hasMoreElements()){ /*强制转换为通讯端口类型*/

portId=(CommPortIdentifier)portList.nextElement();

if(portId.getPortType() == CommPortIdentifier.PORT_SERIAL){ if (portId.getName().equals("COM1"))

{ try {

serialPort = (SerialPort) portId.open("ReadComm", 2000); out_message.setText("已打开端口COM1 ,正在接收数据..... "); }

catch (PortInUseException e) { }

/*设置串口监听器*/

try {

serialPort.addEventListener(this); }

catch (TooManyListenersException e) { } /* 侦听到串口有数据,触发串口事件*/

serialPort.notifyOnDataAvailable(true);

} //if end

} //if end

} //while end

readThread = new Thread(this);

readThread.start(); //线程负责每接收一次数据休眠20秒

钟 } //actionPerformed()

end

/*接收数据后休眠20秒钟*/

public void run() {

try {

Thread.sleep(20000); }

catch (InterruptedException e) { } } //run()

end

/*串口监听器触发的事件,设置串口通讯参数,读取数据并写到文本区中*/

public void serialEvent(SerialPortEvent event) {

/*设置串口通讯参数:波特率、数据位、停止位、奇偶校验*/

try {

serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } catch (UnsupportedCommOperationException e) {}

byte[] readBuffer = new byte[20];

try {

inputStream = serialPort.getInputStream(); }

catch (IOException e) {}

try {

/* 从线路上读取数据流 */

while (inputStream.available() > 0)

{

int numBytes = inputStream.read(readBuffer); } //while end str=new String(readBuffer); /*接收到的数据存放到文本区中*/ in_message.append(str+"\n"); }

catch (IOException e) { } } //serialEvent() end } //类R_Frame end

public class ReadComm {

public static void main(String args[]) {

/* 实例化接收串口数据的窗体类 */

R_Frame R_win=new R_Frame();

/* 定义窗体适配器的关闭按钮功能 */

R_win.addWindowListener(new WindowAdapter()

{public void windowClosing(WindowEvent e)

{System.exit(0); }

});

R_win.pack();

}

}

四、 实验总结

通过本次实验,我了解了使用Java进行串口通信需要的准备工作,在我的应用程序中,

我将收到的数据打包放到一个缓存中,然后启动另一个线程从缓存中获取并处理数据。两个线程以生产者—消费者模式协同工作。在处理线程中调用这个方法返回所需要的数据序列并处理之,这样不但没有丢失数据的现象行出现,也没有数据接收延迟了。这里唯一需要注意的就是当串口停止发送数据或没有数据的时候is.read()一直都返回-1,如果一旦在开始接收数据的时候发现-1就不要理它,继续接收,直到收到真正的数据为止.

更多相关推荐:
串口通信实验报告

基于Labview的串行通信接口实验报告一实验目的通过软件Labview编写前面板和程序框图通过该面板实现计算机与外围设备的串口通信设置好通信端口波特率等参数后在输入控件中输入数据字符当点击发送按钮时下位机发生...

单片机串口通讯实验报告

实验十单片机串行口与PC机通讯实验报告实验目的1掌握串行口工作方式的程序设计掌握单片机通讯的编制2了解实现串行通讯的硬环境数据格式的协议数据交换的协议3了解PC机通讯的基本要求实验器材1G6W仿真器2MCS51...

基于VC++ 6.0的串口通信实验报告

网络与通信实验报告网络与通信实验报告题目串口通行实验班级0309103学号030910338姓名田静指导老师付大丰日期20xx1021网络与通信实验报告一实验要求把两台计算机的串口通过串口线连在一起通过串口实现...

串口通信实验报告

基于LabwindowsCVI的串行通信接口实验报告一实验目的通过软件LabwindowsCVI编写仪器面板通过该面板实现计算机与外围设备的串口通信设置好通信端口波特率等参数后在TextBox控件中输入数据字符...

rs232串口通信实验报告

计算机网络实验实现RS232串口通信程序及MODBUS协议的编程一实验目的1熟悉并掌握RS232串口标准及原理2实现PC机通过RS232串口进行数据的收发3掌握MODBUS协议4掌握MODBUS协议编程的编写二...

嵌入式ARM串口实验报告

实验五串口通信实验1实验目的1掌握ARM的串行口工作原理2编程实现ARM的UART通讯3掌握S3C2410寄存器配置方法2实验设备1S3C2410嵌入式开发板JTAG仿真器2软件PC机操作系统WindowsXP...

串口通信实验报告

华南农业大学实验报告目录1实验任务和目的12实验准备13实验步骤14实验分析与总结11分析12总结31实验任务和目的了解串行通信的背景知识后通过三线制制作一条串口通信线PCPC并编程实现两台PC间通过RS232...

串口通信实验

串口通信实验实验报告学号20xx12235027姓名曹勇发第4次

串行通信实验,南京理工大学紫金学院单片机实验报告

单片机实验报告实验名称姓名学号班级时间串行通信实验通信20xx11南京理工大学紫金学院电光系一实验目的1理解单片机串行口的工作原理2学习使用单片机的TXDRXD口3了解MAX232芯片的作用二实验原理MCS51...

串口通信电平转换实验报告

课程实验报告一实验名称串口232电平转换电路设计与软件实现课程名称现场总线技术一实验目的及要求实现两台电脑的RS232通过RS485接口协议的通信1熟悉串口结构及参数指标2熟悉芯片的内部结构工作机制3完成电路原...

RS232串口通信控制器实验报告

摘要本实验报告为RS232串口通信控制器实验设计了基于VHDL描述的RS232串口通信控制器通过串口调试工具实现PC和CPLD互发和接收数据完成的功能包括实现收发一帧10个bit波特率为9600的串口通信控制器...

串口通信实验

单片机原理及应用实验报告实验序号7实验项目名称串口通信

串口通信实验报告(34篇)