当前位置: 技术问答>java相关
如何用java读、写串口?
来源: 互联网 发布时间:2015-02-23
本文导语: 我装了javax.comm后运行samples,都说找不到串口,可我都是按照它的指示做的。 不解。 是不是非要在串口上插线才行? | 转自BBS水木清华站Java讨论区 利用Java实现串口全双工通讯 qyjohn , 3...
我装了javax.comm后运行samples,都说找不到串口,可我都是按照它的指示做的。
不解。
是不是非要在串口上插线才行?
不解。
是不是非要在串口上插线才行?
|
转自BBS水木清华站Java讨论区
利用Java实现串口全双工通讯
qyjohn , 3月30日,2001年
关键字: Java Comm API,串口,全双工通讯
摘要:
本文介绍一个利用Java Comm API (javax.comm)实现串口全双工通讯的简单程序
本文介绍一个利用Java Comm API (javax.comm)实现串口全双工通讯的简单程序。这个程序首先打开并初始化一个串口,然后启动如下三个进程:ReadSerial进程从该串口读取数据并放入缓冲区,ReadBuffer进程从缓冲区读取数据并打印到屏幕, WriteSerial进程每5秒钟向该串口发送一个星号(*)。
在这个示例程序中使用了一个简单的协议,既不同的消息之间用星号'*'作为分隔。缓冲区程序根据是否收到星号作为存在等待处理的消息的判断依据。
Java Comm API不是标准的Java API,因此的标准的运行环境中并不提供这个包。如果你的系统上还没有安装这个包,你可以从SUN公司的网站下载。在这个包里面有一个安装指南,如果你没有正确安装这个包,可能你不能够正确运行这个例程。
这个简单的例程包括以下文件:
IMU.java (主程序)
ReadBuffer.java (从缓冲区读取一个消息)
ReadSerial.java (读取串口数据并放入缓冲区)
SerialBuffer.java (缓冲区)
WriteSerial.java (每5秒钟往串口送一个星号'*')
测试程序:
SendCom.java (将一个数据文件往串口发送)
SEND.TXT (供测试用的数据文件)
测试方法:
1 正确安装Java Comm API后编译本例程
2 将计算机的COM1和COM2用一条串口线连接起来
3 运行IMU。如果你这时候打开Windows自带的超级终端并连接到COM2的话,你应该能够看见有星号出现在超级终端的屏幕上。超级终端的参数设置为9600, N, 8, 1, none。
4 关闭超级终端,运行SendCom。这时候你应该能够从IMU的屏幕上看到数据文件里面的内容。
/*
*
* 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 (Fax)
* qjiang@tsinghua.edu
*
*/
import java.io.*;
import java.util.*;
import javax.comm.*;
class IMU
{
static CommPortIdentifier portId;
static SerialPort serialPort;
static OutputStream out;
static InputStream in;
public static void main(String[] args)
{
try
{
//Declare the serial port, and open it.
portId = CommPortIdentifier.getPortIdentifier("COM1");
try
{
serialPort = (SerialPort) portId.open("IMU_App", 2000);
} catch (PortInUseException e)
{
System.out.println(e.getMessage());
}
//Use InputStream in to read from the serial port, and OutputStream
//out to write to the serial port.
try
{
in = serialPort.getInputStream();
out = serialPort.getOutputStream();
} catch (IOException e)
{
System.out.println(e.getMessage());
}
//Initialize the communication parameters to 9600, 8, 1, none.
try
{
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e)
{
System.out.println(e.getMessage());
}
} catch (NoSuchPortException e)
{
System.out.println(e.getMessage());
}
//Declare the serial buffer area, a thread to read from the seriial port,
//a thread to read from the serial buffer for processing, and a thread
//to write to the serial port.
SerialBuffer SB = new SerialBuffer();
ReadSerial r1 = new ReadSerial(SB, in);
ReadBuffer r2 = new ReadBuffer(SB);
WriteSerial r3 = new WriteSerial(out);
//Start all three threads.
r1.start();
r2.start();
r3.start();
}
}
/*
*
* SerialBuffer.java 1.0
* Class that implements 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)
* qjiang@tsinghua.edu
*
*/
public class SerialBuffer
{
private String Content = "";
private String CurrentMsg, TempContent;
private boolean available = false;
//read a message from the serial buffer. The star character '*' is used
//as the seperation mark between different messages.
public synchronized String GetMsg()
{
int SepMark;
if ((SepMark = Content.indexOf('*')) == -1)
{
available = false;
while (available == false)
{
try
{
wait();
} catch (InterruptedException e) { }
}
SepMark = Content.indexOf('*');
}
CurrentMsg = Content.substring(0, SepMark);
TempContent = Content.substring(SepMark+1);
Content = TempContent;
notifyAll();
return CurrentMsg;
}
//Put a character to the serial buffer
public synchronized void PutChar(int c)
{
Character d = new Character((char) c);
Content = Content.concat(d.toString());
if (c == '*')
{
available = true;
}
notifyAll();
}
}
/*
*
* ReadSerial.java 1.0
* Program to read characters from the serial port and put it
* to the 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)
* qjiang@tsinghua.edu
*
*/
import java.io.*;
public class ReadSerial extends Thread
{
private SerialBuffer ComBuffer;
private InputStream ComPort;
public ReadSerial(SerialBuffer SB, InputStream Port)
{
ComBuffer = SB;
ComPort = Port;
}
public void run()
{
int c;
try
{
while (true)
{
c = ComPort.read();
ComBuffer.PutChar(c);
}
} catch (IOException e) {}
}
}
/*
*
* 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)
* qjiang@tsinghua.edu
*
*/
import java.io.*;
public class ReadBuffer extends Thread
{
private SerialBuffer ComBuffer;
public ReadBuffer(SerialBuffer SB)
{
ComBuffer = SB;
}
public void run()
{
String Msg;
while (true)
{
Msg = ComBuffer.GetMsg();
System.out.println(Msg);
}
}
}
/*
*
* WriteSerial.java 1.0
* Program to send a star to the serial port every 5 seconds.
*
* 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)
* qjiang@tsinghua.edu
*
*/
import java.io.*;
public class WriteSerial extends Thread
{
private SerialBuffer ComBuffer;
private OutputStream ComPort;
public WriteSerial(OutputStream Port)
{
ComPort = Port;
}
public void run()
{
int c;
try
{
while (true)
{
ComPort.write('*');
try
{
wait(5000);
} catch (InterruptedException e) { }
}
} catch (IOException e)
{
System.out.println(e.getMessage());
}
}
}
/*
*
* SendCom.java 1.0
*
* Project: Java Based Information Exchange Support System
* Onboard Plug-in System
* Sending data through serial port
*
* Created: March 15, 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)
*
*/
import java.io.*;
public class SendCom
{
public static void main(String[] args)
{
File OutFile = new File("SEND.TXT");
File ComPort = new File("COM2");
int c;
try
{
FileReader in = new FileReader(OutFile);
FileWriter out = new FileWriter(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 a
serial cable so that you can test this program on one machine. If
you have two machines, you can connect the two machine via a serial
cable and test it. Modified the definition of ComPort in the program
if necessary. *
Thank you for testing this program. If you have any suggestions please
kindly let me know. *
小结:
在上面的例程中,大多数的程序仅对我前天发的《一个使用Java读取串口的程序》
一文做了小篇幅的改动,有几个程序和数据文件都没有改动。但是为了本文的完整
性,仍然将雷同的内容也贴了一遍,还望斑竹多多见谅。
这个例程和前面一个例程的区别在于前面一个例程使用了文件IO,而本例程使用了
Comm API。在C语言里面用fopen()函数来打开串口是可读也可写的,但是在Java里
面声明了File以后并不立即打开文件,文件是在声明FileReader或者FileWriter时
才打开的。由于串口不能同时被打开两次,所以读操作和写操作不能够同时进行,
不能够实现全双工通讯。
Comm API虽然能够实现全双工通讯,但是由于它不是标准的Java API,代码的可移
植性难以保证。如果程序并不要求实现全双工的话,我认为利用文件操作不失为一
个好办法。
编辑 guty
利用Java实现串口全双工通讯
qyjohn , 3月30日,2001年
关键字: Java Comm API,串口,全双工通讯
摘要:
本文介绍一个利用Java Comm API (javax.comm)实现串口全双工通讯的简单程序
本文介绍一个利用Java Comm API (javax.comm)实现串口全双工通讯的简单程序。这个程序首先打开并初始化一个串口,然后启动如下三个进程:ReadSerial进程从该串口读取数据并放入缓冲区,ReadBuffer进程从缓冲区读取数据并打印到屏幕, WriteSerial进程每5秒钟向该串口发送一个星号(*)。
在这个示例程序中使用了一个简单的协议,既不同的消息之间用星号'*'作为分隔。缓冲区程序根据是否收到星号作为存在等待处理的消息的判断依据。
Java Comm API不是标准的Java API,因此的标准的运行环境中并不提供这个包。如果你的系统上还没有安装这个包,你可以从SUN公司的网站下载。在这个包里面有一个安装指南,如果你没有正确安装这个包,可能你不能够正确运行这个例程。
这个简单的例程包括以下文件:
IMU.java (主程序)
ReadBuffer.java (从缓冲区读取一个消息)
ReadSerial.java (读取串口数据并放入缓冲区)
SerialBuffer.java (缓冲区)
WriteSerial.java (每5秒钟往串口送一个星号'*')
测试程序:
SendCom.java (将一个数据文件往串口发送)
SEND.TXT (供测试用的数据文件)
测试方法:
1 正确安装Java Comm API后编译本例程
2 将计算机的COM1和COM2用一条串口线连接起来
3 运行IMU。如果你这时候打开Windows自带的超级终端并连接到COM2的话,你应该能够看见有星号出现在超级终端的屏幕上。超级终端的参数设置为9600, N, 8, 1, none。
4 关闭超级终端,运行SendCom。这时候你应该能够从IMU的屏幕上看到数据文件里面的内容。
/*
*
* 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 (Fax)
* qjiang@tsinghua.edu
*
*/
import java.io.*;
import java.util.*;
import javax.comm.*;
class IMU
{
static CommPortIdentifier portId;
static SerialPort serialPort;
static OutputStream out;
static InputStream in;
public static void main(String[] args)
{
try
{
//Declare the serial port, and open it.
portId = CommPortIdentifier.getPortIdentifier("COM1");
try
{
serialPort = (SerialPort) portId.open("IMU_App", 2000);
} catch (PortInUseException e)
{
System.out.println(e.getMessage());
}
//Use InputStream in to read from the serial port, and OutputStream
//out to write to the serial port.
try
{
in = serialPort.getInputStream();
out = serialPort.getOutputStream();
} catch (IOException e)
{
System.out.println(e.getMessage());
}
//Initialize the communication parameters to 9600, 8, 1, none.
try
{
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e)
{
System.out.println(e.getMessage());
}
} catch (NoSuchPortException e)
{
System.out.println(e.getMessage());
}
//Declare the serial buffer area, a thread to read from the seriial port,
//a thread to read from the serial buffer for processing, and a thread
//to write to the serial port.
SerialBuffer SB = new SerialBuffer();
ReadSerial r1 = new ReadSerial(SB, in);
ReadBuffer r2 = new ReadBuffer(SB);
WriteSerial r3 = new WriteSerial(out);
//Start all three threads.
r1.start();
r2.start();
r3.start();
}
}
/*
*
* SerialBuffer.java 1.0
* Class that implements 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)
* qjiang@tsinghua.edu
*
*/
public class SerialBuffer
{
private String Content = "";
private String CurrentMsg, TempContent;
private boolean available = false;
//read a message from the serial buffer. The star character '*' is used
//as the seperation mark between different messages.
public synchronized String GetMsg()
{
int SepMark;
if ((SepMark = Content.indexOf('*')) == -1)
{
available = false;
while (available == false)
{
try
{
wait();
} catch (InterruptedException e) { }
}
SepMark = Content.indexOf('*');
}
CurrentMsg = Content.substring(0, SepMark);
TempContent = Content.substring(SepMark+1);
Content = TempContent;
notifyAll();
return CurrentMsg;
}
//Put a character to the serial buffer
public synchronized void PutChar(int c)
{
Character d = new Character((char) c);
Content = Content.concat(d.toString());
if (c == '*')
{
available = true;
}
notifyAll();
}
}
/*
*
* ReadSerial.java 1.0
* Program to read characters from the serial port and put it
* to the 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)
* qjiang@tsinghua.edu
*
*/
import java.io.*;
public class ReadSerial extends Thread
{
private SerialBuffer ComBuffer;
private InputStream ComPort;
public ReadSerial(SerialBuffer SB, InputStream Port)
{
ComBuffer = SB;
ComPort = Port;
}
public void run()
{
int c;
try
{
while (true)
{
c = ComPort.read();
ComBuffer.PutChar(c);
}
} catch (IOException e) {}
}
}
/*
*
* 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)
* qjiang@tsinghua.edu
*
*/
import java.io.*;
public class ReadBuffer extends Thread
{
private SerialBuffer ComBuffer;
public ReadBuffer(SerialBuffer SB)
{
ComBuffer = SB;
}
public void run()
{
String Msg;
while (true)
{
Msg = ComBuffer.GetMsg();
System.out.println(Msg);
}
}
}
/*
*
* WriteSerial.java 1.0
* Program to send a star to the serial port every 5 seconds.
*
* 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)
* qjiang@tsinghua.edu
*
*/
import java.io.*;
public class WriteSerial extends Thread
{
private SerialBuffer ComBuffer;
private OutputStream ComPort;
public WriteSerial(OutputStream Port)
{
ComPort = Port;
}
public void run()
{
int c;
try
{
while (true)
{
ComPort.write('*');
try
{
wait(5000);
} catch (InterruptedException e) { }
}
} catch (IOException e)
{
System.out.println(e.getMessage());
}
}
}
/*
*
* SendCom.java 1.0
*
* Project: Java Based Information Exchange Support System
* Onboard Plug-in System
* Sending data through serial port
*
* Created: March 15, 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)
*
*/
import java.io.*;
public class SendCom
{
public static void main(String[] args)
{
File OutFile = new File("SEND.TXT");
File ComPort = new File("COM2");
int c;
try
{
FileReader in = new FileReader(OutFile);
FileWriter out = new FileWriter(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 a
serial cable so that you can test this program on one machine. If
you have two machines, you can connect the two machine via a serial
cable and test it. Modified the definition of ComPort in the program
if necessary. *
Thank you for testing this program. If you have any suggestions please
kindly let me know. *
小结:
在上面的例程中,大多数的程序仅对我前天发的《一个使用Java读取串口的程序》
一文做了小篇幅的改动,有几个程序和数据文件都没有改动。但是为了本文的完整
性,仍然将雷同的内容也贴了一遍,还望斑竹多多见谅。
这个例程和前面一个例程的区别在于前面一个例程使用了文件IO,而本例程使用了
Comm API。在C语言里面用fopen()函数来打开串口是可读也可写的,但是在Java里
面声明了File以后并不立即打开文件,文件是在声明FileReader或者FileWriter时
才打开的。由于串口不能同时被打开两次,所以读操作和写操作不能够同时进行,
不能够实现全双工通讯。
Comm API虽然能够实现全双工通讯,但是由于它不是标准的Java API,代码的可移
植性难以保证。如果程序并不要求实现全双工的话,我认为利用文件操作不失为一
个好办法。
编辑 guty
|
不一定,我的就可以