Java串口通信(代码+测试工具)

时间:2022-11-24 11:37:34

1.window7 64位操作系统的话  要使用java 64位的串口通信包:http://download.csdn.net/detail/likekobe2012/9149871

将里面的三个文件分别放到这里  <JAVA_HOME>代表你的jdk安装目录,比如我的是C:\Program Files (x86)\Java\jdk1.6.0_31 

Copy RXTXcomm.jar ---> <JAVA_HOME>/jre/lib/ext
Copy rxtxSerial.dll ---> <JAVA_HOME>/jre/lib/i386/
Copy rxtxParallel.dll ---> <JAVA_HOME>/jre/lib/i386/


2.再把rxtxSerial.dll、rxtxParallel.dll复制到C:\Windows\System32文件夹下


3.开启MyEclipse新建项目,BuildPath导入RXTXcomm.jar


4.利用虚拟串口工具建立一个虚拟串口对,http://download.csdn.net/detail/likekobe2012/9149879,这里将COM2、COM5建立串口对


5.利用串口调试工具,开启两个,进行测试,com2、com5是可以通信的,http://download.csdn.net/detail/likekobe2012/9149929

Java串口通信(代码+测试工具)


6.代码

package com;

import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;

/**
 * 
 * 串口工具的调试
 * <功能详细描述>
 * 
 * @author  like
 * @version  [版本号, 2015-9-30]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class CommTest implements Runnable, SerialPortEventListener
{
    private String m_sAppName = "串口测试工具Like";
    
    /**
     * 端口的等待时间
     */
    private int m_iWaitTime = 2000;
    
    /**
     * 线程时间
     */
    private int m_iThreadTime = 0;
    
    private CommPortIdentifier m_commPort;
    
    private SerialPort m_serialPort;
    
    private InputStream m_inputStream;
    
    private OutputStream m_outputStream;
    
    /**
     * 列出所有端口
     * <功能详细描述>
     * @see [类、类#方法、类#成员]
     */
    @SuppressWarnings("rawtypes")
    public void listPort()
    {
        CommPortIdentifier commPortIdentifier;
        Enumeration enumeration = CommPortIdentifier.getPortIdentifiers();
        System.out.println("现在列出所有PC端口:" + enumeration);
        
        while (enumeration.hasMoreElements())
        {
            commPortIdentifier = (CommPortIdentifier)enumeration.nextElement();
            if (commPortIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
            {
                System.out.println(commPortIdentifier.getName() + "," + commPortIdentifier.getCurrentOwner());
            }
        }
    }
    
    /**
     * 根据端口名选中端口
     * <功能详细描述>
     * @param sPortName
     * @see [类、类#方法、类#成员]
     */
    @SuppressWarnings("rawtypes")
    public void selectPort(String sPortName)
    {
        m_commPort = null;
        CommPortIdentifier commPortIdentifier;
        Enumeration enumeration = CommPortIdentifier.getPortIdentifiers();
        
        while (enumeration.hasMoreElements())
        {
            commPortIdentifier = (CommPortIdentifier)enumeration.nextElement();
            
            if (commPortIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL
                && commPortIdentifier.getName().equals(sPortName))
            {
                m_commPort = commPortIdentifier;
                openPort();
                break;
            }
        }
    }
    
    /**
     * 打开端口
     * <功能详细描述>
     * @see [类、类#方法、类#成员]
     */
    public void openPort()
    {
        if (m_commPort == null)
        {
            log(String.format("无法找到名字为'%1$s'的串口", m_commPort.getName()));
            
        }
        else
        {
            log("端口选择成功,当前端口:" + m_commPort.getName() + ",现在实例化 serialPort:");
            
            try
            {
                m_serialPort = (SerialPort)m_commPort.open(m_sAppName, m_iWaitTime);
                log("实例化 serialPort成功!");
            }
            catch (PortInUseException e)
            {
                throw new RuntimeException(String.format("端口'%1$s'正在使用中!", m_commPort.getName()));
            }
        }
    }
    
    /**
     * 检查端口是否正确连接 
     * <功能详细描述>
     * @see [类、类#方法、类#成员]
     */
    public void checkPort()
    {
        if (m_commPort == null)
        {
            throw new RuntimeException("没有选择端口,请使用 selectPort(string sPortName)方法选择端口");
        }
        if (m_serialPort == null)
        {
            throw new RuntimeException("serialPort对象为null");
            
        }
    }
    
    /**
     * 向端口发送数据
     * <功能详细描述>
     * @param sMessage
     * @see [类、类#方法、类#成员]
     */
    public void write(String sMessage)
    {
        checkPort();
        try
        {
            m_outputStream = new BufferedOutputStream(m_serialPort.getOutputStream());
        }
        catch (IOException e)
        {
            throw new RuntimeException("获取端口的OutputStream出错" + e.getMessage());
        }
        
        try
        {
            m_outputStream.write(sMessage.getBytes());
            log("向端口发送信息成功:" + sMessage);
        }
        catch (IOException e)
        {
            throw new RuntimeException("向端口发送信息时出错:" + e.getMessage());
        }
        finally
        {
            try
            {
                m_outputStream.close();
            }
            catch (Exception e)
            {
                
            }
            
        }
    }
    
    /**
     * 开始监听从端口中接收的数据
     * <功能详细描述>
     * @param iTime
     * @see [类、类#方法、类#成员]
     */
    public void startRead(int iTime)
    {
        checkPort();
        try
        {
            m_inputStream = new BufferedInputStream(m_serialPort.getInputStream());
        }
        catch (IOException e)
        {
            throw new RuntimeException("获取端口的InputStream出错:" + e.getMessage());
        }
        
        try
        {
            m_serialPort.addEventListener(this);
        }
        catch (TooManyListenersException e)
        {
            throw new RuntimeException(e.getMessage());
        }
        
        m_serialPort.notifyOnDataAvailable(true);
        
        log(String.format("开始监听来自'%1$s'的数据----------", m_commPort.getName()));
        if (iTime > 0)
        {
            m_iThreadTime = iTime * 1000;
            Thread thread = new Thread(this);
            thread.start();
            log(String.format("监听程序将在%1$d秒后关闭", m_iThreadTime));
        }
    }
    
    public void close()
    {
        m_serialPort.close();
        m_serialPort = null;
        m_commPort = null;
    }
    
    /**
     * 记录日志
     * <功能详细描述>
     * @param sMessage 日志信息
     * @see [类、类#方法、类#成员]
     */
    public void log(String sMessage)
    {
        System.out.println(m_sAppName + "-->" + sMessage);
    }
    
    @Override
    public void run()
    {
        try
        {
            Thread.sleep(m_iThreadTime);
            m_serialPort.close();
            log(String.format("端口'%1$s'监听关闭了!", m_commPort.getName()));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    @Override
    public void serialEvent(SerialPortEvent arg0)
    {
        switch (arg0.getEventType())
        {
            case SerialPortEvent.BI:/*Break interrupt,通讯中断*/
            case SerialPortEvent.OE:/*Overrun error,溢位错误*/
            case SerialPortEvent.FE:/*Framing error,传帧错误*/
            case SerialPortEvent.PE:/*Parity error,校验错误*/
            case SerialPortEvent.CD:/*Carrier detect,载波检测*/
            case SerialPortEvent.CTS:/*Clear to send,清除发送*/
            case SerialPortEvent.DSR:/*Data set ready,数据设备就绪*/
            case SerialPortEvent.RI:/*Ring indicator,响铃指示*/
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty,输出缓冲区清空*/
                break;
            case SerialPortEvent.DATA_AVAILABLE:/*Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端*/
                byte[] readBuffer = new byte[1024];
                String readStr = "";
                String s2 = "";
                
                try
                {
                    while (m_inputStream.available() > 0)
                    {
                        m_inputStream.read(readBuffer);
                        readStr += new String(readBuffer).trim();
                    }
                    
                    s2 = new String(readBuffer).trim();
                    
                    log("接收到端口返回数据(长度为" + readStr.length() + "):" + readStr);
                    log(s2);
                }
                catch (IOException e)
                {
                }
        }
        
    }
    
}


7.由于com2、com5是连接的,我们测试的时候,向com2写数据,串口调试助手com5里面是可以接收到数据的

package com;

public class CommUseTest
{
    public static void main(String[] args)
        throws InstantiationException, IllegalAccessException
    {
        CommTest com = new CommTest();
        
        com.listPort();
        
        com.selectPort("COM2");
        com.write("Too young Too simple,sometimes naive!!!");
        com.startRead(10);
    }
    
}

Java串口通信(代码+测试工具)




8.利用java程序接收从串口调试助手发来的信息,串口调试助手利用com5发送数据

package com;

public class CommUseTest
{
    public static void main(String[] args)
        throws InstantiationException, IllegalAccessException
    {
        CommTest com = new CommTest();
        
        com.listPort();
        
        com.selectPort("COM2");
        //com.write("Too young Too simple,sometimes naive!!!");
        com.startRead(100);
    }
    
}

Java串口通信(代码+测试工具)