Python 串口调试工具设计与实现
相关资源文件已经打包成EXE文件,可双击直接运行程序,且文章末尾已附上相关源码,以供大家学习交流,博主主页还有更多Python相关程序案例,秉着开源精神的想法,望大家喜欢,点个关注不迷路!!!
1. 简介:
这是一个基于 Python编写的tkinter 和 pyserial 的串口调试工具。通过图形化界面(GUI),用户可以方便地进行串口通信的设置、数据发送与接收、文件传输等操作。程序提供了对串口参数的全面控制(如波特率、数据位、校验位等),并且支持对发送和接收数据的格式进行多种定制,如 Hex 格式显示、校验码(CRC-16、XOR)等。除此之外,工具还支持自动发送功能,用户可以根据需求设置数据发送的时间间隔,极大地提高了工作效率。
功能:
串口设置:
用户可以选择串口号、波特率、数据位、校验位、停止位和流控方式。
支持串口端口列表的动态更新。
数据发送:
可以手动输入文本数据,或者发送文件。
支持以 Hex 编码发送数据。
可以在数据末尾添加 CRC-16 或 XOR 校验码。
数据接收:
- 支持显示接收到的数据(可以选择以文本或 Hex 格式显示)。
- 支持接收时显示时间戳。
文件传输:
- 支持发送文件内容,并将其以二进制形式发送。
- 支持将接收到的数据保存到本地文件。
自动发送:
- 支持定时自动发送数据,发送间隔时间可以设置。
- 可根据设置的间隔自动循环发送数据。
颜色定制:
- 用户可以设置接收和发送数据的颜色。
扩展功能:
- 提供了“预置命令”和“自动答复”两个扩展功能选项卡,供高级用户自定义命令或响应。
状态栏:
- 显示当前串口连接状态。
- 显示接收和发送的数据计数。
串口控制:
- 可以打开或关闭串口连接。
- 在串口连接成功后,自动开始接收数据。
2. 运行效果:
3.总结
这款串口调试工具通过简洁的图形化界面和强大的功能,提供了一个全面的串口通信调试平台。用户可以方便地控制串口参数,进行数据的发送与接收,支持多种数据格式和校验方式,还能够将数据保存至文件。自动发送和扩展功能增加了工具的灵活性,可以满足更复杂的调试需求。整体而言,工具适用于硬件开发、嵌入式调试、协议分析等场景,对于串口通信的开发者和调试人员来说,是一个非常实用的工具。
4. 相关源码:
import serial
import serial.tools.list_ports
import tkinter as tk
from tkinter import ttk, messagebox, colorchooser, filedialog
from threading import Thread, Event
import time
import binascii
from datetime import datetime
class SerialDebugger:
def __init__(self, master):
self.master = master
self.serial_port = None
self.receive_flag = Event()
self.auto_send_flag = False
self.rx_counter = 0
self.tx_counter = 0
self.recv_color = '#FF0000' # 默认接收颜色红色
self.send_color = '#0000FF' # 默认发送颜色蓝色
self.extension_visible = False # 扩展窗口可见状态
# 获取默认Checkbutton背景颜色
temp = tk.Checkbutton(master)
self.default_bg = temp.cget('bg')
temp.destroy()
# 初始化ttk样式
self.style = ttk.Style()
self.style.configure('Yellow.TCombobox', fieldbackground='yellow')
# 初始化界面
self.setup_ui()
self.setup_extension_window()
self.update_ports()
# 绑定事件
self.port_combo.bind("<<ComboboxSelected>>", self.on_port_change)
def setup_ui(self):
"""初始化主界面布局"""
self.master.geometry("990x700")
self.master.title("串口调试工具")
self.master.minsize(650, 450)
# 配置主窗口网格布局
self.master.grid_columnconfigure(0, weight=1)
self.master.grid_columnconfigure(1, weight=0, minsize=0) # 扩展窗口列
self.master.grid_rowconfigure(0, weight=1) # 数据显示区
self.master.grid_rowconfigure(1, weight=0) # 控制区
self.master.grid_rowconfigure(2, weight=0) # 状态栏
# ========== 数据显示区 ==========
display_frame = ttk.Frame(self.master)
display_frame.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
self.text_display = tk.Text(display_frame, state=tk.DISABLED, wrap=tk.WORD)
scroll_display = ttk.Scrollbar(display_frame, orient="vertical", command=self.text_display.yview)
self.text_display.configure(yscrollcommand=scroll_display.set)
self.text_display.grid(row=0, column=0, sticky="nsew")
scroll_display.grid(row=0, column=1, sticky="ns")
display_frame.grid_columnconfigure(0, weight=1)
display_frame.grid_rowconfigure(0, weight=1)
# ========== 中间控制区 ==========
control_frame = ttk.Frame(self.master)
control_frame.grid(row=1, column=0, columnspan=2, sticky="nsew", padx=5, pady=2)
control_frame.grid_columnconfigure(0, minsize=200, weight=0)
control_frame.grid_columnconfigure(1, weight=1)
control_frame.grid_columnconfigure(2, minsize=250, weight=0)
control_frame.grid_rowconfigure(0, minsize=155, weight=0)
# 串口设置区
self.setup_serial_controls(control_frame)
# 发送输入区
self.setup_send_controls(control_frame)
# 功能区
self.setup_function_controls(control_frame)
# ========== 状态栏 ==========
self.setup_status_bar()
def setup_extension_window(self):
"""初始化扩展窗口"""
self.extension_frame = ttk.Frame(self.master, width=425)
self.extension_frame.grid(row=0, column=1, sticky="nsew")
self.extension_frame.grid_remove()
# 创建Notebook
self.notebook = ttk.Notebook(self.extension_frame)
self.notebook.pack(expand=True, fill='both')
# 预置命令标签页
self.preset_frame = ttk.Frame(self.notebook)
self.notebook.add(self.preset_frame, text="预置命令")
# 自动答复标签页
self.auto_reply_frame = ttk.Frame(self.notebook)
self.notebook.add(self.auto_reply_frame, text="自动答复")
# 设置固定宽度
self.extension_frame.grid_propagate(False)
self.extension_frame.config(width=425)
def toggle_extension(self):
"""切换扩展窗口显示状态"""
self.extension_visible = not self.extension_visible
if self.extension_visible:
self.extension_frame.grid()
self.master.grid_columnconfigure(1, minsize=425, weight=0)
else:
self.extension_frame.grid_remove()
self.master.grid_columnconfigure(1, weight=0, minsize=0)
def setup_status_bar(self):
"""初始化底部状态栏"""
status_bar = ttk.Frame(self.master, height=22)
status_bar.grid(row=2, column=0, columnspan=2, sticky="sew")
self.status_conn = ttk.Label(status_bar, text="未连接", anchor=tk.W)
self.status_rx = ttk.Label(status_bar, text