java与51单片机串口通信

2019-04-15 18:43发布

起因是做微信跳一跳物理辅助,用java控制单片机,单片机控制马达点击屏幕,这里协议所以只是简单的电脑端发送一个字节,单片机接收到这个字节后设置p0口,并返回收到的字节。串口java端库用的RXTXcomm.jar,注意还要安装rxtxParallel.dll和rxtxSerial.dll,看下面代码里说明。另外注意用11.0592mhz晶振,不然收发的字节会错误。java端代码示例:package com.superzlc.zlctest.proj.camctrl; import gnu.io.CommPortIdentifier; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; import gnu.io.UnsupportedCommOperationException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.TooManyListenersException; /** * 测试rxtx操作串口 * * rxtx下载自https://bitbucket.org/jlauer/mfz-cdn/downloads/mfz-rxtx-2.2-20081207-win-x64.zip。 * 之前从http://rxtx.qbang.org/pub/rxtx/rxtx-2.1-7-bins-r2.zip下载的,没有x64版本dll。 * * 使用的jdk安装在C:Program FilesJavajdk1.8.0_60,所以, * 解压的文件rxtxParallel.dll和rxtxSerial.dll放到C:Program FilesJavajdk1.8.0_60in * 解压的文件RXTXcomm.jar放到C:Program FilesJavajdk1.8.0_60jrelibext * * 另外找RXTXcomm.jar的mvn库,找到org.rxtx:rxtx:2.1.7看应该是一样的,但是没见jar包带dll,这样dll应该还是要手动放 * * @author zhanglc-c */ public class TestRxTx { public static void main(String[] args) throws Exception { CommPortIdentifier port = getSerialPort("COM6"); System.out.println(port.getName()); SerialPortClient client = new SerialPortClient(port); client.initAndOpen(); client.send(new byte[]{(byte) 0x05}); client.send(new byte[]{(byte) 0x02}); for (int i = 0; i < 10; i++) { System.out.println(i); client.send(new byte[]{(byte) i}); Thread.sleep(200); } client.close(); } // 列出端口 public static Enumeration listAllPort() { @SuppressWarnings("unchecked") Enumeration portList = CommPortIdentifier .getPortIdentifiers(); return portList; } public static List listAllPort(int portType) { List ret = new ArrayList<>(); Enumeration all = listAllPort(); if (all == null) return ret; while (all.hasMoreElements()) { CommPortIdentifier portId = (CommPortIdentifier) all.nextElement(); if (portId.getPortType() == portType) { ret.add(portId); } } return ret; } public static List listAllSerialPort() { return listAllPort(CommPortIdentifier.PORT_SERIAL); } // 获取串口 public static CommPortIdentifier getSerialPort(String portName) { List list = listAllSerialPort(); if (list == null) return null; for (CommPortIdentifier p : list) { if (p.getName().equalsIgnoreCase(portName)) { return p; } } return null; } // 串口操作 public static class SerialPortClient implements SerialPortEventListener { public final CommPortIdentifier port; public SerialPort serialPort; public InputStream is; public OutputStream os; public SerialPortClient(CommPortIdentifier port) { this.port = port; } public void initAndOpen() throws IOException, UnsupportedCommOperationException, TooManyListenersException, PortInUseException { System.out.println("串口:初始化和打开。。。(波特率9600,数据位8,停止位1,无奇偶校验)"); serialPort = (SerialPort) port.open("SerialPort-Test", 2000); serialPort.addEventListener(this); serialPort.notifyOnDataAvailable(true); serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); os = serialPort.getOutputStream(); is = serialPort.getInputStream(); } public void close() { System.out.println("串口:关闭。。。"); if (os != null) try { os.close(); } catch (IOException e) { } if (is != null) try { is.close(); } catch (IOException e) { } if (serialPort != null) serialPort.close(); } public void send(byte[] arr) throws IOException { if (arr != null && os != null) { System.out.println("串口:发送字节个数" + arr.length); os.write(arr); } else { System.out.println("串口:发送失败,发送数据为空或没打开串口"); } } protected void onReceive(SerialPortEvent event) { System.out.println("串口:读数据。。。"); int newData = 0; do { try { newData = is.read(); System.out.println("串口:读到数据:" + Integer.toString(newData, 16)); } catch (IOException e) { return; } } while (newData != -1); } public void serialEvent(SerialPortEvent event) { 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: break; case SerialPortEvent.DATA_AVAILABLE:// 获取到串口返回信息 onReceive(event); break; default: break; } } } }单片机端示例:#include #define uint unsigned int #define uchar unsigned char uchar LEDOFF = 0xff; uchar LEDON = 0x00; uchar MYSBUF; bit MYT1 = 0; bit MYR1 = 0; void my_interrupt() interrupt 4 { if(RI == 1) { RI = 0; MYR1 = 1; MYSBUF = SBUF; } if (TI == 1) { TI = 0; MYT1 = 1; } } void main() { SCON = 0x50; //串口方式1, 8-n-1, 允许接收. TMOD = 0x20; //T1方式2 TH1 = 0xFD; //9600bps@11.0592MHz TL1 = 0xFD; TR1 = 1; ES = 1; //开中断. EA = 1; P0 = 0x0f; while(1) { if (MYR1 == 1) { SBUF = MYSBUF; P0 = MYSBUF; P2 = MYSBUF; MYR1 = 0; } else { } } }