http://www.csdn.net/expert/topic/84/84387.shtm

解决方案 »

  1.   

    转自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)  
    [email protected]  
    *  
    */  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)  
    [email protected]  
    *  
    */  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  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)  
    [email protected]  
    *  
    */  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)  
    [email protected]  
    *  
    */  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)  
    [email protected]  
    *  
    */  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