挫文共享之第一个Java串口通信

本文介绍了一种使用Java实现串口通信的方法,包括串口读取、写入及简单GUI界面的设计过程。作者通过SWT库创建了串口通信应用程序,并详细展示了主类、界面类、读取类和写入类的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是第一次写关于串口通信的东西,开始Google了很多关于Java串口通信的文章,发现所有中文资料就那几个,这让我这种菜鸟情何以堪……不过还好,有一个人介绍了commapi,这是一个Java扩展包,具体神马的就Google吧。在这个包中有两个simple code,分别是串口的read和write。有了它们,简单的串口通信就有了。其他的就是加界面什么的。本来是要求做字符传送和文件传送的,但是要是把文件传送理解为*.txt的话,我真的不想做了(其实现在的状况就是这样)。于是乎我就只想写一个字符传送好了。
我用得比较多的一个Java的GUI库是SWT,虽然它不是很全,而且不那么跨平台,但是很好用且界面和本地界面契合地比较好。
下面就看看我的写的一个串口通信吧,实现了传字符,传文件只做了一个界面……
主类mainclass:
 
 
package commpi;

import org.eclipse.swt.widgets.Display;

public class mainclass {
private static UIclass UIdata;//界面类
private static readClass readClass;//串口读取类
private static writeClass sendclass;//串口写入类
public static void main(String[] args){
UIdata = new UIclass();
UIdata.getShell().open();
readClass = new readClass(UIdata);
sendclass = new writeClass(UIdata);
Display display = UIdata.getDisplay();
while (!UIdata.getShell().isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}

界面类UIClass:
package commpi;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;

public class UIclass {
private Display display = new Display();
private Shell shell;
private final int x_len = 500;
private final int y_len = 500;
private TabFolder twoChoiceTabFolder;
private TabItem charItem,fileItem;
private Group group1,group2;
private Text readText,writeText,fileReadText,fileWriteText;
private Label readLabel,writeLabel,sendLabel,receiveLabel;
private Label FileReceiveLabel,serialFileReceivelLabel,FileSendLabel,serialFileSendLabel;
private Text sPText,rPText,sFPText,rFPText;
private Button sendButton,receiveButton,fileSendButton,fileReceiveButton;
public UIclass(){
init();
}
private void init(){
shell = new Shell(display,SWT.CLOSE | SWT.MIN);
shell.setText("串口通信");
shell.setSize(x_len, y_len);
twoChoiceTabFolder = new TabFolder(shell, SWT.NONE);
twoChoiceTabFolder.setBounds(5, 5, 487, 460);
charItem = new TabItem(twoChoiceTabFolder, SWT.NONE);
charItem.setText("字符收发");
fileItem = new TabItem(twoChoiceTabFolder, SWT.NONE);
fileItem.setText("文件收发");
{
group1 = new Group(twoChoiceTabFolder, SWT.NONE);
charItem.setControl(group1);
group1.setBounds(5, 25, 475, 430);
readLabel = new Label(group1, SWT.NONE);
readLabel.setText("收到的字符:");
readLabel.setBounds(15, 15, 100, 15);
readText = new Text(group1, SWT.BORDER | SWT.LEFT | SWT.V_SCROLL);
readText.setBounds(7,35,460,150);
receiveLabel = new Label(group1, SWT.NONE);
receiveLabel.setText("输入串口后点击按钮开始接收数据:");
receiveLabel.setBounds(15, 193, 185, 15);
rPText = new Text(group1, SWT.BORDER);
rPText.setBounds(205, 193, 80, 20);
receiveButton = new Button(group1, SWT.NONE);
receiveButton.setText("接收");
receiveButton.setBounds(290, 190, 150, 25);
writeLabel = new Label(group1, SWT.NONE);
writeLabel.setText("发送的字符:");
writeLabel.setBounds(15, 225, 100, 15);
writeText = new Text(group1, SWT.BORDER | SWT.LEFT | SWT.V_SCROLL);
writeText.setBounds(7,245,460,150);
sendLabel = new Label(group1,SWT.NONE);
sendLabel.setText("输入串口后点击按钮发送:");
sendLabel.setBounds(15,405,140,15);
sPText = new Text(group1, SWT.BORDER);
sPText.setBounds(160, 403, 60, 20);
sendButton = new Button(group1, SWT.NONE);
sendButton.setText("发送");
sendButton.setBounds(250, 400, 180, 25);
}
{
group2 = new Group(twoChoiceTabFolder, SWT.NONE);
fileItem.setControl(group2);
group2.setBounds(5, 25, 475, 430);
FileReceiveLabel = new Label(group2, SWT.NONE);
FileReceiveLabel.setText("输入接收到的文件的路径:");
FileReceiveLabel.setBounds(15, 25, 145, 15);
fileReadText = new Text(group2, SWT.BORDER);
fileReadText.setBounds(160,25,300,20);
serialFileReceivelLabel = new Label(group2, SWT.NONE);
serialFileReceivelLabel.setText("输入串口后点击按钮开始接收文件:");
serialFileReceivelLabel.setBounds(15, 60, 190, 15);
sFPText = new Text(group2, SWT.BORDER);
sFPText.setBounds(215, 60, 120, 20);
fileReceiveButton = new Button(group2, SWT.NONE);
fileReceiveButton.setText("接收");
fileReceiveButton.setBounds(350, 60, 100, 25);
FileSendLabel = new Label(group2, SWT.NONE);
FileSendLabel.setText("输入要发送文件的路径:");
FileSendLabel.setBounds(15, 125, 145, 15);
fileWriteText = new Text(group2, SWT.BORDER);
fileWriteText.setBounds(160,125,300,20);
serialFileSendLabel = new Label(group2, SWT.NONE);
serialFileSendLabel.setText("输入串口后点击按钮开始发送文件:");
serialFileSendLabel.setBounds(15, 160, 190, 15);
sFPText = new Text(group2, SWT.BORDER);
sFPText.setBounds(215, 160, 120, 20);
fileSendButton = new Button(group2, SWT.NONE);
fileSendButton.setText("发送");
fileSendButton.setBounds(350, 160, 100, 25);
}
}
public Display getDisplay(){
return display;
}
public Shell getShell() {
return shell;
}
public String getComname(){
return sPText.getText();
}
public void setReadString(String _in) {
readText.setText(_in);
}
public Button getsendButton(){
return sendButton;
}
public Button getreveiceButton(){
return receiveButton;
}
public String getSendMessageString(){
return writeText.getText();
}
public String getSerialReceiveString(){
return rPText.getText();
}
public String getserialSendString(){
return sPText.getText();
}
public String getFileSerialReceiveString(){
return sFPText.getText();
}
public String getFileReceivePathString(){
return fileReadText.getText();
}
public String getFileSerialSendString(){
return rFPText.getText();
}
public String getFileSendPathStirng(){
return fileWriteText.getText();
}
public Button getFileReceiveButton(){
return fileReceiveButton;
}
public Button getFileSendButton(){
return fileSendButton;
}
}

串口读取类readClass:
package commpi;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;

import javax.comm.CommPortIdentifier;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;

public class readClass implements SerialPortEventListener, Runnable {
UIclass uIclass;
CommPortIdentifier portIdentifier;
Enumeration portList;
InputStream inputStream;
SerialPort serialPort;
Thread readThread;
String reveiceseraiString = "";
String dataString = "";
    byte[] readBuffer = new byte[200];
public readClass(UIclass in_uiclass){
uIclass = in_uiclass;
portList = CommPortIdentifier.getPortIdentifiers();
Button reveiveButton = uIclass.getreveiceButton();
reveiveButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event){
reveiceseraiString = uIclass.getSerialReceiveString();
while (portList.hasMoreElements()) {
portIdentifier = (CommPortIdentifier) portList.nextElement();
if (portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portIdentifier.getName().equals(reveiceseraiString)) {//从界面得到要读取的串口号
init();
readThread.start();//读取是跑在一个线程里的 它随时要准备从串口接收数据 当然向串口写数据就不需要这样了 在图书馆看到一本关于Java线程的书 我这菜鸟下次好好研究一下
}
}
}
}
});
}
public void init() {//串口的设置 抄simple code
try {
serialPort = (SerialPort) portIdentifier.open("SimpleReadApp", 2000);
} catch (PortInUseException e) {
e.printStackTrace();
}
try {
inputStream = serialPort.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
e.printStackTrace();
}
serialPort.notifyOnDataAvailable(true);
try {
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
}
readThread = new Thread(this);

}
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
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://这里是自己写的读取字符串
            try {
             int numBytes = 0;
             String tempString = "";
           
                while (inputStream.available() > 0) {
                    numBytes = inputStream.read(readBuffer);
                }
               
                tempString = new String(readBuffer);//这里要经过一个从byte[]到String的转化
                dataString += tempString.substring(0, numBytes);
                               
                uIclass.getDisplay().syncExec(new Runnable() {//SWT要向UI线程中写数据就要这样
public void run() {
uIclass.setReadString(dataString);
}
});

                System.out.print(dataString + "_" + numBytes);
            } catch (IOException e) {}
            break;
default:
break;
}
}
}

串口写入类writeClass:
package commpi;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;

import javax.comm.CommPortIdentifier;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.UnsupportedCommOperationException;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;

public class writeClass {
private UIclass uIclass;
private Enumeration portList;
private CommPortIdentifier portIdentifier;
private String messageString = "";
private SerialPort serialPort;
private OutputStream outputStream;
private String sendserialString = "";
public writeClass(UIclass _uIclass){
uIclass = _uIclass;
portList = CommPortIdentifier.getPortIdentifiers();
Button sendButton = uIclass.getsendButton();
sendButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event){
sendserialString = uIclass.getserialSendString();
init();//这些都是串口设置 全部抄simple code 下面是自己的
String sendString = uIclass.getSendMessageString();//获取要发送的字符串
try {
outputStream.write(sendString.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
private void init(){
while (portList.hasMoreElements()) {
portIdentifier = (CommPortIdentifier) portList.nextElement();
if (portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portIdentifier.getName().equals(sendserialString)) {//这里选择要发送的串口号 从界面中读取
try {
serialPort = (SerialPort) portIdentifier.open("SimpleWriteApp", 2000);
} catch (PortInUseException e) {
e.printStackTrace();
}
try {
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
}
}
}
}
}
}
首先,我的命名方法还是很乱的,我以后尽力写好。其实我写Java没多久,对于其基本结构还需要了解,这里的代码结构恶心是必然的了,不过,总之它跑起来了。哎,洗洗睡吧……
 
收来备用,谢谢原博主。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值