• java 实现串口通讯


    1、引入依赖

    <dependency>
    	<groupId>org.scream3rgroupId>
    	<artifactId>jsscartifactId>
    	<version>2.8.0version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、配置启动串口

    @Component
    public class ContextHolder implements ApplicationContextAware{
    	
    	private static ApplicationContext applicationContext = null;
    	
    	@Override
    	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
    		if(ContextHolder.applicationContext == null){
    			ContextHolder.applicationContext  = arg0;
    	    }
    		System.out.println("========ApplicationContext配置成功,ContextHolder.getAppContext()获取applicationContext对象,applicationContext="+ ContextHolder.applicationContext+"========");
    	}
    	
    	//获取applicationContext
        public static ApplicationContext getApplicationContext() {
           return applicationContext;
        }
        //通过name获取 Bean.
        public static Object getBean(String name){
           return getApplicationContext().getBean(name);
        }
        //通过class获取Bean.
        public static <T> T getBean(Class<T> clazz){
           return getApplicationContext().getBean(clazz);
        }
        //通过name,以及Clazz返回指定的Bean
        public static <T> T getBean(String name,Class<T> clazz){
           return getApplicationContext().getBean(name, clazz);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    @Slf4j
    @Component
    public class SerialPortCanContext{
        //串口映射
        public static Map<String, SerialPort> serialPortMap = new ConcurrentHashMap<>();
    
    
        @PostConstruct
        public void initSerialPort() throws Exception{
            String portName = "COM2";
            startSerialPort(portName);
        }
        /**
         * 初始化串口
         * @param portName
         */
        public synchronized void startSerialPort(String portName){
            //如果有之前的串口就关闭
            SerialPort serialPort1 = serialPortMap.get(portName);
            if (serialPort1 != null){
                try {
                    serialPort1.removeEventListener();
                    serialPort1.closePort();
                } catch (SerialPortException e) {
                    log.error(e.getMessage());
                }
            }
            //生成新的串口并打开
            SerialPort serialPort = new SerialPort(portName);
            try {
                serialPort.openPort();
                serialPort.setParams(SerialPort.BAUDRATE_256000,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_EVEN);
                serialPort.addEventListener(new HhdSerialPortListener());
            } catch (SerialPortException e) {
                log.error(e.getMessage());
            }
            serialPortMap.put(portName,serialPort);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    /**
     * @author fangyuan
     * @description 串口监听器
     * @date 2023年11月7日09:08:43
     **/
    public class SerialPortListener implements SerialPortEventListener {
        private static Logger logger= LoggerFactory.getLogger(HhdSerialPortListener.class);
        private SerialPortCanContext serialPortCanContext;
        public SerialPortListener() {
            this.serialPortCanContext = ContextHolder.getBean(SerialPortCanContext.class);
        }
    
        @Override
        public void serialEvent(SerialPortEvent serialPortEvent) {
            String portName = serialPortEvent.getPortName();
            if (StringUtils.isBlank(portName)){
                return;
            }
            //通过缓存拿到串口 没有就生成一下
            SerialPort serialPort = SerialPortCanContext.serialPortMap.get(portName);
            if (serialPort == null){
                serialPortCanContext.startSerialPort(portName);
            }
            try {
                String body = serialPort.readString();
                if (StringUtils.isBlank(body)){
                    return;
                }
                logger.info("SerialPort : {}  received : {}",portName,body);
                int size = body.length() / 2;
                ByteBuf buf = Unpooled.buffer(size);
                buf.writeBytes(hexToBytes(body));
                //todo 再将buf数据进行后续处理
            } catch (SerialPortException e) {
                logger.error(e.getMessage());
            }
        }
    
    
    
        /**
         * 将16进制字符串转换为byte[]
         * @param hexStr
         * @return
         */
        public static byte[] hexToBytes(String hexStr) {
            int len = hexStr.length();
            hexStr = hexStr.toUpperCase();
            byte[] des;
            if (len % 2 != 0 || len == 0) {
                return null;
            } else {
                int halfLen = len / 2;
                des = new byte[halfLen];
                char[] tempChars = hexStr.toCharArray();
                for (int i = 0; i < halfLen; ++i) {
                    char c1 = tempChars[i * 2];
                    char c2 = tempChars[i * 2 + 1];
                    int tempI = 0;
                    if (c1 >= '0' && c1 <= '9') {
                        tempI += ((c1 - '0') << 4);
                    } else if (c1 >= 'A' && c1 <= 'F') {
                        tempI += (c1 - 'A' + 10) << 4;
                    } else {
                        return null;
                    }
                    if (c2 >= '0' && c2 <= '9') {
                        tempI += (c2 - '0');
                    } else if (c2 >= 'A' && c2 <= 'F') {
                        tempI += (c2 - 'A' + 10);
                    } else {
                        return null;
                    }
                    des[i] = (byte) tempI;
                    // system.out.println(des[i]);
                }
                return des;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    3、 模拟串口发送消息

    3、1 安装 Configure Virtual Serial Port Driver

    链接:https://pan.baidu.com/s/1fQ76Fh07kzqPeKho9nb7CA?pwd=6533
    提取码:6533
    解压后安装,将安装后的 这两个文件复制到安装目录并覆盖之前的文件
    在这里插入图片描述

    在这里插入图片描述

    增加映射串口
    在这里插入图片描述
    打开 我点电脑----> 右键属性 -------> 设备管理 --------->端口查看
    有数据表示串口映射成功
    在这里插入图片描述

    3、2 安装打开 sscom

    链接:https://pan.baidu.com/s/13csdZ5XEkZ-E9r5XRYXWVA?pwd=6533
    提取码:6533

    在这里插入图片描述

    3、3 发送消息

    在这里插入图片描述

    接收消息
    在这里插入图片描述

  • 相关阅读:
    什么是 mapState 助手?
    深入探索时间复杂度:解锁算法性能的关键
    [LeetCode周赛复盘] 第 322 场周赛20221204
    如何用思维导图做备考计划
    IDEA阿里云OSS实现文件上传·解决苍穹外卖图片回显
    一文搞懂Linux内存映射实现(二)
    入站两周增长1200w播放!B站新人UP主竟能爆款频出
    优化算法 - Adadelta
    Mybatis,自定义Mybatis拦截器与Plugin
    Python+selenium,轻松搭建Web自动化测试框架
  • 原文地址:https://blog.csdn.net/weixin_47752736/article/details/134397588