树莓派3使用JAVA实现串口通讯

在这里插入图片描述

1、配置树莓派:

(1)sudo raspi-config
(2)选择 Interfacing Options,然后选择Serial,关闭串口shell终端,使能串口。
(3)修改配置文件

sudo nano /boot/config.txt

追加如下内容

dtoverlay=pi3-miniuart-bt
enable_uart=1

2、配置Java串口环境

(1)获取系统版本信息

uname -r

(2)将获取到的系统版本信息写入配置文件/usr/include/linux/version.h

#define UTS_RELEASE "4.14.34-v7+" //引号内容根据实际情概况修改

(3)下载相关程序包【网页链接:http://rxtx.qbang.org/wiki/index.php/Download

wget http://rxtx.qbang.org/pub/rxtx/rxtx-2.2pre2.zip

unzip rxtx-2.2pre2.zip

cd rxtx-2.2pre2

(4)JDK1.6及以上的运行环境下,需要对configure文件进行修改。

 在configure文件中找到所有的 1.2*|1.3*|1.4*|1.5* , 将现有的JDK版本加入进去即可.如:改成 1.2*|1.3*|1.4*|1.5*|1.6*|1.7*|1.8*

sh ./configure

make

make install

(5)安装成功后,会显示如下信息

Libraries have been installed in:
/cloud/jdk/jre/lib/arm
...................
/usr/bin/install -c RXTXcomm.jar /cloud/jdk/jre/lib/ext/

3、编写java代码

示例代码如下

/**
 * 串口通讯
 */
public class SerialPortManager
{
    private static final SerialPortManager SERIAL_PORT_MANAGER = new SerialPortManager();
    private SerialPort serialPort;
    private InputStream inputStream;
    private OutputStream outputStream;

    public static SerialPortManager getInstance()
    {
        return SERIAL_PORT_MANAGER;
    }

    public void init()
    {
        if (openPort())//打开串口
        {
            addListener();//添加监听器
            return;
        }
        Device.isConnect = false;
        try
        {
            Thread.sleep(2000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        //刷新参数
        new ParameterManager(false).run();
    }

    /**
     * 从串口读取数据
     */
    private void readPortData(DataLinkParserUtil parserUtil)
    {
        if (!Device.isConnect)
        {
            return;
        }
        try
        {
            if (serialPort == null)
            {
                System.out.println("Serial-串口对象为空,监听失败!");
                init();
                return;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            init();
            return;
        }
        byte[] readBuffer = new byte[4096];
        try
        {
            parserUtil.unpackData(inputStream.read(readBuffer), readBuffer);
        }
        catch (IOException ignored)
        {
            System.out.println("inputStream.read(readBuffer):ERROR!");
            init();
        }
    }

    /**
     * 给串口添加监听器
     */
    private void addListener()
    {
        try
        {
            inputStream = serialPort.getInputStream();
            outputStream = serialPort.getOutputStream();
            Device.isConnect = true;
            final DataLinkParserUtil parserUtil = new DataLinkParserUtil();
            serialPort.addEventListener(new SerialPortListener(() -> readPortData(parserUtil)));
            // 设置当有数据到达时唤醒监听接收线程
            serialPort.notifyOnDataAvailable(true);
            // 设置当通信中断时唤醒中断线程
            serialPort.notifyOnBreakInterrupt(true);
            new Thread(this::sendPortData).start();//发送串口数据
            new Thread(this::getSn).start();//发送获取飞控编号请求
        }
        catch (TooManyListenersException | IOException e)
        {
            e.printStackTrace();
            Device.isConnect = false;
            init();
        }
    }

    /**
     * 发送串口数据
     */
    private void sendPortData()
    {
        while (Device.isConnect && outputStream != null)
        {
            if (Device.sendCommandQueue.isEmpty())
            {
                continue;
            }
            Packet packet = null;
            try
            {
                packet = Device.sendCommandQueue.take();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            if (packet == null)
            {
                continue;
            }
            try
            {
                outputStream.write(packet.encodePacket());
                outputStream.flush();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

    /**
     * 打开串口
     */
    private boolean openPort()
    {
        closePort();
        try
        {
            if (Parameter.isLinux)
            { //RXTX只支持ttyS开头的设备,而我们要跟串口通讯用的是 ttyAMA0,所以在此之前还要做一下映射
                Util.exeShellCommand("sudo ln -s /dev/ttyAMA0 /dev/ttyS4502");
            }
            System.out.println("打开串口:PORT=" + Parameter.PORT + ",RATE=" + Parameter.RATE);
            serialPort = openPort(Parameter.PORT, Parameter.RATE);
            if (serialPort != null)
            {
                System.out.println("Serial-串口已打开!");
                return true;
            }
        }
        catch (PortInUseException e)
        {
            System.out.println("Serial-串口已被占用!");
            e.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * 打开串口
     *
     * @param portName 端口名称
     * @param rate     波特率
     * @return 串口对象
     * @throws PortInUseException 串口已被占用
     */
    private SerialPort openPort(String portName, int rate) throws PortInUseException
    {
        try
        {
            // 通过端口名识别端口
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
            // 打开端口,并给端口名字和一个timeout(打开操作的超时时间)
            CommPort commPort = portIdentifier.open(portName, 2000);
            // 判断是不是串口
            if (!(commPort instanceof SerialPort))
            {
                System.out.println("Serial-" + portName + "不是串口");
                return null;
            }
            SerialPort serialPort = (SerialPort) commPort;
            try
            {
                // 设置一下串口的波特率等参数
                // 数据位:8
                // 停止位:1
                // 校验位:None
                serialPort.setSerialPortParams(rate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                return serialPort;
            }
            catch (UnsupportedCommOperationException e)
            {
                e.printStackTrace();
                return null;
            }
        }
        catch (NoSuchPortException e1)
        {
            e1.printStackTrace();
            System.out.println("Serial-没有这个端口");
            return null;
        }
    }

    /**
     * 关闭串口
     */
    public void closePort()
    {
        System.out.println("Serial-关闭串口中...");
        Device.isConnect = false;
        if (serialPort != null)
        {
            serialPort.removeEventListener();
            serialPort.close();
            serialPort = null;
        }
        if (inputStream != null)
        {
            try
            {
                inputStream.close();
                inputStream = null;
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        if (outputStream != null)
        {
            try
            {
                outputStream.close();
                outputStream = null;
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        System.out.println("Serial-串口已关闭");
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章