java 实现串口通讯

1、引入依赖

xml 复制代码
<dependency>
	<groupId>org.scream3r</groupId>
	<artifactId>jssc</artifactId>
	<version>2.8.0</version>
</dependency>

2、配置启动串口

java 复制代码
@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);
    }

}
java 复制代码
@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);
    }
}
java 复制代码
/**
 * @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;
        }
    }
}

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 发送消息

接收消息

相关推荐
芒果披萨12 分钟前
El表达式和JSTL
java·el
q5673152313 分钟前
在 Bash 中获取 Python 模块变量列
开发语言·python·bash
许野平38 分钟前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
也无晴也无风雨41 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
狂奔solar1 小时前
yelp数据集上识别潜在的热门商家
开发语言·python
duration~1 小时前
Maven随笔
java·maven
zmgst1 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
跃ZHD1 小时前
前后端分离,Jackson,Long精度丢失
java
blammmp1 小时前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧2 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++