标题:
STM32单片机示波器(pyhton上位机)
[打印本页]
作者:
SORZ
时间:
2023-5-30 16:59
标题:
STM32单片机示波器(pyhton上位机)
本设计以Python为上位机制作的STM32示波器,实现了波形显示、频率计算、波形保存等功能,代码均有完整中文注释,供大家参考(如果有条件,使用OLED显示屏当做上位机实现该设计,这样有效的减少了上位机界面刷新的延迟)
文件包括上位机 下位机 测试数据等
上位机程序:
import serial
import threading
import time
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from PIL import Image, ImageTk
import numpy as np
class Oscilloscope:
def __init__(self, master):
self.master = master # 定义 master 变量
self.master.title("简易示波器") # 设置窗口标题
self.master.geometry("1400x600") # 设置窗口大小
self.master.resizable(False, False) # 设置窗口不可调整大小
self.master.protocol("WM_DELETE_WINDOW", self.close_window) # 设置关闭窗口时调用的方法
self.ser = None # 定义 ser 变量,初始值为 None
self.baudrate = tk.StringVar(value="921600") # 定义波特率变量,初始值为 "921600"
self.port = tk.StringVar(value="COM5") # 定义端口变量,初始值为 "COM11"
self.size = tk.StringVar(value=50)
self.MAXvar = tk.StringVar()
self.MINvar = tk.StringVar()
self.Fvar = tk.StringVar()
self.Fsvar = tk.StringVar()
self.pause = tk.BooleanVar(value=False) # 定义暂停变量,初始值为 False
self.fig = plt.Figure(figsize=(6, 4), dpi=100) # 创建一个 Figure 对象
self.ax = self.fig.add_subplot(111) # 在 Figure 对象中添加一个子图
self.canvas = FigureCanvasTkAgg(self.fig, master=self.master) # 创建一个画布对象
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True) # 将画布添加到窗口中
self.toolbar = tk.Frame(master=self.master) # 创建一个工具栏对象
self.toolbar.pack(side=tk.TOP, fill=tk.X) # 将工具栏添加到窗口中
self.pause_button = ttk.Checkbutton(self.toolbar, text="暂停", variable=self.pause, command=self.pause_waveform, width=6) # 创建一个暂停按钮
self.pause_button.pack(side=tk.LEFT, padx=5) # 将暂停按钮添加到工具栏中
self.save_button = ttk.Button(self.toolbar, text="保存图片", command=self.save_waveform, width=8) # 创建一个保存按钮
self.save_button.pack(side=tk.LEFT, padx=5) # 将保存按钮添加到工具栏中
self.port_label = ttk.Label(self.toolbar, text="端口:", width=6) # 创建一个端口标签
self.port_label.pack(side=tk.LEFT, padx=5) # 将端口标签添加到工具栏中
self.port_combobox = ttk.Combobox(self.toolbar, textvariable=self.port, values=["COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8","COM10"], width=6) # 创建一个端口下拉框
self.port_combobox.pack(side=tk.LEFT, padx=5) # 将端口下拉框添加到工具栏中
self.baudrate_label = ttk.Label(self.toolbar, text="波特率:", width=6) # 创建一个波特率标签
self.baudrate_label.pack(side=tk.LEFT, padx=5) # 将波特率标签添加到工具栏中
self.baudrate_combobox = ttk.Combobox(self.toolbar, textvariable=self.baudrate, values=["9600", "115200","921600"], width=6) # 创建一个波特率下拉框
self.baudrate_combobox.pack(side=tk.LEFT, padx=5) # 将波特率下拉框添加到工具栏中
self.baudrate_label = ttk.Label(self.toolbar, text="横轴长度:", width=8) # 创建一个波特率标签
self.baudrate_label.pack(side=tk.LEFT, padx=5) # 将波特率标签添加到工具栏中
self.baudrate_combobox = ttk.Combobox(self.toolbar, textvariable=self.size, values=[50, 100, 200, 500, 1000], width=5) # 创建一个横坐标尺寸下拉框
self.baudrate_combobox.pack(side=tk.LEFT, padx=5) # 将波特率下拉框添加到工具栏中
self.connect_button = ttk.Button(self.toolbar, text="连接", command=self.connect, width=6) # 创建一个连接按钮
self.connect_button.pack(side=tk.LEFT, padx=5) # 将连接按钮添加到工具栏中
self.disconnect_button = ttk.Button(self.toolbar, text="断开连接", command=self.disconnect, width=8) # 创建一个断开连接按钮
self.disconnect_button.pack(side=tk.LEFT, padx=5)
self.disconnect_button = ttk.Button(self.toolbar, text="清除图像", command=self.clear, width=8) # 创建一个断开连接按钮
self.disconnect_button.pack(side=tk.LEFT, padx=5) # 将断开连接按钮添加到工具栏中
······
复制代码
下位机主程序:
/**********************************************************
MCU接线说明
采样接口:PA6
正弦波:PA4
三角波:PA5
增加采样频率:KEY0
降低采样频率:KEY1
基于正点原子精英板 MCU STM32F1Z8T6
时间:2023年5月12日
***********************************************************/
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "adc.h"
#include "dma.h"
#include "timer.h"
#include "table_fft.h"
#include "stm32_dsp.h"
#include "math.h"
#include "key.h"
#include "BEEP.h"
#include "dac.h"
#include "exti.h"
#define NPT 1024 //采样次数
#define PI2 6.28318530717959 //2*pi 用于正弦波生成
void InitBufInArray(void); //正弦波输出缓存
void sinout(void); //正弦波输出
void GetPowerMag(void); //FFT变换,输出频率
void sendData(void);
int long fftin [NPT]; //FFT输入 x[n]
int long fftout[NPT]; //FFT输出 X[k]
u32 FFT_Mag[NPT/2]={0}; //幅频特性
u16 magout[NPT]; //模拟正弦波输出缓存区
u16 currentadc; //实时采样数据
u16 adcx[NPT]; //adc数值缓存
u32 adcmax; //采样最大值和最小值
u32 adcmin;
u8 adc_flag=0; //采样结束标志
u8 key_flag=0; //按键扫描标志
u8 show_flag=1; //更新暂停标志
u16 T=2000; //定时器2重载值,不能小于PWM的Pluse值
u16 pre=36; //定时器2预分频值
u32 fre; //采样频率 Hz
u16 F; //波形频率
u16 temp=0; //幅值最大的频率成分
u16 t=0;
u16 key; //按键
int main()
{
u16 i;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
MYDMA1_Config(DMA1_Channel1,(u32)&ADC1->DR,(u32)¤tadc,1);
uart_init(921600);
delay_init();
LED_Init();
EXTIX_Init();
Adc_Init();
InitBufInArray();
TIM4_Int_Init(1,35); //三角波和噪声频率控制,
TIM3_Int_Init(39,71); //72MHz/40/72=25kHz 25kHz/1024≈25Hz 正弦波频率约为24.5Hz
TIM2_PWM_Init(T-1,pre-1); //最大频率72000000/1/2000=3.6KHz
Dac1_Init();
Dac2_Init();
while(1)
{
//等待采样完成
while(adc_flag==0)
{
LED1=!LED1;
sendData(); //发数据给上位机
delay_ms(100);
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1