Java和51单片机串口通信(Java发送数据到单片机,单片机反馈数据到电脑)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java和51单⽚机串⼝通信(Java发送数据到单⽚机,单⽚机反
馈数据到电脑)
Java发送字符串到单⽚机,单⽚机返回给电脑
----------------------------------------------------------------------------------------------------
材料:
1. 51单⽚机
2. Java客户端
3. Keil程序
----------------------------------------------------------------------------------------------------
⼀、单⽚机程序
在Keil中新建⼯程,编写程序,⽣成 .hex ⽂件(这个⽂件可以烧录到单⽚机中)
/*
串⼝通信:
1、由PC机通过串⾏⼝向单⽚机发送数据,这个数据是存放在单⽚机的接收缓冲器SBUF中的;
2、单⽚机将串⾏⼝中的数据存放在⼀个临时变量中;
3、单⽚机将存放在临时变量中的数据发送到发送缓冲器SBUF中,在PC机上显⽰。

*/
#include <reg52.h>
#define u16 unsigned int
#define u8 unsigned char
// 串⾏⼝通信初始化函数
void StartInit()
{
/*
1、确定T1的⼯作⽅式(编程TMOD寄存器):因为串⾏⼝中断是由定时器T1决定的,
所以,低四位全部为0,⾼四位中,GATE=0,C/T⾮=0,选择⼯作⽅式1(8位的⾃动重装载),即M1M0=10
所以是:00100000,转成⼗六进制数是:0x20
*/
TMOD=0x20;
/*
2、计算T1的初值,装载TH1、TL1:使⽤⼯具⽣成,设置参数,定时器⽅式:⽅式2;晶振频率:12Mhz;
波特率:4800;SMOD:波特率倍增位,1,即增加1倍;计算结果是:F3H
所以TH1=0xF3,TL1=0xF3,⾃动重装载
*/
TH1=0xF3;
TL1=0xF3;
/*
PCON:与串⾏⼝⼯作相关的参数,只有⼀位SMOD(最⾼位),在串⾏⼝⽅式1、⽅式2、⽅式3时,
波特率与SMOD有关,当SMOD=1时,波特率提⾼⼀倍。

复位时,SMOD=0,
这⾥波特率提⾼⼀倍,所以SMOD=1,即10000000,转成⼗六进制数字是:0x80
*/
PCON=0x80;
/*
4、启动T1(编程TCON中的TR1位):TR1=1时,定时器T1才开始启动
*/
TR1=1;
/*
5、确定串⾏⼝控制(编程SCON寄存器):选择⼯作⽅式1(10位异步收发器,8位数据,1位起始位,1位停⽌位),
所以SM0=0,SM1=1;不需要RB8控制RI的激活(就是为了简单),设置SM2=0(SM2是多机通信控制位);
REN,允许串⾏接收位,启动串⾏⼝接收数据,REN=1;
TB8,RB8,TI,RI均为0(看资料),所以是:01010000,转成⼗六进制数是:0x50
*/
SCON=0x50;
/*
6、中断位的开启,总中断允许位EA=1;串⾏⼝中断允许位ES=1
*/
EA=1;
ES=1;
// 主函数
void main()
{
StartInit(); // 串⾏⼝通信初始化
while(1); // 等待数据的发送和接收
}
// 发送或接收完⼀帧数据引起中断,串⾏⼝中断函数
void Start() interrupt 4
{
u8 receiveData; // ⽤⼀个变量存放数据
receiveData=SBUF; // 从单⽚机的接收缓冲器中获取数据
RI=0; // 当数据接收完成后,由内部硬件将RI置1,所以这⾥需要把RI置0,等待下⼀次继续接收数据
SBUF=receiveData; // 把变量中的数据放到发送缓冲器中,向PC机发送数据
while(!TI); // 当数据发送完成后(即串⾏⼝在发送停⽌位时,由内部硬件将TI置1,所以数据发送完成时TI=1)
TI=0; // 数据发送完成时,要将TI置0,等待下⼀次继续发送数据
}
⼆、使⽤USB线连接电脑和单⽚机(或使⽤RS232/RS485 + MAX232),下载程序到单⽚机
三、编写Java端程序
这个⽂件夹⾥⾯需要注意两点:jar包RXTXcomm需要导⼊到java⼯程⾥⾯去。

另外就是需要将rxtxParallel.dll与rxtxSerial.dll复制在安转JDK的bin⽂件下和jre的bin⽂件夹下⾯,这样才能保证能够正常使⽤这个jar包。

以下是将两个dll⽂件复制的位置
新建Java⼯程:这⾥只是做⼀个测试,没有考虑代码的结构
package com.lvshitech.java51;
import mPort;
import mPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
public class Tools {
/*类⽅法不可改变不接受继承
* 扫描获取可⽤的串⼝
* 将可⽤串⼝添加⾄list并保存⾄list
@SuppressWarnings({ "rawtypes", "unchecked" })
public static final ArrayList<String> uartPortUseAblefind() {
//获取当前所有可⽤串⼝
//由CommPortIdentifier类提供⽅法
Enumeration<CommPortIdentifier> portList=CommPortIdentifier.getPortIdentifiers();
ArrayList<String> portNameList=new ArrayList();
//添加并返回ArrayList
while(portList.hasMoreElements()) {
String portName=portList.nextElement().getName();
portNameList.add(portName);
}
return portNameList;
}
/*
* 串⼝常见设置
* 1)打开串⼝
* 2)设置波特率根据单板机的需求可以设置为57600 ...
* 3)判断端⼝设备是否为串⼝设备
* 4)端⼝是否占⽤
* 5)对以上条件进⾏check以后返回⼀个串⼝设置对象new UARTParameterSetup()
* 6)return:返回⼀个SerialPort⼀个实例对象,若判定该com⼝是串⼝则进⾏参数配置
* 若不是则返回SerialPort对象为null
*/
public static final SerialPort portParameterOpen(String portName,int baudrate) {
SerialPort serialPort=null;
try { //通过端⼝名识别串⼝
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
//打开端⼝并设置端⼝名字 serialPort和超时时间 2000ms
CommPort commPort=portIdentifier.open(portName,1000);
//进⼀步判断comm端⼝是否是串⼝ instanceof
if(commPort instanceof SerialPort) {
System.out.println("该COM端⼝是串⼝!串⼝名称是:" + portName);
//进⼀步强制类型转换
serialPort=(SerialPort)commPort;
//设置baudrate 此处需要注意:波特率只能允许是int型对于57600⾜够
//8位数据位
//1位停⽌位
//⽆奇偶校验
serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8,SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); //串⼝配制完成 log
System.out.println("串⼝参数设置已完成,波特率为"+baudrate+",数据位8bits,停⽌位1位,⽆奇偶校验");
} else { //不是串⼝
System.out.println("该com端⼝不是串⼝,请检查设备!");
//将com端⼝设置为null 默认是null不需要操作
}
} catch (NoSuchPortException e) {
e.printStackTrace();
} catch (PortInUseException e) {
e.printStackTrace();
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
}
return serialPort;
}
/*
* 串⼝数据发送以及数据传输作为⼀个类
* 该类做主要实现对数据包的传输⾄下单板机
*/
/*
* 上位机往单板机通过串⼝发送数据
* 串⼝对象 seriesPort
* 数据帧:dataPackage
* 发送的标志:数据未发送成功抛出⼀个异常
*/
public static void uartSendDatatoSerialPort(SerialPort serialPort,byte[] dataPackage) {
OutputStream out=null;
try {
out=serialPort.getOutputStream();
out.write(dataPackage);
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭输出流
if(out!=null) {
try {
out.close();
out=null;
//System.out.println("数据已发送完毕!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
* 上位机接收数据
* 串⼝对象seriesPort
* 接收数据buffer
* 返回⼀个byte数组
*/
public static byte[] uartReceiveDatafromSingleChipMachine(SerialPort serialPort) {
byte[] receiveDataPackage=null;
InputStream in=null;
try {
in=serialPort.getInputStream();
// 获取data buffer数据长度
int bufferLength=in.available();
while(bufferLength!=0) {
receiveDataPackage=new byte[bufferLength];
in.read(receiveDataPackage);
bufferLength=in.available();
}
} catch (IOException e) {
e.printStackTrace();
}
return receiveDataPackage;
}
public static void main(String[] args) throws Exception {
// 打开串⼝
SerialPort serialPort = portParameterOpen("COM3", 4800);
// 要发送的数据
String dataSend = "【Java和51单⽚机串⼝通信测试,我能吞下玻璃⽽不伤⾝体!】";
int i=1;
while(true) {
// 发送数据到单⽚机
byte []datByte = dataSend.getBytes();
uartSendDatatoSerialPort(serialPort, datByte);
System.out.println("-------------------------------------------------------");
System.out.println((i++) + ". 发送到串⼝的数据:" + dataSend);
// 休眠300ms,等待单⽚机反应
Thread.sleep(500);
// 从单⽚机接收到的数据
byte[] dat = uartReceiveDatafromSingleChipMachine(serialPort);
if(dat != null && dat.length > 0) {
String dataReceive = new String(dat, "GB2312");
System.out.println((i++) + ". 从串⼝接收的数据:" + dataReceive);
} else {
System.out.println("接收到的数据为空!");
}
}
}
}
四、测试
插上USB,右键“我的电脑” - “管理” - “设备管理器” - “端⼝”,可以看到单⽚机的串⼝号
(1)打开单⽚机
(2)运⾏Java程序
以上实现了Java和单⽚机的串⼝通信,扩展:
(1)控制单⽚机的功能模块,⽐如 LED灯的亮灭,蜂鸣器,跑马灯,数码管,电机转动等等。

(2)在(1)的基础上,使⽤Web⼯程做其他扩展实验,通过点击页⾯的按钮。

(3)点击单⽚机上的按钮,向电脑串⼝(Java端)发送数据,在页⾯上显⽰数据。

(4)使⽤C或者GUI开发客户端进⾏(1)(2)(3)的实验,还可以进⾏饼图、柱状图、折线图等形式展现数据规律。

相关文档
最新文档