JAVA写串口程序

来源:互联网 发布:数据结构算法 编辑:程序博客网 时间:2024/05/17 22:26

JAVA提供的串口操作的包(javax,comm),可以用于PC的串口一般操作,其包内的方法基本有如下几个

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


       有了以上方法,基本就可以对串口操作了。而JAVA开发起来也比较容易,我第一次用JAVA开发桌面程序就没有想象中那么艰辛。

       一般的单片机都有串口,所以与PC机通信的时候,一般均会选择串口将采集到数据或者是其他什么发送出来,然后PC机进行接收,进行或简单或复杂的数据处理,然后予以显示。这一般就是一个上位机的搭建吧!

      基本的串口操作就是这么几个步骤:枚举本机可用串口,选定串口并打开,设置串口,数据通信!

      在SUN公司给的DOME中,基本的串口操作就都有了,只要稍加修改就可。

      步骤1:枚举本机串口

      在网上搜了几个代码,基本都是差不多的。使用 getPortIdentifiers() 方法得到系统中的串口列表,然后通过portId.getPortType()   ==   CommPortIdentifier.PORT_SERIAL    ,判断是否为COM端口,然后我把结果放入了COMBOBOX(组合框中)。

    private void listPortChoices()
    {
        //Enumeration 为枚举型类
        Enumeration   en   =   CommPortIdentifier.getPortIdentifiers();
        while   (en.hasMoreElements())  
           {
                    portId   =   (CommPortIdentifier)   en.nextElement();
                    if (portId.getPortType()   ==   CommPortIdentifier.PORT_SERIAL)  
                    {
                            comboBoxCommPort.addItem(portId.getName());
                    }
           }
    }

       步骤2:选定串口,并打开。

       上一步我将串口的名称放入了组合框COMBOBOX中,那么,只要加入监@听,当有选择的动作时候,返回所选择的字符串,再通过放方法getPortIdentifier(CommPort) 打开所选择的串口。代码如下。

     try
     {
            portId =  CommPortIdentifier.getPortIdentifier(CommChoose);
     }
     catch (NoSuchPortException e)
     {
            MessagetextArea.append("端口不存在"+"/n");
     }  

     如果抛出异常,就该检查端口是否正常连接了。不过一般这不会出错。

     然后是打开串口,只需使用open(String, int) 这个方法就好。String为工程的名字,int则为延时。

     try       
     {//打开所选择的串口
                serialPort = (SerialPort)portId.open("Comm",2000);
      }  
      catch   (PortInUseException e)
      {     
                MessagetextArea.append("打开串口"+portId.getName()+"失败"+"/n"); 
      }

      按照以上代码,那么,就成功的打开串口了。但是还需要对串口进行配置。

      步骤3:串口的配置

      配置代码如下,

      try  
      {//获得输入输出流
            inputStream   =   serialPort.getInputStream();
            outputStream  =   serialPort.getOutputStream();
       }
       catch   (IOException   e)  
       {
             MessagetextArea.append("获取串口"+portId.getName()+"输入输出流失败"+"/n"); 
             serialPort.close();
             MessagetextArea.append("已关闭串口"+portId.getName()+"/n"); 
       }
       
        try  
        {//为串口添加兼听器
              CommProtDateAction CommProtDateAction = new CommProtDateAction("GetDate");
              serialPort.addEventListener(CommProtDateAction);
        }  
        catch   (TooManyListenersException   e)
        {             
              MessagetextArea.append("兼听串口"+portId.getName()+"失败"+"/n"); 
              serialPort.close();
              MessagetextArea.append("已关闭串口"+portId.getName()+"/n");
       }
       serialPort.notifyOnDataAvailable(true);    //设置数据事件有效,中断?!
       
        try  
        {//配置串口
                 serialPort.setSerialPortParams(9600,//波特率9600bps
                                     SerialPort.DATABITS_8,//8位数据位
                                     SerialPort.STOPBITS_1,//1位停止位
                                     SerialPort.PARITY_NONE);//无校验
                 MessagetextArea.append("串口波特率:9600"+"/n");
                 MessagetextArea.append("串口数据位:8位"+"/n");
                 MessagetextArea.append("串口停止位:1位"+"/n");
                 MessagetextArea.append("串口校验方式:无校验"+"/n");
        }  
        catch   (UnsupportedCommOperationException   e)  
        {
                MessagetextArea.append("配置串口"+portId.getName()+"失败"+"/n"); 
                serialPort.close();
                MessagetextArea.append("已关闭串口"+portId.getName()+"/n");
       }

     上位机需与下位机进行通讯,所以首先须获得输入输出流,保证自身能接受下位机数据,自身也可以发数据至下位机。

     至于兼听串口,这个我的理解是,有数据则产生“中断”,之后程序将进行“中断”的“服务函数”。这个理解始终还是未脱离单片机,不是那么的地道,但按照程序执行的来看,确实是相当于中断。

     然后是统一数据格式,波特率,数据位多少,停止位多少,是否检验。只要上位机与下位机之间保持一致,那么数据就能良好的传输。

     至此,已经可以进行数据通信了。

     对于PC机(上位机)来说,发送数据的代码如下。

     private void sendDate(String SendData)
    {
         try       //发送~~~~~~~~~~~~!!!!
         {
               outputStream = serialPort.getOutputStream();
               outputStream.write(SendData.getBytes());      
         }
         catch (IOException e)
         {
                MessagetextArea.append("发送数据"+"“"+SendData+"”"+"失败"+"/n");
         }
               MessagetextArea.append("发送数据"+"“"+SendData+"”"+"成功"+"/n");       
    }

    接收数据的代码如下。

  private class CommProtDateAction implements SerialPortEventListener
 {
           private String Mas; 
           public CommProtDateAction(String Message)
          {
                Mas = Message;
          }
          public void   serialEvent(SerialPortEvent event)  
         { 

                     try    //延时0.5秒
                     {
                            Thread.sleep(100);
                    }
                    catch (InterruptedException e)
                    {
                           MessagetextArea.append("延时失败"+"/n");
                    }     
                    //GetTextArea.append("数据到达"+"/n"); 
                  switch(event.getEventType())  
                  {
                        case   SerialPortEvent.BI:
                        case   SerialPortEvent.OE:
                        case   SerialPortEvent.FE:
                        case   SerialPortEvent.PE:
                        case   SerialPortEvent.CD:
                        case   SerialPortEvent.CTS:
                        case   SerialPortEvent.DSR:
                        case   SerialPortEvent.RI:
                        case   SerialPortEvent.OUTPUT_BUFFER_EMPTY: MessagetextArea.append("数据未通过校验"+"/n");
                                                                                                             break;
                        case   SerialPortEvent.DATA_AVAILABLE://如果有数据到达
                        byte[] readBuffer = new byte[20];
                        try  
                          {
                              while   (inputStream.available()>0)  
                                   { //读取一个字节到readBuffer
                                          int number = inputStream.read(readBuffer);
                                          getDate = readBuffer[0];
                                          MessagetextArea.append("数据" + getDate + "到达/n");
                                    }
                       }
                  }
                  catch (IOException   e)
                  {
                   MessagetextArea.append("串口"+portId.getName()+"接收数据失败"+"/n");
                  }
          }
     }
   }

       最后,接收的数据就存储在getDate之中。如果数据不是单个的,那么就加点数据处理的语句。以上为我删减的后的代码,我进行了数据的处理,这个就按照自己的意愿或者要求来就好,并不是一定的必须怎么处理。