python实现串口通讯小程序(GUI界面)

待我称王封你为后i 2023-07-05 05:21 64阅读 0赞

python实现串口通讯小程序(GUI界面)

使用python实现串口通讯需要使用python的pyserial库来实现,这个库在安装python的时候没有自动进行安装,需要自己进行安装。
1、安装pyserial库:
打开命令行窗口,在命令行中输入:pip install pyserial 命令进行安装。
2、程序使用python自带的GUI库tkinter来实现GUI窗口,使用pyserial来实现串口通讯模块。
效果图如下:
在这里插入图片描述
串口号选择框会自动加载所有可用的串口号,并且显示在选择框中。在使用时选择合适的串口号,然后点击打开串口按键即可。
在这里插入图片描述

注:本程序使用的是虚拟串口

3、效果演示:
1)发送数据演示:
在这里插入图片描述
注:在发送数据显示框中显示字符,则表明发送成功
动态效果演示:
在这里插入图片描述
2)接收数据演示:
在这里插入图片描述
注:接收数据显示框显示字符,则表明发送数据成功
动态演示效果:
在这里插入图片描述
4:工程介绍:
本工程由两个文件组成:分别是GUI文件和串口文件。
文件代码如下:
GUI文件:

  1. ''' @ author: summer @ tools: pycharm @ content: 实现串口通讯主类 @ date: 2020.2.12 '''
  2. import tkinter
  3. from tkinter import ttk
  4. from 串口通讯.SerialClass import SerialAchieve # 导入串口通讯类
  5. class MainSerial:
  6. def __init__(self):
  7. # 定义串口变量
  8. self.port = None
  9. self.band = None
  10. self.check = None
  11. self.data = None
  12. self.stop = None
  13. self.myserial = None
  14. # 初始化窗体
  15. self.mainwin = tkinter.Tk()
  16. self.mainwin.title("串口调试工具")
  17. self.mainwin.geometry("600x400")
  18. # 标签
  19. self.label1 = tkinter.Label(self.mainwin,text = "串口号:",font = ("宋体",15))
  20. self.label1.place(x = 5,y = 5)
  21. self.label2 = tkinter.Label(self.mainwin, text="波特率:", font=("宋体", 15))
  22. self.label2.place(x=5, y=45)
  23. self.label3 = tkinter.Label(self.mainwin, text="校验位:", font=("宋体", 15))
  24. self.label3.place(x=5, y=85)
  25. self.label4 = tkinter.Label(self.mainwin, text="数据位:", font=("宋体", 15))
  26. self.label4.place(x=5, y=125)
  27. self.label5 = tkinter.Label(self.mainwin,text = "停止位:",font = ("宋体",15))
  28. self.label5.place(x = 5,y = 165)
  29. # 文本显示,清除发送数据
  30. self.label6 = tkinter.Label(self.mainwin, text="发送数据:", font=("宋体", 15))
  31. self.label6.place(x=230, y=5)
  32. self.label7 = tkinter.Label(self.mainwin, text="接收数据:", font=("宋体", 15))
  33. self.label7.place(x=230, y=200)
  34. # 串口号
  35. self.com1value = tkinter.StringVar() # 窗体中自带的文本,创建一个值
  36. self.combobox_port = ttk.Combobox(self.mainwin, textvariable=self.com1value,
  37. width = 10,font = ("宋体",13))
  38. # 输入选定内容
  39. self.combobox_port["value"] = [""] # 这里先选定
  40. self.combobox_port.place(x = 105,y = 5) # 显示
  41. # 波特率
  42. self.bandvalue = tkinter.StringVar() # 窗体中自带的文本,创建一个值
  43. self.combobox_band = ttk.Combobox(self.mainwin, textvariable=self.bandvalue, width=10, font=("宋体", 13))
  44. # 输入选定内容
  45. self.combobox_band["value"] = ["4800","9600","14400","19200","38400","57600","115200"] # 这里先选定
  46. self.combobox_band.current(6) # 默认选中第0个
  47. self.combobox_band.place(x=105, y=45) # 显示
  48. # 校验位
  49. self.checkvalue = tkinter.StringVar() # 窗体中自带的文本,创建一个值
  50. self.combobox_check = ttk.Combobox(self.mainwin, textvariable=self.checkvalue, width=10, font=("宋体", 13))
  51. # 输入选定内容
  52. self.combobox_check["value"] = ["无校验位"] # 这里先选定
  53. self.combobox_check.current(0) # 默认选中第0个
  54. self.combobox_check.place(x=105, y=85) # 显示
  55. # 数据位
  56. self.datavalue = tkinter.StringVar() # 窗体中自带的文本,创建一个值
  57. self.combobox_data = ttk.Combobox(self.mainwin, textvariable=self.datavalue, width=10, font=("宋体", 13) )
  58. # 输入选定内容
  59. self.combobox_data["value"] = ["8", "9", "0"] # 这里先选定
  60. self.combobox_data.current(0) # 默认选中第0个
  61. self.combobox_data.place(x=105, y=125) # 显示
  62. # 停止位
  63. self.stopvalue = tkinter.StringVar() # 窗体中自带的文本,创建一个值
  64. self.combobox_stop = ttk.Combobox(self.mainwin, textvariable=self.stopvalue, width=10, font=("宋体", 13))
  65. # 输入选定内容
  66. self.combobox_stop["value"] = ["1", "0"] # 这里先选定
  67. self.combobox_stop.current(0) # 默认选中第0个
  68. self.combobox_stop.place(x=105, y=165) # 显示
  69. # 按键显示,打开串口
  70. self.button_OK = tkinter.Button(self.mainwin, text="打开串口",
  71. command=self.button_OK_click, font = ("宋体",13),
  72. width = 10,height = 1)
  73. self.button_OK.place(x = 5,y = 210) # 显示控件
  74. # 关闭串口
  75. self.button_Cancel = tkinter.Button(self.mainwin, text="关闭串口", # 显示文本
  76. command=self.button_Cancel_click, font = ("宋体",13),
  77. width=10, height=1)
  78. self.button_Cancel.place(x = 120,y = 210) # 显示控件
  79. # 清除发送数据
  80. self.button_Cancel = tkinter.Button(self.mainwin, text="清除发送数据", # 显示文本
  81. command=self.button_clcSend_click, font=("宋体", 13),
  82. width=13, height=1)
  83. self.button_Cancel.place(x=400, y=2) # 显示控件
  84. # 清除接收数据
  85. self.button_Cancel = tkinter.Button(self.mainwin, text="清除接收数据", # 显示文本
  86. command=self.button_clcRece_click, font=("宋体", 13),
  87. width=13, height=1)
  88. self.button_Cancel.place(x=400, y=197) # 显示控件
  89. # 发送按键
  90. self.button_Send = tkinter.Button(self.mainwin, text="发送", # 显示文本
  91. command=self.button_Send_click, font=("宋体", 13),
  92. width=6, height=1)
  93. self.button_Send.place(x=5, y=255) # 显示控件
  94. # 接收按键
  95. self.button_Send = tkinter.Button(self.mainwin, text="接收", # 显示文本
  96. command=self.button_Rece_click, font=("宋体", 13),
  97. width=6, height=1)
  98. self.button_Send.place(x=5, y=310) # 显示控件
  99. # 显示框
  100. # 实现记事本的功能组件
  101. self.SendDataView = tkinter.Text(self.mainwin,width = 40,height = 9,
  102. font = ("宋体",13)) # text实际上是一个文本编辑器
  103. self.SendDataView.place(x = 230,y = 35) # 显示
  104. self.ReceDataView = tkinter.Text(self.mainwin, width=40, height=9,
  105. font=("宋体", 13)) # text实际上是一个文本编辑器
  106. self.ReceDataView.place(x=230, y=230) # 显示
  107. # 发送的内容
  108. test_str = tkinter.StringVar(value="Hello")
  109. self.entrySend = tkinter.Entry(self.mainwin, width=13,textvariable = test_str,font = ("宋体",15))
  110. self.entrySend.place(x = 80,y = 260) # 显示
  111. # 获取文件路径
  112. test_str = tkinter.StringVar(value="Hello")
  113. self.entrySend = tkinter.Entry(self.mainwin, width=13, textvariable=test_str, font=("宋体", 15))
  114. self.entrySend.place(x=80, y=260) # 显示
  115. # 获取界面的参数
  116. self.band = self.combobox_band.get()
  117. self.check = self.combobox_check.get()
  118. self.data = self.combobox_data.get()
  119. self.stop = self.combobox_stop.get()
  120. print("波特率:"+self.band)
  121. self.myserial = SerialAchieve(int(self.band),self.check,self.data,self.stop)
  122. # 处理串口值
  123. self.port_list = self.myserial.get_port()
  124. port_str_list = [] # 用来存储切割好的串口号
  125. for i in range(len(self.port_list)):
  126. # 将串口号切割出来
  127. lines = str(self.port_list[i])
  128. str_list = lines.split(" ")
  129. port_str_list.append(str_list[0])
  130. self.combobox_port["value"] = port_str_list
  131. self.combobox_port.current(0) # 默认选中第0个
  132. def show(self):
  133. self.mainwin.mainloop()
  134. def button_OK_click(self):
  135. ''' @ 串口打开函数 :return: '''
  136. if self.port == None or self.port.isOpen() == False:
  137. self.myserial.open_port(self.combobox_port.get())
  138. print("打开串口成功")
  139. else:
  140. pass
  141. def button_Cancel_click(self):
  142. self.myserial.delete_port()
  143. print("关闭串口成功")
  144. def button_clcSend_click(self):
  145. self.SendDataView.delete("1.0","end")
  146. def button_clcRece_click(self):
  147. self.ReceDataView.delete("1.0", "end")
  148. def button_Send_click(self):
  149. try:
  150. if self.myserial.port.isOpen() == True:
  151. print("开始发送数据")
  152. send_str1 = self.entrySend.get()
  153. self.myserial.Write_data(send_str1)
  154. self.SendDataView.insert(tkinter.INSERT, send_str1+" ")
  155. print("发送数据成功")
  156. else:
  157. print("串口没有打开")
  158. except:
  159. print("发送失败")
  160. def button_Rece_click(self):
  161. try:
  162. readstr = self.myserial.Read_data()
  163. self.ReceDataView.insert(tkinter.INSERT, readstr + " ")
  164. except:
  165. print("读取失败")
  166. if __name__ == '__main__':
  167. my_ser1 = MainSerial()
  168. my_ser1.show()

串口文件:

  1. ''' @ author: summer @ tools: pycharm @ content: 串口通讯实现类 @ date: 2020.2.12 '''
  2. import serial
  3. import serial.tools.list_ports
  4. class SerialAchieve:
  5. def __init__(self,band=115200,check="无校验位",data=8,stop=1):
  6. self.port = None
  7. # 获取可用串口
  8. self.port_list = list(serial.tools.list_ports.comports())
  9. assert (len(self.port_list) != 0),"无可用串口"
  10. self.bandRate = band
  11. self.checkbit = check
  12. self.databit = data
  13. self.stopbit = stop
  14. # 读写的数据
  15. self.read_data = None
  16. self.write_data = None
  17. pass
  18. def show_port(self):
  19. for i in range(0,len(self.port_list)):
  20. print(self.port_list[i])
  21. def show_other(self):
  22. print("波特率:"+self.bandRate)
  23. print("校验位:" + self.checkbit)
  24. print("数据位:" + self.databit)
  25. print("停止位:" + self.stopbit)
  26. # 返回串口
  27. def get_port(self):
  28. return self.port_list
  29. # 打开串口
  30. def open_port(self,port):
  31. self.port = serial.Serial(port, self.bandRate,timeout = None)
  32. def delete_port(self):
  33. if self.port != None:
  34. self.port.close()
  35. print("关闭串口完成")
  36. else:
  37. pass
  38. def Read_data(self): # self.port.read(self.port.in_waiting) 表示全部接收串口中的数据
  39. self.read_data = self.port.read(self.port.in_waiting) # 读取数据
  40. return self.read_data.decode("utf-8")
  41. def Write_data(self,data):
  42. if self.port.isOpen() == False:
  43. print("串口打开错误")
  44. else:
  45. self.port.write(data.encode("utf-8")) # 返回的是写入的字节数
  46. if __name__ == '__main__':
  47. myser = SerialAchieve()
  48. myser.open_port("COM7")
  49. myser.delete_port()
  50. myser.show_port()

由于程序写的比较匆忙,所以还有很多需要完善的地方,如果你对这个工程感兴趣可以一起来完善它。
本工程GitHub地址

发表评论

表情:
评论列表 (有 0 条评论,64人围观)

还没有评论,来说两句吧...

相关阅读

    相关 串口通讯介绍

    串口通讯的物理连接和传输协议,是学习单片机串口编程的基础。 本文参照《深入浅出玩转51单片机》和《零死角玩转STM32》书籍,对通讯以及串口一些基本概念做了详解。 1. 串

    相关 java串口通讯实例

    现在一般的电脑都没有串口端口的了,所以还是用虚拟的串口来做测试吧。 我们用 VSPD(Virtual Serial Port Driver) 这个软件建立两个虚拟串口,COM