[经验分享] 【玄铁杯第三届RISC-V应用创新大赛】Python开发体验-实现串口调试助手与串口测试

qinyunti   2023-10-8 10:20 楼主

前言

前面我们体验了板上直接开发,以sqlite3构建为例进行了C开发体验,我们现在来以python为例进行体验。实现一个具备实用价值的串口调试助手,一方面体验python开发环境,一方面进行串口测试。

 

准备

apt-get install python3-tk

apt install python3-serial

 

代码

下载代码

git clone https://gitee.com/qinyunti/python_tkinter_uart.git

cd python_tkinter_uart/

 

# UART Tx/Rx demo

import tkinter as tk

from tkinter import ttk

import serial

import threading

 

# A simple Information Window

class InformWindow:

    def __init__(self,informStr):

        self.window = tk.Tk()

        self.window.title("Information")

        self.window.geometry("220x60")

        label = tk.Label(self.window, text=informStr)

        buttonOK = tk.Button(self.window,text="OK",command=self.processButtonOK)

        label.pack(side = tk.TOP)

        buttonOK.pack(side = tk.BOTTOM)

        self.window.mainloop()

 

    def processButtonOK(self):

        self.window.destroy()

 

class mainGUI:

    def __init__(self):

        window = tk.Tk()

        window.title("GUI UART Tx/Rx Demo")

        self.uartState = False # is uart open or not

 

        # a frame contains COM's information, and start/stop button

        frame_COMinf = tk.Frame(window)

        frame_COMinf.grid(row = 1, column = 1)

 

        labelCOM = tk.Label(frame_COMinf,text="COMx: ")

        self.COM = tk.StringVar(value = "/dev/ttyS3")

        ertryCOM = tk.Entry(frame_COMinf, textvariable = self.COM)

        labelCOM.grid(row = 1, column = 1, padx = 5, pady = 3)

        ertryCOM.grid(row = 1, column = 2, padx = 5, pady = 3)

 

        labelBaudrate = tk.Label(frame_COMinf,text="Baudrate: ")

        self.Baudrate = tk.IntVar(value = 921600)

        ertryBaudrate = tk.Entry(frame_COMinf, textvariable = self.Baudrate)

        labelBaudrate.grid(row = 1, column = 3, padx = 5, pady = 3)

        ertryBaudrate.grid(row = 1, column = 4, padx = 5, pady = 3)

 

        labelParity = tk.Label(frame_COMinf,text="Parity: ")

        self.Parity = tk.StringVar(value ="NONE")

        comboParity = ttk.Combobox(frame_COMinf, width = 17, textvariable=self.Parity)

        comboParity["values"] = ("NONE","ODD","EVEN","MARK","SPACE")

        comboParity["state"] = "readonly"

        labelParity.grid(row = 2, column = 1, padx = 5, pady = 3)

        comboParity.grid(row = 2, column = 2, padx = 5, pady = 3)

 

        labelStopbits = tk.Label(frame_COMinf,text="Stopbits: ")

        self.Stopbits = tk.StringVar(value ="1")

        comboStopbits = ttk.Combobox(frame_COMinf, width = 17, textvariable=self.Stopbits)

        comboStopbits["values"] = ("1","1.5","2")

        comboStopbits["state"] = "readonly"

        labelStopbits.grid(row = 2, column = 3, padx = 5, pady = 3)

        comboStopbits.grid(row = 2, column = 4, padx = 5, pady = 3)

       

        self.buttonSS = tk.Button(frame_COMinf, text = "Start", command = self.processButtonSS)

        self.buttonSS.grid(row = 3, column = 4, padx = 5, pady = 3, sticky = tk.E)

 

        # serial object

        self.ser = serial.Serial()

        # serial read threading

        self.ReadUARTThread = threading.Thread(target=self.ReadUART)

        self.ReadUARTThread.start()

 

        frameRecv = tk.Frame(window)

        frameRecv.grid(row = 2, column = 1)

        labelOutText = tk.Label(frameRecv,text="Received Data:")

        labelOutText.grid(row = 1, column = 1, padx = 3, pady = 2, sticky = tk.W)

        frameRecvSon = tk.Frame(frameRecv)

        frameRecvSon.grid(row = 2, column =1)

        scrollbarRecv = tk.Scrollbar(frameRecvSon)

        scrollbarRecv.pack(side = tk.RIGHT, fill = tk.Y)

        self.OutputText = tk.Text(frameRecvSon, wrap = tk.WORD, width = 60, height = 20, yscrollcommand = scrollbarRecv.set)

        self.OutputText.pack()

 

        frameTrans = tk.Frame(window)

        frameTrans.grid(row = 3, column = 1)

        labelInText = tk.Label(frameTrans,text="To Transmit Data:")

        labelInText.grid(row = 1, column = 1, padx = 3, pady = 2, sticky = tk.W)

        frameTransSon = tk.Frame(frameTrans)

        frameTransSon.grid(row = 2, column =1)

        scrollbarTrans = tk.Scrollbar(frameTransSon)

        scrollbarTrans.pack(side = tk.RIGHT, fill = tk.Y)

        self.InputText = tk.Text(frameTransSon, wrap = tk.WORD, width = 60, height = 5, yscrollcommand = scrollbarTrans.set)

        self.InputText.pack()

        self.buttonSend = tk.Button(frameTrans, text = "Send", command = self.processButtonSend)

        self.buttonSend.grid(row = 3, column = 1, padx = 5, pady = 3, sticky = tk.E)

       

        window.mainloop()

 

    def processButtonSS(self):

        # print(self.Parity.get())

        if (self.uartState):

            self.ser.close()

            self.buttonSS["text"] = "Start"

            self.uartState = False

        else:

            # restart serial port

            self.ser.port = self.COM.get()

            self.ser.baudrate = self.Baudrate.get()

           

            strParity = self.Parity.get()

            if (strParity=="NONE"):

                self.ser.parity = serial.PARITY_NONE

            elif(strParity=="ODD"):

                self.ser.parity = serial.PARITY_ODD

            elif(strParity=="EVEN"):

                self.ser.parity = serial.PARITY_EVEN

            elif(strParity=="MARK"):

                self.ser.parity = serial.PARITY_MARK

            elif(strParity=="SPACE"):

                self.ser.parity = serial.PARITY_SPACE

               

            strStopbits = self.Stopbits.get()

            if (strStopbits == "1"):

                self.ser.stopbits = serial.STOPBITS_ONE

            elif (strStopbits == "1.5"):

                self.ser.stopbits = serial.STOPBITS_ONE_POINT_FIVE

            elif (strStopbits == "2"):

                self.ser.stopbits = serial.STOPBITS_TWO

           

            try:

                self.ser.open()

            except:

                infromStr = "Can't open "+self.ser.port

                InformWindow(infromStr)

           

            if (self.ser.isOpen()): # open success

                self.buttonSS["text"] = "Stop"

                self.uartState = True

 

    def processButtonSend(self):

        if (self.uartState):

            strToSend = self.InputText.get(1.0,tk.END)

            bytesToSend = strToSend[0:-1].encode(encoding='ascii')

            self.ser.write(bytesToSend)

            print(bytesToSend)

        else:

            infromStr = "Not In Connect!"

            InformWindow(infromStr)

 

    def ReadUART(self):

        # print("Threading...")

        while True:

            if (self.uartState):

                try:

                    ch = self.ser.read().decode(encoding='ascii')

                    print(ch,end='')

                    self.OutputText.insert(tk.END,ch)

                except:

                    infromStr = "Something wrong in receiving."

                    InformWindow(infromStr)

                    self.ser.close() # close the serial when catch exception

                    self.buttonSS["text"] = "Start"

                    self.uartState = False

                   

 

mainGUI()

 

 

测试

板上默认使能了串口1,串口0为调试串口。

串口3需要修改设备树使能,我们以串口1测试。

串口1对应设备/dev/ttyS1

 

我们将串口1使用串口线接到PC,

开发板和PC上位机相互发送数据测试

 

python3 Python_Tkinter_UART.py

 

测试如下收发OK

image-20231008102018-1.png  

 

总结

得益于开发版运行完整的Debian系统和优秀的性能,具备完整的Python开发环境,可以直接安装python包,可以方便快捷高效的进行开发。

 

 

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复