Skip to content

Commit

Permalink
幅频特性仪优化
Browse files Browse the repository at this point in the history
  • Loading branch information
framist committed Sep 14, 2021
1 parent 96c4bf1 commit aa59afb
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 82 deletions.
69 changes: 41 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# E-kit

E-kit 一体化电子工具箱,STM32实现,示波器+函数发生器+...
E-kit 一体化电子工具箱,STM32实现,示波器+函数发生器+幅频特性仪器...

![main](README/main.jpg)

![singal](README/singal.png)
![singal](README/singal.jpg)

*目前此仓库仅适合个人参考,但每次提交的工程都确保已实现部分能用*

*注意:采用GB2312编码*



Expand Down Expand Up @@ -49,49 +53,61 @@ E-kit һ

### 1. 软件部分

采用HAL库支持的C语言程序实现,通过无操作系统的形式直接运行在ARM架构STM32F407单片机上。通过 ARM Cortex M4 额外支持的硬件FPU、DSP指令集,更快的FSMC,给予程序更高的运行效率、数据处理效率以及更高的显示速度。

程序流程通过初始化+主循环的模式。稳定性好。显示方案采用STemWin图形库实现,并支持电阻屏触摸。

项目工程已开源在 [framist/E-kit: E-kit 一体化电子工具箱 (github.com)](https://github.com/framist/E-kit)

#### 1.1 示波器部分





通过通用定时器TIM5定时中断,控制ADC按精准的时间间隔取样。



采用FFT得出频率,作为后续处理的前提参考

微分法首先判别是否为方波

积分法判断波形和测占空比

使用TIM4中断方式ADC取样以确保精度

超循环中循环采样及显示及其他功能

显示方案采用STemWin图形库实现;
#### 1.2 信号发生器部分

用一个电阻式触摸屏实现按键输入与显示功能



使用DMA的方法把内存中的波形数据依次传递到DAC控制器,基本定时器TIM6控制DMA的速度来控制输出波形的频率。

#### 1.2 信号发生器部分
通过软件控制波形、峰峰值、偏置电压、占空比。

DAC输出0~3.3V的电平信号再经过外围电路的转换得到-5V到+5V范围的信号并进行输出。


使用DMA的方法把内存中的波形数据依次传递到DAC控制器,定时器控制DMA的速度来控制输出波形的频率。DAC输出0~3.3V的电平信号再经过外围电路的转换得到-5V到+5V范围的信号并进行输出。

#### 1.3 幅频特性仪部分

比较输入输出信号的峰峰值可以计算得出滤波器的增益,

#### 1.3 IOT上位机部分
通过扫频的方式连续测量可以绘制出未知滤波器的幅频特性曲线

蓝牙串口透传模块实现。可转换实现上位机的有线无线传输。
通过幅频特性曲线可以判别出滤波器的类型,目前可自动判别以下几种类型的滤波器:

0:低通 HPF 1:高通 LPF 2:带通 BPF 3:带阻BRF


#### 1.4 幅频特性仪部分

#### 1.4 IOT上位机部分

蓝牙串口透传模块实现。可转换实现与上位机的无线信号传输。

通过其他各种数据分析软件,我们可以同步在上位机观察波形并进行数据分析

![image-20210914214415461](README/image-20210914214415461.png)



Expand Down Expand Up @@ -251,18 +267,17 @@ E-kit һ

**输出波形选择:**

可以选择输出
可以选择输出:

* OFF, 不启用DAC输出功能
* SIN, 正弦波 ~~~~
* TRI, 三角波 VVVV
* SQU, 方波 _||_
* SAW_1, 锯齿波1 /|/|
* SAW_2, 锯齿波2 |\|\|
* RAD, 噪波 ????
* DC, 直流 ----

```c
Wave_Form_NA,
Wave_Form_SIN, //正弦波 ~~~~
Wave_Form_TRI, //三角波 VVVV
Wave_Form_SQU, //方波 _||_
Wave_Form_SAW_1, //锯齿波1 /|/|
Wave_Form_SAW_2, //锯齿波2 |\|\|
Wave_Form_RAD, //噪波 ????
Wave_Form_DC //直流 ----
```

**捷径配置选择:**

Expand Down Expand Up @@ -324,8 +339,6 @@ Wave_Form_DC //ֱ

---

目前此仓库仅适合个人参考,但每次提交的工程都确保已实现部分能用

注意:采用GB2312编码

![image-20210906003413804](README/image-20210906003413804.png)
Binary file added README/image-20210914214415461.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README/singal.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed README/singal.png
Binary file not shown.
68 changes: 34 additions & 34 deletions STM32F407/GUIBulder/AFCFramewinDLG.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,16 @@ static void plot_aPoint(WM_MESSAGE *pMsg){

}

/*********************************************************************
*
* @SignMeasure 单次测量
*/
/**
* @brief 单次测量
*
* @param pMsg
* @return float 测量电压值 V
*/
static float SignMeasure(WM_MESSAGE *pMsg){

extern float Vpp_measured;
Wave_Output_Config(Wave_Form_SIN,F_Ouput,10,0,0);
Wave_Output_Config_F(F_Ouput);

/* 原始方式
u32 nus = 1.0/F_Ouput*1000000.0 * 30.0; //测30次
Expand Down Expand Up @@ -190,14 +192,15 @@ static float SignMeasure(WM_MESSAGE *pMsg){

return Vpp_measured/1000.0f;
}
/*********************************************************************
*
* @cmpfunc 排序所用的比较函数
*/
static int cmpfunc(const void *a, const void *b) {
const float *aa = a;
const float *bb = b;
return (*aa > *bb) - (*aa < *bb);

/**
* @brief 计算db 10.0f是原输出电压
*
* @param Vpp
* @return float
*/
static float _db(float Vpp){
return log10f(Vpp/10.0f)*20.0f;
}
/*********************************************************************
*
Expand All @@ -208,33 +211,30 @@ static int AutoMeasure(WM_MESSAGE *pMsg,int ifMeasure){
int i = 0;
static float pointsX[100] ; //频率-真实值Hz
static float pointsY[100] ; //电压-真实值V
static float pointsYS[100] ; //用于排序找最大最小值的电压
static float mindB;
static float mindB = 9999; //最大的db绝对值

Wave_Output_Config(Wave_Form_SIN,F_Ouput,10,0,0);
PROGBAR_SetValue(WM_GetDialogItem(pMsg->hWin, ID_PROGBAR_0),0);//显示 0%
WM_Paint(WM_GetDialogItem(pMsg->hWin, ID_PROGBAR_0));
if(ifMeasure == 1){
mindB = 9999;
//100 ~ 10 000 Hz 9 900 / 100 + 1 = 100
for(F_Ouput = 100; F_Ouput <= 10000; F_Ouput += 100){
pointsX[i] = (float) F_Ouput;
pointsY[i] = SignMeasure(pMsg) ;
pointsYS[i] = pointsY[i];
if(_db(pointsY[i]) < mindB) mindB = _db(pointsY[i]);
i++;
}

qsort(pointsYS, 100, sizeof(float),cmpfunc );//升序
mindB = (log10f(pointsYS[0]/2.828f)*20.0f );//最大的db绝对值
//float maxdB = (log10f(pointsYS[99]/2.828)*20.0 );
}

if(CHECKBOX_GetState(WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0))==0) {
//普通绘制
for(i = 0; i < _aNumPoints ; i++ ){
if(i < _aNumPoints-1 && fabs(pointsY[i] - pointsY[i-1]) > 0.3) { // 去毛刺
pointsY[i] = pointsY[i+1];
}
_aPoint[i].x = (int)( pointsX[i]/10000.0f*200.0f );
_aPoint[i].y = (int)(225 - (log10f(pointsY[i]/2.42f)*20.0f )/mindB *225 );//先转换为db,再装换为像素
//plot_aPoint( pMsg);

_aPoint[i].y = (int)(225 - (_db(pointsY[i]) )/mindB *225 );//先转换为db,再装换为像素
}
//画曲线
plot_aPoint( pMsg);
Expand All @@ -257,7 +257,7 @@ static int AutoMeasure(WM_MESSAGE *pMsg,int ifMeasure){
pointsY[i] = pointsY[i+1];
}
_aPoint[i].x = (int)( (log10f(pointsX[i])-2)/2.0f*200.0f );//log10 : 2~4
_aPoint[i].y = (int)(225 - (log10f(pointsY[i]/2.42f)*20.0f )/mindB *225 );//先转换为db,再装换为像素
_aPoint[i].y = (int)(225 - ( _db(pointsY[i]) )/mindB *225 );//先转换为db,再装换为像素
//plot_aPoint( pMsg);
}
//画曲线
Expand All @@ -276,7 +276,7 @@ static int AutoMeasure(WM_MESSAGE *pMsg,int ifMeasure){
GRAPH_SCALE_SetTextColor(_hScaleH, GUI_DARKCYAN);
//GRAPH_SCALE_SetTextColor(_hScaleH, GUI_BLACK);//隐藏坐标
}
//滤波器判别 0:低通 1:高通 2:带通 3:带阻
//滤波器判别 0:低通 HPF 1:高通 LPF 2:带通 BPF 3:带阻BRF
if(pointsY[0] < pointsY[50] && pointsY[50] < pointsY[99]){
//高通
filterType = 1;
Expand Down Expand Up @@ -325,7 +325,7 @@ static void _cbDialog(WM_MESSAGE * pMsg) {
// Initialization of 'AFCFramewin'
//
hItem = pMsg->hWin;
FRAMEWIN_SetText(hItem, "amplitude - frequency characteristics | Yexiaqiufeng, Framist");
FRAMEWIN_SetText(hItem, "Amplitude - Frequency Characteristics");
FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
FRAMEWIN_SetFont(hItem, GUI_FONT_16B_1);
//
Expand Down Expand Up @@ -368,13 +368,11 @@ static void _cbDialog(WM_MESSAGE * pMsg) {
TEXT_SetFont(hItem, GUI_FONT_16_1);
// USER START (Optionally insert additional code for further widget initialization)

//
// 滑块、微调框初始化
//

SLIDER_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SLIDER_0), 100, 10000);
SPINBOX_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_0),100,10000);
SPINBOX_SetStep(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_0),10); //频率步进扩展至 10Hz
SPINBOX_SetEdge(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_0),SPINBOX_EDGE_CENTER);
SLIDER_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SLIDER_0), 50, 50000);
SPINBOX_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_0),50,50000);
SPINBOX_SetStep(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_0),20); //频率步进扩展至 10Hz
//
// Initialization of 'GRAPH' 图像初始化
//
Expand Down Expand Up @@ -489,11 +487,13 @@ static void _cbDialog(WM_MESSAGE * pMsg) {

AFC_LogPrint("\nMode==single measurement", pMsg);
//单次测量

Wave_Output_Config(Wave_Form_SIN,F_Ouput,10,0,0);
float sm ;
sm = SignMeasure(pMsg);
sprintf(stemp, "\nADC max V =%.2f dB =%.2f",sm, (log10f(sm/2.42f)*20.0f ));
sprintf(stemp, "\nADC max V =%.2f dB =%.2f",sm, (_db(sm) ));
AFC_LogPrint(stemp, pMsg);
sprintf(stemp, "F output: %dHz\n: %.2fV %.2fdB",F_Ouput,sm,(log10f(sm/2.42f)*20.0f));
sprintf(stemp, "F output: %dHz\n: %.2fV %.2fdB",F_Ouput,sm,(_db(sm) ));
TEXT_SetText(WM_GetDialogItem(pMsg->hWin, ID_TEXT_1), stemp);
TEXT_SetFont(WM_GetDialogItem(pMsg->hWin, ID_TEXT_1), GUI_FONT_8X16);
WM_Paint(WM_GetDialogItem(pMsg->hWin, ID_TEXT_1));
Expand Down
6 changes: 3 additions & 3 deletions STM32F407/GUIBulder/SingalWindowDLG.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ static void _cbDialog(WM_MESSAGE * pMsg) {
RADIO_SetText(hItem, "Frequency (+Hz)", 0);
RADIO_SetText(hItem, "Vpp (+mV)", 1);
RADIO_SetText(hItem, "Offset (+-mV)", 2);
RADIO_SetText(hItem, "Duty (if SQU) (+%)", 3);
RADIO_SetText(hItem, "Duty (if SQU) (+%%)", 3);
RADIO_SetFont(hItem, GUI_FONT_10_ASCII);
//
// Initialization of 'Header'
Expand All @@ -271,8 +271,8 @@ static void _cbDialog(WM_MESSAGE * pMsg) {
SPINBOX_SetEdge(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_2),SPINBOX_EDGE_CENTER);
SPINBOX_SetEdge(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_3),SPINBOX_EDGE_CENTER);

SPINBOX_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_0),1,50000); //暂时的数值设定
SLIDER_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SLIDER_2), 1,50000);
SPINBOX_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_0),20,50000); //暂时的数值设定
SLIDER_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SLIDER_2), 20,50000);

SPINBOX_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_1),0,10000);
SLIDER_SetRange(WM_GetDialogItem(pMsg->hWin, ID_SLIDER_1), 0,10000);
Expand Down
12 changes: 8 additions & 4 deletions STM32F407/GUIBulder/oscilloscopeFramewinDLG.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,9 +664,10 @@ void True_mV_To_aPoints(void) {
for (i = 0; i < _aNumPoints ; i++) {
_aPoint[i].x = (int)(i * 50.0f * k / us_div )-250;
_aPoint[i].y = (int)( True_mV[i]/((float)mV_div)*10.0f) + 250;
if(IOT) {
printf("(%f,%f)\n\t",(float)i,True_mV[i]); // TODO 横坐标精确计算
}
// if(IOT) {
// // TODO 横坐标精确计算
// printf("{plotter:%.3f}\n",True_mV[i]/1000);
// }
}
//更新坐标轴
// 修改垂直刻度
Expand Down Expand Up @@ -707,6 +708,7 @@ void refresh_Measure(WM_HWIN hWin){
extern float Vpp_measured;
extern float F_measured;
extern float DR_measured;
extern float Offset_measured;
char stemp[100] = "";

if(_StopRun == osc_STOP ) return;
Expand All @@ -729,7 +731,9 @@ void refresh_Measure(WM_HWIN hWin){
SPINBOX_SetValue(WM_GetDialogItem(hWin, ID_SPINBOX_0),us_div);
SPINBOX_SetValue(WM_GetDialogItem(hWin, ID_SPINBOX_1),mV_div);

LogPrint(".", hWin);
// offset 中间值
sprintf(stemp, "\noffset=%.2fV; ", Offset_measured/1000.0f);
LogPrint(stemp, hWin);
}


Expand Down
19 changes: 12 additions & 7 deletions STM32F407/HARDWARE/ADC/adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ void Measure(void){
extern float Vpp_measured;
extern float F_measured;
extern float DR_measured;
extern float Offset_measured;
extern enum Wave_Form Input_Wave_Form;
extern int sampleF; //取样频率
extern int us_div;
Expand All @@ -98,7 +99,8 @@ void Measure(void){
float min_mV = 5000;
float temp;
float sum = 0;
float offSet;
float DC_measured;

ADC_ChannelConfTypeDef ADC1_ChanConf;
ADC1_ChanConf.Channel=ADC_CHANNEL_5; //通道 5 (注意)
ADC1_ChanConf.Rank=1; //第1个序列,序列1
Expand Down Expand Up @@ -129,7 +131,7 @@ void Measure(void){

for(i=0; i<NumMeasurePoints; i++){
temp = (float)OrginalV[i]*(3.3f/4096.0f); //得到ADC电压值(现在是真实值,最后需换为转换真实值)
temp = (temp - 1.65f)*5.0f ; //跟外置电路有关
temp = (temp - 1.65f)/1.65f*5.0f ; //跟外置电路有关
temp = temp * 1000.0f;
True_mV[i] = temp;
if(max_mV < True_mV[i]){
Expand All @@ -143,6 +145,9 @@ void Measure(void){

//Vpp
Vpp_measured = max_mV - min_mV;
//Offset_measured
Offset_measured = (max_mV + min_mV)/2;

//F, Hz
F_measured = wave_frequency_calculate();

Expand All @@ -158,12 +163,12 @@ void Measure(void){
max_d = fabs(True_mV[i]-True_mV[i-1]);
}
}
//offSet
offSet = sum / (float)(nTPoints) ;
//DC_measured
DC_measured = sum / (float)(nTPoints) ;

//占空比 (如果强制Input_Wave_Form == 3,则可测)
//占空比 (如果强制Input_Wave_Form == Wave_Form_SQU,则可测)
if(Input_Wave_Form == Wave_Form_SQU) {
DR_measured = (offSet-min_mV)/Vpp_measured;
DR_measured = (DC_measured-min_mV)/Vpp_measured;
}

//波形判断
Expand All @@ -174,7 +179,7 @@ void Measure(void){
//积分判别波形
sum = 0;
for(i=0; i<nTPoints && i<NumMeasurePoints ; i++){
sum += fabs( True_mV[i] - offSet );
sum += fabs( True_mV[i] - DC_measured );
}
temp = (Vpp_measured*1.15f)*(float)nTPoints/4.0f;
if( sum <= temp ) {
Expand Down
Loading

0 comments on commit aa59afb

Please sign in to comment.