最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA設(shè)備對(duì)接與串口通信詳解

 更新時(shí)間:2025年07月15日 16:42:07   作者:秋分的秋刀魚  
作者為項(xiàng)目對(duì)接串口設(shè)備,系統(tǒng)學(xué)習(xí)串口通信原理與編程,通過(guò)代碼示例實(shí)踐實(shí)現(xiàn)通信功能,總結(jié)其在數(shù)據(jù)傳輸穩(wěn)定性、系統(tǒng)設(shè)計(jì)靈活性等方面的重要價(jià)值

一、背景

近期,我的項(xiàng)目需要對(duì)接各種設(shè)備,其中有幾臺(tái)設(shè)備采用了串口通信方式。由于之前對(duì)串口通信方式接觸不多,深感自己在這方面知識(shí)的欠缺,于是我決定對(duì)串口通信進(jìn)行深入的研究和開發(fā)。

我仔細(xì)學(xué)習(xí)了串口通信的原理、協(xié)議以及相關(guān)的編程技術(shù),并通過(guò)實(shí)踐不斷加深對(duì)串口通信的理解。

在這個(gè)過(guò)程中,我遇到了不少挑戰(zhàn),但通過(guò)不斷的學(xué)習(xí)和實(shí)踐,最終成功實(shí)現(xiàn)了與設(shè)備的串口通信?,F(xiàn)在,我將自己的學(xué)習(xí)和開發(fā)經(jīng)驗(yàn)記錄下來(lái),形成這篇博文,希望能夠?yàn)橛行枰耐瑢W(xué)提供一些幫助和指導(dǎo)。

二、串口通信技術(shù)介紹

串口是串行接口(serial port)的簡(jiǎn)稱,也稱為串行通信接口或COM接口。

串口通信是指采用串行通信協(xié)議(serial communication)在一條信號(hào)線上將數(shù)據(jù)一個(gè)比特一個(gè)比特地逐位進(jìn)行傳輸?shù)耐ㄐ拍J健?/p>

  • 串口通信是一種利用串行通信協(xié)議,在計(jì)算機(jī)與外部設(shè)備之間進(jìn)行異步通信的技術(shù)。串行通信按照時(shí)間順序,按位依次發(fā)送通信字節(jié),相較于并行通信,它僅需較少的數(shù)據(jù)線,通常兩根線即可實(shí)現(xiàn)雙向通信。在串行通信中,并行數(shù)據(jù)被轉(zhuǎn)換為串行數(shù)據(jù)后,通過(guò)傳輸線路依次傳輸。
  • 異步通信則是發(fā)送端和接收端通過(guò)起始位、停止位來(lái)同步數(shù)據(jù)塊的方式。發(fā)送端在發(fā)送數(shù)據(jù)字節(jié)前,會(huì)先發(fā)送一個(gè)起始位,然后依次發(fā)送數(shù)據(jù)字節(jié)的每個(gè)位,最后發(fā)送一個(gè)或多個(gè)停止位。接收端通過(guò)檢測(cè)起始位的狀態(tài)轉(zhuǎn)變來(lái)同步接收數(shù)據(jù),一旦檢測(cè)到起始位,便會(huì)根據(jù)事先約定的規(guī)則接收之后的數(shù)據(jù)位和停止位。

三、代碼示例

3.1 創(chuàng)建串口監(jiān)聽器

// 串口監(jiān)聽器
@Slf4j
public class MyLister implements SerialPortEventListener {

    //private static final Logger log = LoggerFactory.getLogger(MyLister.class);

    @Override
    public void serialEvent(SerialPortEvent event) {
        switch (event.getEventType()) {
            // 串口存在有效數(shù)據(jù)
            case SerialPortEvent.DATA_AVAILABLE:
                byte[] bytes = SerialPortUtil.getSerialPortUtil().readFromPort(PortInit.serialPort);
                log.info("===========start===========");
                String str = new String(bytes, StandardCharsets.UTF_8);
                log.info("{}【讀到的字符】:-----{}", LocalDateTime.now(), str);
                log.info("{}【字節(jié)數(shù)組轉(zhuǎn)16進(jìn)制字符串】:-----{}", LocalDateTime.now(), stringToHex(str));
                log.info("===========end===========");
                break;
            // 2.輸出緩沖區(qū)已清空
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
                log.error("輸出緩沖區(qū)已清空");
                break;
            // 3.清除待發(fā)送數(shù)據(jù)
            case SerialPortEvent.CTS:
                log.error("清除待發(fā)送數(shù)據(jù)");
                break;
            // 4.待發(fā)送數(shù)據(jù)準(zhǔn)備好了
            case SerialPortEvent.DSR:
                log.error("待發(fā)送數(shù)據(jù)準(zhǔn)備好了");
                break;
            // 10.通訊中斷
            case SerialPortEvent.BI:
                log.error("與串口設(shè)備通訊中斷");
                break;
            default:
                break;
        }
    }

    public static String stringToHex(String input) {
        byte[] bytes = input.getBytes(StandardCharsets.UTF_8);
        StringBuilder hexString = new StringBuilder();

        for (byte b : bytes) {
            String hex = Integer.toHexString(0xFF & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    /**
     * ASCII碼轉(zhuǎn)字節(jié)數(shù)組
     */
    public static byte[] asciiToIntArray(List<Integer> asciiValues) {
        byte[] byteArray = new byte[asciiValues.size()];
        for (int i = 0; i < asciiValues.size(); i++) {
            int asciiValue = asciiValues.get(i);
            byteArray[i] = (byte) asciiValue;
        }
        return byteArray;
    }

    /**
     * 字符串轉(zhuǎn)ASCII碼
     */
    public static List<Integer> stringToAscii(String input) {
        List<Integer> asciiValues = new ArrayList<>();
        for (char c : input.toCharArray()) {
            asciiValues.add((int) c);
        }
        return asciiValues;
    }


    /**
     * 16進(jìn)制字符串轉(zhuǎn)字節(jié)數(shù)組
     *
     * @param hex 16進(jìn)制字符串
     * @return 字節(jié)數(shù)組
     */
    public static byte[] hex2byte(String hex) {
        if (!isHexString(hex)) {
            return null;
        }
        char[] arr = hex.toCharArray();
        byte[] b = new byte[hex.length() / 2];
        for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
            String swap = "" + arr[i++] + arr[i];
            int byteint = Integer.parseInt(swap, 16) & 0xFF;
            b[j] = new Integer(byteint).byteValue();
        }
        return b;
    }

    /**
     * 校驗(yàn)是否是16進(jìn)制字符串
     *
     * @param hex
     * @return
     */
    public static boolean isHexString(String hex) {
        if (hex == null || hex.length() % 2 != 0) {
            return false;
        }
        for (int i = 0; i < hex.length(); i++) {
            char c = hex.charAt(i);
            if (!isHexChar(c)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 校驗(yàn)是否是16進(jìn)制字符
     *
     * @param c
     * @return
     */
    private static boolean isHexChar(char c) {
        return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
    }

}

3.2 串口初始化

/**
 * 串口初始化
 */
@Component
@Slf4j
public class PortInit implements ApplicationRunner {
    public static SerialPort serialPort = null;

    @Override
    public void run(ApplicationArguments args) {
        String portName = "COM1";
        //查看所有串口
        SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();
        ArrayList<String> port = serialPortUtil.findPort();
        log.info("發(fā)現(xiàn)全部串口:{}", port);
        log.info("打開指定portName:{}", portName);
        //打開該對(duì)應(yīng)portName名字的串口
        PortInit.serialPort = serialPortUtil.openPort(
                portName,
                9600,
                SerialPort.DATABITS_8,
                SerialPort.PARITY_NONE,
                SerialPort.PARITY_ODD);
        //給對(duì)應(yīng)的serialPort添加監(jiān)聽器
        serialPortUtil.addListener(PortInit.serialPort, new MyLister());
    }

}

3.3 啟動(dòng)類

@SpringBootApplication
public class SerialPortProjectApplication {

    public static void main(String[] args) {
        SpringApplication.run(SerialPortProjectApplication.class, args);
    }

    @PreDestroy
    public void destroy() {
        //關(guān)閉應(yīng)用前 關(guān)閉端口
        SerialPortUtil serialPortUtil = SerialPortUtil.getSerialPortUtil();
        serialPortUtil.removeListener(PortInit.serialPort);
        serialPortUtil.closePort(PortInit.serialPort);
    }
}

3.4 pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.xsd</groupId>
    <artifactId>SerialPortProject</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SerialPortProject</name>
    <description>SerialPortProject</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>com.baomidou</groupId>-->
<!--            <artifactId>mybatis-plus-boot-starter</artifactId>-->
<!--            <version>3.5.2</version>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>mysql</groupId>-->
<!--            <artifactId>mysql-connector-java</artifactId>-->
<!--            <scope>runtime</scope>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.security</groupId>-->
<!--            <artifactId>spring-security-test</artifactId>-->
<!--            <scope>test</scope>-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.1-jre</version>
        </dependency>
        <!--    PropertyUtils工具類    -->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.4</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.9</version>
        </dependency>
        <!--   jwt依賴    -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.11.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.11.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.11.5</version>
            <scope>runtime</scope>
        </dependency>
        <!-- 串口內(nèi)容讀取 -->
        <dependency>
            <groupId>org.bidib.jbidib.org.qbang.rxtx</groupId>
            <artifactId>rxtxcomm</artifactId>
            <version>2.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3.5 發(fā)送的Job

@Component
@EnableScheduling
public class SendJob {

    /**
     * 定時(shí)發(fā)送數(shù)據(jù)
     * initialDelay :系統(tǒng)啟動(dòng)后,3秒后開始運(yùn)行此方法
     * fixedDelay:表示此方法運(yùn)行結(jié)束后,過(guò)1秒再次運(yùn)行此方法
     */
    @Scheduled(initialDelay = 1000 * 3, fixedDelay = 1000)
    public void plcAnalytic() {
        String s = "4040000900手動(dòng)滑稽阿薩德和靜安寺060004000000100172323";
        SerialPortUtil.getSerialPortUtil().sendToPort(PortInit.serialPort, MyLister.asciiToIntArray(MyLister.stringToAscii(s)));
    }
}

3.6 模擬窗口發(fā)布的軟件

四、總結(jié)

串口通信因其簡(jiǎn)單性、靈活性和通用性,在眾多應(yīng)用場(chǎng)景中仍然保持著極高的實(shí)用價(jià)值。

深入理解串口的工作原理,掌握串口通信接口的選擇與編程技巧,對(duì)于更好地應(yīng)用串口技術(shù)、設(shè)計(jì)出更為可靠的通信系統(tǒng)具有重要意義。

這不僅能夠幫助我們充分發(fā)揮串口通信的優(yōu)勢(shì),還能在不同應(yīng)用場(chǎng)景中靈活應(yīng)對(duì)各種通信需求,確保數(shù)據(jù)傳輸?shù)姆€(wěn)定性和準(zhǔn)確性。因此,深入學(xué)習(xí)和掌握串口通信的相關(guān)知識(shí),是提升通信系統(tǒng)設(shè)計(jì)能力、實(shí)現(xiàn)高效數(shù)據(jù)傳輸?shù)年P(guān)鍵所在。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

锡林郭勒盟| 临汾市| 康平县| 卫辉市| 宿迁市| 绥棱县| 定襄县| 深水埗区| 遵义县| 安康市| 葵青区| 滦平县| 全椒县| 铜梁县| 景泰县| 本溪| 安西县| 年辖:市辖区| 罗城| 荔浦县| 蒙自县| 商城县| 仁怀市| 广州市| 肃北| 金塔县| 芦山县| 军事| 奉化市| 秭归县| 定陶县| 南京市| 宁德市| 江津市| 始兴县| 安吉县| 镇康县| 微山县| 梨树县| 嵊州市| 攀枝花市|