首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

求做过串口通讯的帮忙看一下

2013-10-29 
求做过串口通信的帮忙看一下import java.awt.EventQueueimport java.awt.event.ActionEventimport java.

求做过串口通信的帮忙看一下


import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Master1View extends JFrame {
private static final long serialVersionUID = 1L;
private JTextField equiNum = new JTextField();
private JButton sendButton;
private JButton receiveButton;
private Master1 master = new Master1();
public Master1View(){
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
sendButton = new JButton("Send");
sendButton.setToolTipText("向Slave 发送告警查询报文");
this.setLayout(null);
sendButton.setBounds(100,300,100,100);
this.add(sendButton);
receiveButton = new JButton("Receive");
receiveButton.setToolTipText("接收Slave 发送过来的报文");
receiveButton.setBounds(250,300,100,100);
this.add(receiveButton);
JLabel equiLabel = new JLabel("请输入设备号(十六进制):");
equiLabel.setBounds(50,500,200,100);
this.add(equiLabel);
equiNum.setBounds(200,530,100,40);
master.setNumString(equiNum.getText().trim());
this.add(equiNum);
sendButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
master.send();
}
});
receiveButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
master.receive();
}
});
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
public void run(){
new MasterView();
}
});
}
}

上面是第一个文件

import java.io.*;
import java.util.*;
import javax.comm.*;
public class SerialCommunication implements SerialPortEventListener{
private static CommPortIdentifier portId;
private static Enumeration portList;
private static SerialPort serialPort;
private static OutputStream outputStream;
private static InputStream  inputStream;
private byte[]sendMessage ; 
private byte[] replyMessage;
private byte[] readBuffer[];
private int count = 0; //用来为一次读取到的数据计数
public void setReadBuffer(byte[] readBuffer){
this.readBuffer = this.readBuffer;
}
public SerialPort getSerialPort(){
return this.serialPort;
}
public void setSendMessage(byte []sendMessage){
this.sendMessage = sendMessage;
}
public byte[] getReplyMessage(){
return replyMessage;
}
/**
 * initial 函数主要用来打开端口及初始化端口的各个参数,如波特率,初始数据为等等。
 */
public void initial(String commPort,int port,int baudRate,int Databits,int Stopbits,int parity){
portList = CommPortIdentifier.getPortIdentifiers();
while(portList.hasMoreElements()){
portId = (CommPortIdentifier)portList.nextElement();
if(portId.getPortType()==CommPortIdentifier.PORT_SERIAL && portId.getName().equals(commPort)){
try{
serialPort = (SerialPort)portId.open("SerialCommunication", port);
}catch(PortInUseException e){
e.printStackTrace();
}
try{
outputStream = serialPort.getOutputStream();
}catch(IOException e){
e.printStackTrace();
}
try{
serialPort.setSerialPortParams(baudRate, Databits, Stopbits, parity);
}catch(UnsupportedCommOperationException e){
e.printStackTrace();
}

}
}
}
/**
 * receive 函数主要用来监听端口,以及接收slave发送过来的报文
 * 
 */
public void receive(){
try{
try{
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
}catch(TooManyListenersException e){
e.printStackTrace();
}
}finally{
serialPort.close();
}
}
/**
 * Send 函数用来发送报文给Master
 */
public void send(){
try{
outputStream.write(sendMessage);
outputStream.flush(); 
System.out.println("Send Over!");

}catch(IOException e){
e.printStackTrace();
}finally{
try{
outputStream.close();
serialPort.close();
}catch(Exceptione){
e.printStackTrace();
}
}
}
@Override
public void serialEvent(SerialPortEvent event) {
switch(event.getEventType()){
case SerialPortEvent.BI: break;/* break interrupt 通讯中断 */
case SerialPortEvent.OE: break;/* Overrun error 溢位错误 */
case SerialPortEvent.FE: break;/* Framing error 传帧错误*/
case SerialPortEvent.PE: break;/* Parity error 校验错误 */
case SerialPortEvent.DATA_AVAILABLE: {/*Data avaliable at the serial port 端口有可用数据,读到缓冲数组,输出到终端*/
int numBytes = 0;
byte []readBuffer = new byte[1024];


while(numBytes != 10)
try {
count = inputStream.read(readBuffer);
replyMessage = new byte[numBytes];
for(int i = numBytes ; i <=numBytes+count-1; i++)
replyMessage[i] = readBuffer[i];
numBytes += count;
} catch (IOException e) {
e.printStackTrace();
}
   }
   }
   }
}
这个是实现一个通用的串口收发程序


import javax.comm.*;
public class Master1 {
private SerialCommunication serialCommunication;
/**
 * 
 */
private final int baudRate = 9600;
private final int Databits = SerialPort.DATABITS_8;
private final int Stopbits = SerialPort.STOPBITS_1;
private final int parity   = SerialPort.PARITY_NONE;
private final String commPort = "COM1";
private final int    port     = 2000;
private byte[] sendMessage;
private byte[] receiveMessage;
private SerialPort serialPort;
private String numString; //端口号
private byte[] validate = new byte[1];
private boolean second = false;  
private int count = 1;
private byte [] readBuffer = new byte[10];
public Master1(){
serialCommunication = new SerialCommunication();
sendMessage = formatSendMessage();
serialCommunication.setSendMessage(sendMessage);
serialPort = serialCommunication.getSerialPort();
serialCommunication.setReadBuffer(readBuffer);
}
/**
 * @param num  从JTextField中获取的设备号
 */
public void setNumString(String num){
this.numString = num;
}
/*
 * 设置readBuffer的大小,在铁丝围栏协议中,固定长度为10
 */
public void send(){
serialCommunication.initial(commPort, port, baudRate, Databits, Stopbits, parity);
serialCommunication.send();
}
public void receive(){
serialCommunication.initial(commPort, port, baudRate, Databits, Stopbits, parity);
serialCommunication.receive();
receiveMessage = serialCommunication.getReplyMessage();
try{
if(receiveMessage[4] == 0x01){
/* 查询是否校验码相符合*/
if(receiveMessage[8] != sendMessage[8]){
/**
 * 校验码不符合,需要重新发送数据包
 */
if(count <= 4){
send();
count++;
}
/**
 * 如果重传次数已经大于四次,那么就停止发送,并且count复位为1,等待下一次的发送
 */
else if(count > 4){
count = 1; 
}
}
else {
/**
 * 协议及校验码都正确,这时master要向slave发送应答报文
 * 这次报文应该属于一次通信中master第二次发送的报文,这时数据区数据应该为0xCCCCH
 */
second = true; 
/*把sendMessage里面的设备号设置为接收到告警报文设备的设备号*/
sendMessage[1]=receiveMessage[1];
sendMessage[2]= receiveMessage[2];
serialCommunication.setSendMessage(sendMessage);
send();
sendMessage = formatSendMessage();
serialCommunication.setSendMessage(sendMessage);
}
}
}finally{
serialPort.close();
}
}

public byte[] formatSendMessage(){
byte[]temp = new byte[10];
/**
 * 构造起始码字节
 */
temp[0] = 0x68;
/**
 * 先把十进制输入的数转换为十六进制,然后再构造报文
 */
if(numString.equals(""))
System.out.println("请输入数据!");
numString = Integer.toHexString(Integer.parseInt(numString));
if(numString.length() > 4){
System.out.println("输入数据超出范围");
}
/**
 *在这里为了防止输入的十进制数转化为十六进制数时不够四位,先构造一个四位的char 数组,然后把numString转换而来的char数组复制到构造的数组中
 *这样可以保证如果设备号转换为十六进制后不够四位,高位能够补0
 */
char c[] = new char[]{'0','0','0','0'};
char []c1 = numString.toCharArray();
for(int i = 0 ; i < c1.length; i++)
c[i] = c1[i];
int []num = new int[4];
for(int i = 0 ; i < 4; i++){
if(c[i] >='0' && c[i] <= '9')
num[i] = c[i]- '0';
else if(c[i] >='a' && c[i] <='z')
num[i] = c[i]-'a';
else if(c[i] >='A' && c[i] <='Z')
num[i] = c[i] - 'A';

}
/**
 *设备号部分要用8421码来表示低位在后,高位在前
 */
temp[1]=(byte) (0x00 |(num[0]<<4));
temp[1]=(byte) (temp[1] | num[1]);
temp[2]=(byte) (0x00 | num[2] << 4);
temp[2]=(byte) (temp[2]| num[3]);
/**
 * 3 是数据区长度   要用BCD码表示,低位在后,高位在前
*/
temp[3]= 0x00 | (0x02<<4);
/**
 * 对于告警查询功能来说,协议类型为0x03
*/
temp[4]= 0x03;
/**
 * 凡是master发出的报文,设备状态区都为0x00


*/
temp[5]= 0x00;
/**
 * 数据区部分随着一次通信中master发送报文的次数不同而不同
 * 本程序认为如果second为false,那么就默认按第一次发送数据进行发送
 */
if(second){
temp[6] = (byte) 0xCC;
temp[7] = (byte) 0xCC;
second = false;
}
/**
 * 一次通信中的第一次通信,也就是master向slave发送查询报文
 */
   else {
temp[6] = (byte) 0xBB;
temp[7] = (byte) 0xBB;
}
/**
 * 校验码部分
 */
for(int i = 0 ; i < 8; i++){
validate[0] += temp[i];
}
validate[0]+= 0x16;  //0x16为结束字节
temp[8] =(byte) (validate[0]/(0x100));//需要把校验和存储起来以便和slave发回来报文的校验和对比
temp[9] = 0x16;

return temp;
}
}
这个是实现我们特定需要的串口收发程序,
为什么是错的呢?哪位大哥能不能帮忙看下!感激不尽
[解决办法]
是不是已经启动了一个实例了
[解决办法]
我看了半天看不到问题!你把出错的信息贴出来。
还有端口换一个试试啊。都提示端口被占用了

热点排行