在项目开发中需要用到串口进行通讯,但当有其他串口调试工具、串口助手等打开占用了某一端口,打开串口时会导致程序卡死,针对这一问题的出现及解决过程进行记录。
图形界面开发:PySide2
串口操作:serial
# 串口打开函数
def f_openCom(self, port, baudrate=9600, bytesize="8", stopbits="1", parity="N"):
"""
function: 串口打开函数
in: port:串口名
baud:波特率
data:数据位
stop:停止位
parity:校验位
out: None
return: true:opened ; false,closed
others: open serial function
"""
if self.serial.isOpen(): # 如果串口已经打开
self.timer_send.stop() # 关闭计时器
self.f_closeCom() # 关闭串口
return self.serial.isOpen() # 返回False
else: # 如果串口未打开
# self.__m_Lock.acquire()
self.__f_initCOM(port, baudrate, bytesize, stopbits, parity) # 配置串口
self.serial.timeout = 0.5 # 设置读超时时间为0.5s
self.serial.open() # 打开串口
# self.__m_Lock.release()
self.__m_thread_read = threading.Thread(target=self.f_comRead, args=(0.1,)) # 定义串口读取线程
self.__m_thread_read.setDaemon(True) # 设置该线程为守护线程,表示该线程是不重要的,进程退出时不需要等待这个线程执行完成。
self.__m_thread_read.start() # 线程开启
return self.serial.isOpen() # 返回True
大致实现的功能为:
但在使用过程中发现,如果串口被其他的工具,如串口助手等打开占用,通过 serial.isOpen() 方法获取的都为 False ,所以当串口被占用的情况下通过 serial 打开串口,会导致 UI 界面的卡死。
serial 没有提供相关的方法可以对被其他程序占用的端口状态进行访问,所以想通过 serial 库本身来解决该问题无法实现;
通过查阅资料,网上的方法是通过创建串口,然后去收集是否会抛出异常来判断串口是否被占用,如python:检测windows上某串口(COM口)是否存在和被占用
根据2中的方法,在串口打开时使用 try except 语句去捕获异常,并通过 PySide2 的 QMessageBox 弹出提示框即可提示用户串口被占用。
if self.ui.cbbSerial.currentText() != "":
try:
ir = self.rtu.f_openCom(self.ui.cbbSerial.currentText(),
self.ui.cbbBaud.currentText(),
self.ui.cbbData.currentText(),
self.ui.cbbStop.currentText(),
self.ui.cbbParity.currentText())
except Exception as e:
QMessageBox.critical(self.ui, "警告", f"{self.srl.port}被占用,拒绝访问!")