import serial
import serial.tools.list_ports
import threading
import tkinter as tk
from tkinter import ttk, messagebox
class SerialDebugger:
def __init__(self, port, baudrate=9600, timeout=1):
self.port = port
self.baudrate = baudrate
self.timeout = timeout
self.serial_port = None
self.running = False
def open_port(self):
try:
self.serial_port = serial.Serial(self.port, self.baudrate, timeout=self.timeout)
print(f"串口 {self.port} 打开成功。")
return True
except serial.SerialException as e:
print(f"无法打开串口 {self.port}: {e}")
return False
def close_port(self):
if self.serial_port and self.serial_port.is_open:
self.serial_port.close()
print(f"串口 {self.port} 关闭。")
return True
return False
def read_data(self, text_widget):
while self.running:
if self.serial_port and self.serial_port.is_open:
data = self.serial_port.readline().decode('utf-8').strip()
if data:
text_widget.insert(tk.END, f"接收: {data}\n")
text_widget.see(tk.END)
def write_data(self, data):
if self.serial_port and self.serial_port.is_open:
self.serial_port.write((data + '\n').encode('utf-8'))
print(f"发送: {data}")
return True
else:
return False
def start(self, text_widget):
if self.open_port():
self.running = True
self.read_thread = threading.Thread(target=self.read_data, args=(text_widget,))
self.read_thread.start()
return True
return False
def stop(self):
self.running = False
self.read_thread.join()
self.close_port()
class SerialDebuggerApp:
def __init__(self, root):
self.root = root
self.root.title("串口调试工具")
self.port_label = ttk.Label(root, text="串口:")
self.port_label.grid(row=0, column=0, padx=10, pady=10)
self.port_combobox = ttk.Combobox(root)
self.port_combobox.grid(row=0, column=1, padx=10, pady=10)
self.update_ports()
self.baudrate_label = ttk.Label(root, text="波特率:")
self.baudrate_label.grid(row=1, column=0, padx=10, pady=10)
self.baudrate_combobox = ttk.Combobox(root)
self.baudrate_combobox['values'] = [9600, 19200, 38400, 57600, 115200]
self.baudrate_combobox.current(0)
self.baudrate_combobox.grid(row=1, column=1, padx=10, pady=10)
self.open_button = ttk.Button(root, text="打开串口", command=self.open_serial_port)
self.open_button.grid(row=2, column=0, padx=10, pady=10)
self.close_button = ttk.Button(root, text="关闭串口", command=self.close_serial_port)
self.close_button.grid(row=2, column=1, padx=10, pady=10)
self.send_label = ttk.Label(root, text="发送数据:")
self.send_label.grid(row=3, column=0, padx=10, pady=10)
self.send_entry = ttk.Entry(root)
self.send_entry.grid(row=3, column=1, padx=10, pady=10)
self.send_button = ttk.Button(root, text="发送", command=self.send_data)
self.send_button.grid(row=3, column=2, padx=10, pady=10)
self.text_widget = tk.Text(root, height=10, width=50)
self.text_widget.grid(row=4, column=0, columnspan=3, padx=10, pady=10)
self.debugger = None
def update_ports(self):
ports = [port.device for port in serial.tools.list_ports.comports()]
self.port_combobox['values'] = ports
if ports:
self.port_combobox.current(0)
def open_serial_port(self):
port = self.port_combobox.get()
baudrate = int(self.baudrate_combobox.get())
self.debugger = SerialDebugger(port, baudrate)
if self.debugger.start(self.text_widget):
self.text_widget.insert(tk.END, f"串口 {port} 打开成功。\n")
self.text_widget.see(tk.END)
else:
messagebox.showerror("错误", f"无法打开串口 {port}")
def close_serial_port(self):
if self.debugger:
self.debugger.stop()
self.text_widget.insert(tk.END, f"串口 {self.debugger.port} 关闭。\n")
self.text_widget.see(tk.END)
def send_data(self):
data = self.send_entry.get()
if self.debugger:
if self.debugger.write_data(data):
self.text_widget.insert(tk.END, f"发送: {data}\n")
self.text_widget.see(tk.END)
else:
messagebox.showerror("错误", "发送失败:串口未打开")
else:
messagebox.showerror("错误", "发送失败:串口未打开")
if __name__ == "__main__":
root = tk.Tk()
app = SerialDebuggerApp(root)
root.mainloop()
一个python串口调试工具
于 2024-08-15 18:42:54 首次发布