java与51单片机串口通信

起因是做微信跳一跳物理辅助,用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 Files\Java\jdk1.8.0_60,所以,
 * 解压的文件rxtxParallel.dll和rxtxSerial.dll放到C:\Program Files\Java\jdk1.8.0_60\bin
 * 解压的文件RXTXcomm.jar放到C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext
 *
 * 另外找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<CommPortIdentifier> listAllPort() {
		@SuppressWarnings("unchecked")
		Enumeration<CommPortIdentifier> portList = CommPortIdentifier
				.getPortIdentifiers();
		return portList;
	}

	public static List<CommPortIdentifier> listAllPort(int portType) {
		List<CommPortIdentifier> ret = new ArrayList<>();
		Enumeration<CommPortIdentifier> 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<CommPortIdentifier> listAllSerialPort() {
		return listAllPort(CommPortIdentifier.PORT_SERIAL);
	}

	// 获取串口
	public static CommPortIdentifier getSerialPort(String portName) {
		List<CommPortIdentifier> 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<reg52.h>

#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;    //[email protected]
	TL1 = 0xFD;
	TR1 = 1;
	ES  = 1;       //开中断.
	EA  = 1;

	P0 = 0x0f;

	while(1)  { 
		if (MYR1 == 1)  {
			SBUF = MYSBUF;
			P0 = MYSBUF;
			P2 = MYSBUF;
			MYR1 = 0;
		} else {
		}
	}
}




猜你喜欢

转载自blog.csdn.net/superzlc/article/details/79580195