您的位置:首页 > 编程语言 > Java开发

JAVA 编写的串口 读写 程序 以及乱码程序

2011-12-27 10:07 441 查看


最近,由于需要接触了JAVA编写的串口类程序,网上资料很多,看的眼花缭乱。不过,还是学到了许多,在这里把自己学习过程中的一些心得体会跟大家分享一下,希望对以后从事串口开发的同志们有所帮助。


java串口通信的说明(下面的内容是网上拷贝的)

Java提供了CommunicationAPI(包含于javax.comm包中)用于通过与机器无关的方式,控制各种外部设备。Communications API,是标准的Java的扩展部分,它在JavaAPI中是没有附带的。Communications API 的核心是抽象的CommPort类及其两个子类:SerialPort类和ParallePort类。其中,SerialPort类是用于串口通信的类,ParallePort类是用于并行口通信的类。CommPort类还提供了常规的通信模式和方法,例如:getInputStream(
)方法和getOutputStream()方法,专用于与端口上的设备进行通信。

  然而,这些类的构造方法都被有意的设置为非公有的(non-public)。所以,不能直接构造对象,而是先通过静态的CommPortIdentifer.getPortIdentifiers()获得端口列表;再从这个端口列表中选择所需要的端口,并调用CommPortIdentifer对象的Open( )方法,这样,就能得到一个CommPort对象。当然,还要将这个CommPort对象的类型转换为某个非抽象的子类,表明是特定的通讯设备。该子类可以是SerialPort类和ParallePort类中的一个。

CommPortIdentifier类

 CommPortIdentifier类的方法
如下:

addPortName(String, int, CommDriver) 添加端口名到端口列表里
addPortOwnershipListener(CommPortOwnershipListener) 添加端口拥有的监听器
removePortOwnershipListener(CommPortOwnershipListener) 移除端口拥有的监听器
getCurrentOwner() 得到当前占有端口的对象或应用程序
getName() 得到端口名称
getPortIdentifier(CommPort) 得到参数打开的端口的CommPortIdentifier类型对象
getPortIdentifier(String) 得到以参数命名的端口的CommPortIdentifier类型对象
getPortIdentifiers() 得到系统中的端口列表
getPortType() 得到端口的类型
isCurrentlyOwned() 判断当前端口是否被占用
open(FileDescriptor) 用文件描述的类型打开端口
open(String, int) 打开端口,两个参数:程序名称,延迟时间(毫秒数)
SerialPort关于串口参数的静态成员变量

[b]成员变量说明 成员变量 说明 成员变量 说明


DATABITS_5 数据位为5 STOPBITS_2 停止位为2 PARITY_ODD 奇检验

DATABITS_6 数据位为6 STOPBITS_1 停止位为1 PARITY_MARK 标记检验

DATABITS_7 数据位为7 STOPBITS_1_5 停止为1.5 PARITY_NONE 空格检验

DATABITS_8 数据位为8 PARITY_EVEN 偶检验 PARITY_SPACE 无检验 [/b]

BI Break interrupt中断FE Framing error错误

CD Carrier detect载波侦听 OE Overrun error错误

CTS Clear to send清除以传送 PE Parity error奇偶检验错误

DSR Data set ready数据备妥 RI Ring indicator响铃侦测

DATA_AVAILABLE 串口中的可用数据 OUTPUT_BUFFER_EMPTY 输出缓冲区空



SerialPort对象的关于串口参数的函数

方法 说明 方法 说明

getBaudRate() 得到波特率 getParity() 得到检验类型

getDataBits() 得到数据位数 getStopBits() 得到停止位数

setSerialPortParams(int, int, int, int) 设置串口参数依次为(波特率,数据位,停止位,奇偶检验)


isCD() 是否有载波 isCTS() 是否清除以传送 isDSR() 数据是否备妥

isDTR() 是否数据端备妥 isRI() 是否响铃侦测isRTS() 是否要求传送

addEventListener(SerialPortEventListener) 向SerialPort对象中添加串口事件监听器

removeEventListener() 移除SerialPort对象中的串口事件监听器

notifyOnBreakInterrupt(boolean) 设置中断事件true有效,false无效

notifyOnCarrierDetect(boolean) 设置载波监听事件true有效,false无效

notifyOnCTS(boolean) 设置清除发送事件true有效,false无效

notifyOnDataAvailable(boolean) 设置串口有数据的事件true有效,false无效

notifyOnDSR(boolean) 设置数据备妥事件true有效,false无效

notifyOnFramingError(boolean) 设置发生错误事件true有效,false无效

notifyOnOutputEmpty(boolean) 设置发送缓冲区为空事件true有效,false无效

notifyOnParityError(boolean) 设置发生奇偶检验错误事件true有效,false无效

notifyOnRingIndicator(boolean) 设置响铃侦测事件true有效,false无效

getEventType() 得到发生的事件类型返回值为int型

sendBreak(int) 设置中断过程的时间,参数为毫秒值

setRTS(boolean) 设置或清除RTS位

setDTR(boolean) 设置或清除DTR位

close() 关闭串口

getOutputStream() 得到OutputStream类型的输出流

getInputStream() 得到InputStream类型的输入流

网上下载javacomm20-win32.zip文件,解压,把三个重要的文件放到指定的目录下。将下载的文件解压缩后,在\javacomm20-win32\commapi目录下有必需的三个文件comm.jar,javax.comm. properties和win32comm.dll。将文件comm.jar拷贝到%JAVA_HOME%\jre\lib\ext,并将其路径写入到path中;文件javax.comm. properties拷贝到%JAVA_HOME%\jre\lib;文件win32comm.dll拷贝到%JAVA_HOME%\bin。注意%JAVA_HOME%是jdk的路径,而非jre。(注意路径一定要设置正确。)

上面一些是java串口编程的解释说明和所要的配置环境,网上还有其他好多类似的文章,大家多看看就OK了。同API下载的还有一些例子,我根据他给的例子改写了自己需要的程序我的程序代码如下:

下面这个主要是利用线程查询串口是否有数据,有的话就读取。由于读出过程中,遇到了乱码问题,上网搜了许多资料,最终解决了乱码问题。从相应串口读出的数据,不要进行其他处理,直接进行十六进制转换,就不会出现乱码问题。

package comread;
import comread.StringToHex;
import java.io.*;
import java.util.*;
import javax.comm.*;
/**
*
* @author Administrator
*/
public class ComRead implements Runnable{
static CommPortIdentifier portId;
static Enumeration portList;//枚举类
InputStream inputStream;
SerialPort serialPort;
Thread readThread;
StringToHex sHex;
public void start(){
portList=CommPortIdentifier.getPortIdentifiers();//利用枚举类型得到所有通信端口
while(portList.hasMoreElements()){
portId=(CommPortIdentifier)portList.nextElement();
if(portId.getPortType()==CommPortIdentifier.PORT_SERIAL){//如果为串口的话
///System.out.println(portId.getName());
if(portId.getName().equals("COM3")){//如果是COM3,这里需要你自己设定指定的串口
try{
//打开串口
serialPort=(SerialPort)portId.open("Main",2000);
}catch(PortInUseException e){}
try {
inputStream = serialPort.getInputStream();/*获取端口的输入流对象*/
} catch (IOException e) {}
}// end if
}// end if
}// end while
try{
readThread = new Thread(this);
//线程负责每发送一次数据,休眠2秒钟
readThread.start();
}
catch (Exception e) { }
}
public void run(){

try{
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
}catch (UnsupportedCommOperationException e) { }
byte[] readB=new byte[21];
byte[] readC=new byte[21];
int nBytes=0;
String Buff="";
String Buffer="";
try{
while(inputStream.available()>0){
nBytes = inputStream.read(readB);
}
sHex.printHexString(readB);//将读出的字符数组数据,直接转换成十六进制。
}catch(IOException e){
System.err.println(e.toString());
}
try {
Thread.sleep(2000); //读取数据成功,继续start
} catch (InterruptedException e) { }
start();
}
}


下面这个主要进行的是十六进制转换。

package comread;

/**
*
* @author Administrator
*/
public class StringToHex {
public static void printHexString( byte[] b) {
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF)+" ";
if (hex.length() == 2) {
hex = '0' + hex;
}
System.out.print(hex.toUpperCase() );
}
System.out.println("\t\n");
}
}


主函数

package comread;
import comread.ComRead;

/**
*
* @author Administrator
*/
public class Main {

/**
* @param args the command line arguments

*/
public static void main(String[] args) {
// TODO code application logic here
ComRead comread=new ComRead();
comread.start();
}
}


上面这些代码,我已经运行过了,没有错误。我运行这个程序可以成功接收CC2531从串口转发过来的数据,数据的格式没有错误。希望,我的这些心得对大家有帮助。有什么不足,希望能够得到大家的指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐