起因是做微信跳一跳物理辅助,用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 {
}
}
}