找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1679|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

STM32單片機(jī)示波器(pyhton上位機(jī))

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:771642 發(fā)表于 2023-5-30 16:59 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本設(shè)計以Python為上位機(jī)制作的STM32示波器,實現(xiàn)了波形顯示、頻率計算、波形保存等功能,代碼均有完整中文注釋,供大家參考(如果有條件,使用OLED顯示屏當(dāng)做上位機(jī)實現(xiàn)該設(shè)計,這樣有效的減少了上位機(jī)界面刷新的延遲)

文件包括上位機(jī) 下位機(jī) 測試數(shù)據(jù)等

上位機(jī)程序:
  1. import serial
  2. import threading
  3. import time
  4. import matplotlib.pyplot as plt
  5. from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
  6. import tkinter as tk
  7. from tkinter import ttk
  8. from tkinter import filedialog
  9. from PIL import Image, ImageTk
  10. import numpy as np

  11. class Oscilloscope:
  12.     def __init__(self, master):
  13.         self.master = master                    # 定義 master 變量
  14.         self.master.title("簡易示波器")          # 設(shè)置窗口標(biāo)題
  15.         self.master.geometry("1400x600")         # 設(shè)置窗口大小
  16.         self.master.resizable(False, False)     # 設(shè)置窗口不可調(diào)整大小
  17.         self.master.protocol("WM_DELETE_WINDOW", self.close_window)  # 設(shè)置關(guān)閉窗口時調(diào)用的方法

  18.         self.ser = None                         # 定義 ser 變量,初始值為 None
  19.         self.baudrate = tk.StringVar(value="921600")                    # 定義波特率變量,初始值為 "921600"
  20.         self.port = tk.StringVar(value="COM5")                          # 定義端口變量,初始值為 "COM11"
  21.         self.size = tk.StringVar(value=50)
  22.         self.MAXvar = tk.StringVar()
  23.         self.MINvar = tk.StringVar()
  24.         self.Fvar = tk.StringVar()
  25.         self.Fsvar = tk.StringVar()
  26.         self.pause = tk.BooleanVar(value=False)                         # 定義暫停變量,初始值為 False
  27.         self.fig = plt.Figure(figsize=(6, 4), dpi=100)                  # 創(chuàng)建一個 Figure 對象
  28.         self.ax = self.fig.add_subplot(111)                             # 在 Figure 對象中添加一個子圖
  29.         self.canvas = FigureCanvasTkAgg(self.fig, master=self.master)   # 創(chuàng)建一個畫布對象
  30.         self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)  # 將畫布添加到窗口中
  31.         self.toolbar = tk.Frame(master=self.master)                     # 創(chuàng)建一個工具欄對象
  32.         self.toolbar.pack(side=tk.TOP, fill=tk.X)                       # 將工具欄添加到窗口中
  33.         self.pause_button = ttk.Checkbutton(self.toolbar, text="暫停", variable=self.pause, command=self.pause_waveform, width=6)  # 創(chuàng)建一個暫停按鈕
  34.         self.pause_button.pack(side=tk.LEFT, padx=5)                    # 將暫停按鈕添加到工具欄中
  35.         self.save_button = ttk.Button(self.toolbar, text="保存圖片", command=self.save_waveform, width=8)  # 創(chuàng)建一個保存按鈕
  36.         self.save_button.pack(side=tk.LEFT, padx=5)                     # 將保存按鈕添加到工具欄中
  37.         self.port_label = ttk.Label(self.toolbar, text="端口:", width=6)         # 創(chuàng)建一個端口標(biāo)簽
  38.         self.port_label.pack(side=tk.LEFT, padx=5)                      # 將端口標(biāo)簽添加到工具欄中
  39.         self.port_combobox = ttk.Combobox(self.toolbar, textvariable=self.port, values=["COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8","COM10"], width=6)  # 創(chuàng)建一個端口下拉框
  40.         self.port_combobox.pack(side=tk.LEFT, padx=5)                   # 將端口下拉框添加到工具欄中
  41.         self.baudrate_label = ttk.Label(self.toolbar, text="波特率:", width=6)    # 創(chuàng)建一個波特率標(biāo)簽
  42.         self.baudrate_label.pack(side=tk.LEFT, padx=5)                  # 將波特率標(biāo)簽添加到工具欄中
  43.         self.baudrate_combobox = ttk.Combobox(self.toolbar, textvariable=self.baudrate, values=["9600", "115200","921600"], width=6)  # 創(chuàng)建一個波特率下拉框
  44.         self.baudrate_combobox.pack(side=tk.LEFT, padx=5)               # 將波特率下拉框添加到工具欄中
  45.         self.baudrate_label = ttk.Label(self.toolbar, text="橫軸長度:", width=8)    # 創(chuàng)建一個波特率標(biāo)簽
  46.         self.baudrate_label.pack(side=tk.LEFT, padx=5)                  # 將波特率標(biāo)簽添加到工具欄中
  47.         self.baudrate_combobox = ttk.Combobox(self.toolbar, textvariable=self.size, values=[50, 100, 200, 500, 1000], width=5)  # 創(chuàng)建一個橫坐標(biāo)尺寸下拉框
  48.         self.baudrate_combobox.pack(side=tk.LEFT, padx=5)               # 將波特率下拉框添加到工具欄中
  49.         self.connect_button = ttk.Button(self.toolbar, text="連接", command=self.connect, width=6)                           # 創(chuàng)建一個連接按鈕
  50.         self.connect_button.pack(side=tk.LEFT, padx=5)                  # 將連接按鈕添加到工具欄中
  51.         self.disconnect_button = ttk.Button(self.toolbar, text="斷開連接", command=self.disconnect, width=8)             # 創(chuàng)建一個斷開連接按鈕
  52.         self.disconnect_button.pack(side=tk.LEFT, padx=5)
  53.         self.disconnect_button = ttk.Button(self.toolbar, text="清除圖像", command=self.clear, width=8)              # 創(chuàng)建一個斷開連接按鈕
  54.         self.disconnect_button.pack(side=tk.LEFT, padx=5)                # 將斷開連接按鈕添加到工具欄中
  55. ······
復(fù)制代碼
下位機(jī)主程序:
  1. /**********************************************************
  2.                                                                                         MCU接線說明
  3. 采樣接口:PA6
  4. 正弦波:PA4
  5. 三角波:PA5
  6. 增加采樣頻率:KEY0
  7. 降低采樣頻率:KEY1

  8. 基于正點原子精英板 MCU STM32F1Z8T6
  9. 時間:2023年5月12日
  10. ***********************************************************/
  11. #include "led.h"
  12. #include "delay.h"
  13. #include "sys.h"
  14. #include "usart.h"
  15. #include "lcd.h"
  16. #include "adc.h"
  17. #include "dma.h"
  18. #include "timer.h"
  19. #include "table_fft.h"
  20. #include "stm32_dsp.h"
  21. #include "math.h"
  22. #include "key.h"
  23. #include "BEEP.h"
  24. #include "dac.h"
  25. #include "exti.h"

  26. #define NPT 1024 //采樣次數(shù)
  27. #define PI2 6.28318530717959  //2*pi 用于正弦波生成


  28. void InitBufInArray(void);   //正弦波輸出緩存
  29. void sinout(void);                                          //正弦波輸出
  30. void GetPowerMag(void);      //FFT變換,輸出頻率
  31. void sendData(void);
  32. int long fftin [NPT];        //FFT輸入 x[n]
  33. int long fftout[NPT];        //FFT輸出 X[k]
  34. u32 FFT_Mag[NPT/2]={0};      //幅頻特性
  35. u16 magout[NPT];                                                 //模擬正弦波輸出緩存區(qū)

  36. u16 currentadc;              //實時采樣數(shù)據(jù)
  37. u16 adcx[NPT];               //adc數(shù)值緩存
  38. u32 adcmax;                  //采樣最大值和最小值
  39. u32 adcmin;
  40. u8 adc_flag=0;                                                   //采樣結(jié)束標(biāo)志
  41. u8 key_flag=0;                                                          //按鍵掃描標(biāo)志
  42. u8 show_flag=1;                                                         //更新暫停標(biāo)志
  43. u16 T=2000;                                                                         //定時器2重載值,不能小于PWM的Pluse值
  44. u16 pre=36;                                                                          //定時器2預(yù)分頻值
  45. u32 fre;                                                                                   //采樣頻率 Hz
  46. u16 F;                                                                                         //波形頻率

  47. u16 temp=0;                                                                         //幅值最大的頻率成分
  48. u16 t=0;
  49. u16 key;                                                                                  //按鍵

  50. int main()
  51. {
  52.         u16 i;
  53.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  54.         MYDMA1_Config(DMA1_Channel1,(u32)&ADC1->DR,(u32)¤tadc,1);
  55.         uart_init(921600);
  56.         delay_init();
  57.         LED_Init();
  58.         EXTIX_Init();
  59.         Adc_Init();
  60.         InitBufInArray();
  61.         TIM4_Int_Init(1,35);                                //三角波和噪聲頻率控制,
  62.         TIM3_Int_Init(39,71);                                //72MHz/40/72=25kHz   25kHz/1024≈25Hz 正弦波頻率約為24.5Hz
  63.         TIM2_PWM_Init(T-1,pre-1);                //最大頻率72000000/1/2000=3.6KHz
  64.         Dac1_Init();
  65.         Dac2_Init();
  66.         
  67.         while(1)
  68.         {
  69.                 //等待采樣完成
  70.                 while(adc_flag==0)
  71.                 {
  72.                         LED1=!LED1;
  73.                         sendData(); //發(fā)數(shù)據(jù)給上位機(jī)
  74.                         delay_ms(100);
  75.                
  76.                 }
復(fù)制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表