標(biāo)題: STM32單片機(jī)示波器(pyhton上位機(jī)) [打印本頁]

作者: SORZ    時(shí)間: 2023-5-30 16:59
標(biāo)題: STM32單片機(jī)示波器(pyhton上位機(jī))
本設(shè)計(jì)以Python為上位機(jī)制作的STM32示波器,實(shí)現(xiàn)了波形顯示、頻率計(jì)算、波形保存等功能,代碼均有完整中文注釋,供大家參考(如果有條件,使用OLED顯示屏當(dāng)做上位機(jī)實(shí)現(xiàn)該設(shè)計(jì),這樣有效的減少了上位機(jī)界面刷新的延遲)

文件包括上位機(jī) 下位機(jī) 測(cè)試數(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)閉窗口時(shí)調(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)建一個(gè) Figure 對(duì)象
  28.         self.ax = self.fig.add_subplot(111)                             # 在 Figure 對(duì)象中添加一個(gè)子圖
  29.         self.canvas = FigureCanvasTkAgg(self.fig, master=self.master)   # 創(chuàng)建一個(gè)畫布對(duì)象
  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)建一個(gè)工具欄對(duì)象
  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)建一個(gè)暫停按鈕
  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)建一個(gè)保存按鈕
  36.         self.save_button.pack(side=tk.LEFT, padx=5)                     # 將保存按鈕添加到工具欄中
  37.         self.port_label = ttk.Label(self.toolbar, text="端口:", width=6)         # 創(chuàng)建一個(gè)端口標(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)建一個(gè)端口下拉框
  40.         self.port_combobox.pack(side=tk.LEFT, padx=5)                   # 將端口下拉框添加到工具欄中
  41.         self.baudrate_label = ttk.Label(self.toolbar, text="波特率:", width=6)    # 創(chuàng)建一個(gè)波特率標(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)建一個(gè)波特率下拉框
  44.         self.baudrate_combobox.pack(side=tk.LEFT, padx=5)               # 將波特率下拉框添加到工具欄中
  45.         self.baudrate_label = ttk.Label(self.toolbar, text="橫軸長度:", width=8)    # 創(chuàng)建一個(gè)波特率標(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)建一個(gè)橫坐標(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)建一個(gè)連接按鈕
  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)建一個(gè)斷開連接按鈕
  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)建一個(gè)斷開連接按鈕
  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. 基于正點(diǎn)原子精英板 MCU STM32F1Z8T6
  9. 時(shí)間: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í)時(shí)采樣數(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;                                                                         //定時(shí)器2重載值,不能小于PWM的Pluse值
  44. u16 pre=36;                                                                          //定時(shí)器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ù)制代碼





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1