1.项目描述
基于STM32G031的单通道简易示波器,可测量正负0~3V,0~100K的输入信号,显示波形、频谱信息,计算总谐波失真。
2.设计思路
其中采用定时器触发ADC采样以精准的控制采用频率,DMA搬运ADC数据
3.功能介绍
首先可以看到这是波形显示界面
可以看到这是对一个2V、10K正弦信号的采集结果
1.在示波器界面,我们可以进行电压刻度的调节有0.2V、0.5V、1V、2V、5V五个挡位。
2.在Run选项中,旋转编码器可暂停波形锁存数据。
3.在时间刻度选项,可以调节采样频率,最小支持10us
4.可以设置上升沿触发与下降沿触发,并且支持用户输入触发电压
5.触发方式包括:自动触发、普通触发、单次触发,单次触发成功后会将数据锁存,并不再刷新屏幕
6.在波形界面,还会显示当前采集波形的幅值与频率信息
按下左侧按键可进入如下频谱界面
可以看到这是对一个30K的方波进行FFT的结果,且测得其总谐波失真为36%
1.在频谱界面中有可以,我们可以进行电压刻度的调节,这个是与波形显示界面公用的,所以同样有0.2V、0.5V、1V、2V、5V五个挡位。
2.支持手动输入采样频率,采样频率在0~1.6M之间。当选中采样频率选项时,编码器左旋可减少一个刻度的采样频率,右旋可增加一个刻度的采样频率。
3.采样频率的步进刻度也支持手动更改,有100Hz、1K、10K、50K、100K五个挡位。
4.具有Auto功能,当开启Auto功能后,单片机将自动根据当前被测信号选定一个合适的采样频率。
5.在界面最下方显示被测信号的基波频率与总谐波失真值。
4.硬件介绍
这是前端信号处理电路
主控是STM32G031的芯片,采用HAL库开发。在信号的前端有一个运放,有一路PWM波通过低通滤波器产生直流偏置加到被测信号以实现采集负电压。
使用一个模拟开关对运放倍数进行控制
使用一个编码器和一个独立按键进行人机交互
OLED对处理结果进行显示
5.主要代码片段
这里是MAIN函数的循环代码
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
KEY_Handle(); //检测按键状态,给出对应标志位
AnalyseFlag();
Option_flag=Oscilloscope.Button();
if(Menu.oscilloscope==1) //示波器界面
{
if(!Oscilloscope.Hold&&!TriMode2_complete) //hold
{
ClearScreen();
pADCSampling=GetWaveADC(Oscilloscope.F_Sample); //采样
AD_calcuate(ADC_Value,pADCSampling,128); //分析处理采集到的数据 128个
Oscilloscope.Wave(ADC_Value); //波形刷到缓存
}
Oscilloscope.Amplitude(AD_Voltage.MAX,AD_Voltage.MIN); //幅值刷到缓存
Oscilloscope.Frequency(); //计算频率
Oscilloscope.Trigger(Option_flag);
Oscilloscope.Scale(Option_flag);
Oscilloscope.Sample(Option_flag);
Oscilloscope.Suspend(Option_flag);
UpdateScreen(); //刷新屏幕
}
else if (Menu.spectrum==1) //频谱界面
{
ClearScreen();
pADCSampling=GetWaveADC(Spectrum.F_Sample);
Process_FFT_Data(pADCSampling); //FFT
FFT_Disply_Sample(Option_flag);
FFT_Sample_Auto(Option_flag);
Oscilloscope.Scale(Option_flag);
FFT_Sample_Scale(Option_flag);
FFT_Disply_Frescale();
FFT_Disply_FreThd();
UpdateScreen();
}
else;
}
6.遇到的主要问题
1.第一次使用HAL库开发,不熟悉。 解决方法:查资料
2.不熟悉示波器原理 解决方法:查资料
7.不完善的地方
1、代码写的很丑,因为一开始没有搭好架构,想一出是一出的写的,导致代码结构不是很清晰。oled库是直接从网上摘抄的,又根据需求增减了很多,导致代码很丑。RAM经常爆,所以复用了一些数组、变量,然后还没写注释。
2、ADC采样波动感觉很大,当被测信号频率超过50K之后AD的采样浮动到了0.1V左右,不太对,而且在小幅值即小于1V的情况下,AD采样波动很大。
3、频谱泄露问题并没有很好解决,写的Auto函数不是很好,效率低。
8.未来的计划和想法
想把前端处理电路完善一下,画块板子,并且将代码移植到STM32F407上实现。然后把之前提到的一些bug修复,设计一个好一些的代码结构。
9.建议
这块板子确实挺不错,唯一的建议就是下次可不可以弄一个大点的RAM呀,让我们实现数组自由,哈哈哈哈哈哈。
10.项目的百度网盘链接
链接:https://pan.baidu.com/s/1h8n0CNtYX2DWd359QOU2JQ
提取码:drmr