本文主要是java串口编程的例子
首先,要有comm.jar包
package cc.dfsoft.ranqi.util; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import javax.comm.CommPortIdentifier; import javax.comm.NoSuchPortException; import javax.comm.PortInUseException; import javax.comm.SerialPort; import javax.comm.UnsupportedCommOperationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import cc.dfsoft.ranqi.bo.MachineCommand; import cc.dfsoft.ranqi.service.bean.gz.zngz.Command10Mgr; import cc.dfsoft.ranqi.service.bean.gz.zngz.impl.Command10; public class SerialBean{ protected Log logger = LogFactory.getLog("serialBean"); private String PortName; CommPortIdentifier portId; private SerialPort serialPort; private OutputStream out; private InputStream in; static int waitTime = 0; public SerialBean(int PortID) { PortName = "COM" + PortID; if(PortName.equalsIgnoreCase("com6")){ logger = LogFactory.getLog("singal"); } } /** * 新修改的接口,直接传入串口名称 * @param PortID */ public SerialBean(String PortID) { PortName = PortID; if(PortName.equalsIgnoreCase("com6")){ logger = LogFactory.getLog("singal"); } } /** * * This function initialize the serial port for communication. It startss a * thread which consistently monitors the serial port. Any signal capturred * from the serial port is stored into a buffer area. * 本函数初始化所指定的串口并返回初始化结果。 * 如果初始化成功返回1,否则返回-1。 * 初始化的结果是该串口被SerialBean独占性使用,其参数被设置为9600, N, 8, 1。 * 如果串口被成功初始化,则打开一个进程读取从串口传入的数据并将其保存在缓冲区中。 * */ public synchronized int initialize() { int InitSuccess = 1; int InitFail = -1; try { portId = CommPortIdentifier.getPortIdentifier(PortName); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); try { serialPort = (SerialPort) portId.open("Serial_Communication"+PortName,3600); } catch (PortInUseException e) { e.printStackTrace(); return InitFail; } //Use InputStream in to read from the serial port, and OutputStream //out to write to the serial port. InitFail = initStream(); //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) { logger.info(e.getMessage()); e.printStackTrace(); return InitFail; } } catch (NoSuchPortException e) { logger.info(e.getMessage()); e.printStackTrace(); return InitFail; } return InitSuccess; } private int initStream() { try { in = serialPort.getInputStream(); out = serialPort.getOutputStream(); } catch (IOException e) { logger.info(e.getMessage()); e.printStackTrace(); return -1; } return 1; } /** * This function returns a string with a certain length from the incomin messages. * 本函数从串口(缓冲区)中读取指定长度的一个字符串。参数Length指定所返回字符串的长度。 */ public synchronized byte[] readPort(byte[] aByte) { //logger.fatal("线程---串口:" + PortName + " 主机:" + aByte[0] + " 命令:" + aByte[1] + " 进入readPort方法"); //initialize(); //initStream(); PropertyUtil proUtil = new PropertyUtil(); waitTime = Integer.parseInt(proUtil.getCom("waitTime"));//读取配置文件中设置的等待时间 byte[] bf = new byte[100];//供接收使用 byte[] content = new byte[0]; //update in 20070918 by liulei ,锁当前资源 try { for (int i = 0; i < aByte.length; i++) { out.write(aByte[i]); } out.flush(); //Thread.sleep(waitTime); int j = 0; while(in.available() == 0) { Thread.sleep(waitTime); if(j > 2) { logger.fatal("跳出循环,当前j== " + j + "无法读到字节数组; 串口:" + PortName + ",主机:" + aByte[0] + " ,命令:" + aByte[1]); //update by liulei in 2007.10.20,关闭串口同时关闭输入输出流 //in.close(); //out.close(); //closePort(); return content; } j++; } logger.info(PortName +":读到的字节数组长度----------------" + in.available()); } catch (Exception e) { logger.info(e.getMessage()); e.printStackTrace(); } //update in 20070918 by liulei ,锁当前资源 try { //logger.info("读到的字节数组长度:=== " + in.available()); while(in.available() > 0) { int num = in.read(bf);//从输入流中读取一定数量的字节并将其存储在缓冲区数组bf中 content = new byte[num]; for(int k = 0;k < num;k++){ content[k] = bf[k]; } } } catch (Exception e) { logger.info(e.getMessage()); e.printStackTrace(); } //logger.info("得到值,关闭串口正常退出!"); //update by liulei in 2007.10.20,关闭串口同时关闭输入输出流 /* try { in.close(); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } closePort(); */ StringBuffer printResult = new StringBuffer(); if(aByte.length > 0) { for (int i = 0; i < aByte.length; i++) { printResult.append(aByte[i]); printResult.append(","); } } logger.error("向串口: " + PortName + " 发送指令 : " + printResult.toString()); StringBuffer printResult1 = new StringBuffer(); if(content.length > 0) { for (int i = 0; i < content.length; i++) { printResult1.append(content[i]); printResult1.append(","); } } logger.error("从串口: " + PortName + " 返回值 : " + printResult1.toString()); //判断10指令的处理结果 if(aByte[1] == 16 && printResult1.toString().trim().length() == 9){ if(aByte[2] == 0){ logger.info("校验不成功......"); } if(aByte[2] == 1){ logger.info("校验成功......"); } } //判断10指令的处理结果 if(aByte[1] == 5 && printResult1.toString().trim().length() == 9){ logger.info("校验不成功......"); } if(aByte.length > 0 && content.length > 0) { if(aByte[0] != content[0] || aByte[1] != content[1]) { //logger.error("当前线程:" + Thread.currentThread().getName() + "从串口名称: " + PortName + "得到值不一致,进行拦截处理"); return new byte[0]; } } return content; } /** * This function sends a message through the serial port. * @param aByte The data of byte to be sent. * 本函数向串口发送一个字符串。参数Msg是需要发送的字符串。 */ public void writePort(byte[] aByte) { PropertyUtil proUtil = new PropertyUtil(); waitTime = Integer.parseInt(proUtil.getCom("waitTime"));//读取配置文件中设置的等待时间 //update in 20070918 by liulei ,锁当前资源 try { for (int i = 0; i < aByte.length; i++) { out.write(aByte[i]); } Thread.sleep(waitTime); //closePort(); //initialize(); } catch (Exception e) { e.printStackTrace(); } } /** * * This function closes the serial port in use. * 本函数停止串口检测进程并关闭串口。 */ public void closePort() { //RT.stop(); serialPort.close(); } }
图中蓝色部分为主要的初始化工作