📄 childview.cpp
字号:
// ChildView.cpp : implementation of the CChildView class
//
#include "stdafx.h"
#include "ADC.h"
#include "ChildView.h"
#include <iostream.h>
#include <math.h>
#define pi 3.1415926
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
double *data,*xr,*xi,*spect;
double result[5];
int f_bin[7];
int datasize=-1;
int f_sample,N,windowtype;
int xscale,yscale,xo,yo;
BOOL done=FALSE;
void GetData();
void WINDOW(int windowtype);
void FFT();
void GetResult();
int Max(double*pt,int n);
/////////////////////////////////////////////////////////////////////////////
// CChildView
CChildView::CChildView()
{ CSetting CSettingDlg(this);
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView,CWnd )
//{{AFX_MSG_MAP(CChildView)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_LOAD, OnLoad)
ON_COMMAND(ID_SETTING, OnSetting)
ON_COMMAND(ID_RUN, OnRun)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dc(this);
CWnd* pWnd=GetParent();
CDC *pDC=pWnd->GetDC();
if(done)
draw(pDC);
else
pDC->TextOut(250,200,"ADC Evaluation System------Based on FFT");
ReleaseDC(pDC);
// Do not call CWnd::OnPaint() for painting messages
}
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
CString s;
double x_proportion,y_proportion,f,mag;
if(done)
{
x_proportion=double(point.x-xo)/xscale;
y_proportion=double(point.y-yo)/yscale;
if(x_proportion<=1&&x_proportion>0&&y_proportion<=1&&y_proportion>0)
{ f=x_proportion*f_sample/2;
mag=y_proportion*(-130);
s.Format("%.4fMHz %.3fdB",f/1000000.0,mag);
AfxMessageBox(s);
}
}
}
void CChildView::OnLoad()
{
done=FALSE;
GetData();
InvalidateRect(NULL, TRUE);
}
void CChildView::OnSetting()
{
CSettingDlg.m_points=datasize;
CSettingDlg.DoModal();
}
void CChildView::OnRun()
{
f_sample=CSettingDlg.m_freq;
N=CSettingDlg.m_points;
windowtype=CSettingDlg.m_window;
xr=(double *)calloc(N, sizeof(double));
xi=(double *)calloc(N, sizeof(double));
for(int i=0;i<N;i++)
{
if(i<datasize) xr[i]=data[i];
else xr[i]=0;
xi[i]=0;
}
WINDOW(windowtype); // window the sine wave //
FFT();
GetResult();
done=TRUE;
InvalidateRect(NULL, TRUE);
free(xr);
free(xi);
}
void CChildView::draw(CDC*pDC)
{
int x_temp,y_temp,i;
char str[5][30];
char buffer[30];
CRect rcClient;
GetClientRect(rcClient);
CPen myPen;
CPen* pOldPen;
xo=50;yo=100;
xscale=rcClient.right-250;
yscale=rcClient.bottom-150;
//Analyse Result Output.....//
pDC->SetTextColor(RGB(0,100,0));
pDC->TextOut(rcClient.right/2-100,50,"ADC Analyse Result");
sprintf(str[0],"Signal : %.4lf MHz",result[0]/1000000.0);
sprintf(str[1],"SINAD : %.4lf dB",result[1]);
sprintf(str[2],"ENOB : %.4lf Bit",result[2]);
sprintf(str[3],"SFDR : %.4lf dB",result[3]);
sprintf(str[4],"THD : %.4lf dB",result[4]);
for(i=0;i<5;i++) pDC->TextOut(rcClient.right-180,100+i*20,str[i]);
//Draw Coordinate.....//
myPen.CreatePen(PS_DOT, 1, RGB(0,0,100));
pOldPen = pDC->SelectObject(&myPen);
for(i = 0; i <=13; i++)
{ itoa(-i*10,buffer,10);
pDC->TextOut(xo-30,yo+int(i*yscale/13)-10,buffer);
pDC->MoveTo(xo , yo+int(i*yscale/13));
pDC->LineTo(xo + xscale, yo+int(i*yscale/13));
}
for(i = 0; i <=8; i++)
{ itoa(i*(f_sample/2)/8000000,buffer,10);
pDC->TextOut(xo+int(i*xscale/8)-5,yo+yscale,buffer);
pDC->MoveTo(xo+int(i*xscale/8) , yo+yscale);
pDC->LineTo(xo+int(i*xscale/8), yo);
}
pDC->TextOut(xo + xscale/2-50, yo + yscale+30,"Frequency----MHz");
pDC->TextOut(xo-30,yo-30,"dB");
pDC->SelectObject(pOldPen);
myPen.DeleteObject();
pDC->MoveTo(xo, yo);
pDC->LineTo(xo + xscale, yo);
pDC->MoveTo(xo, yo + yscale);
pDC->LineTo(xo + xscale, yo + yscale);
pDC->MoveTo(xo, yo);
pDC->LineTo(xo, yo + yscale);
pDC->MoveTo(xo + xscale, yo);
pDC->LineTo(xo + xscale, yo + yscale);
//Draw Spectrum.....//
myPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
pOldPen = pDC->SelectObject(&myPen);
pDC->MoveTo(xo,yo + yscale);
for(i=0; i<N/2; i++)
{
x_temp=((i*xscale)/(N/2));
y_temp=(int)(yscale*spect[i]/(-130));
if(y_temp>yscale) y_temp=yscale;
pDC->LineTo(xo+x_temp,yo+y_temp);
}
//Harmonic...//
CString sHar;
pDC->SetTextColor(RGB(100,0,0));
pDC->TextOut(rcClient.right-180,yo+yscale-120,"Harmonic Magnitude");
for(i=2;i<=6;i++)
{ x_temp=(f_bin[i]*xscale)/(N/2);
y_temp=(int)(yscale*spect[f_bin[i]]/(-130));
pDC->TextOut(xo+x_temp-3,yo+y_temp-10,itoa(i,buffer,10));
sHar.Format("%.4f MHz %.4f dB",(double)f_sample/1000000.0/N*f_bin[i],spect[f_bin[i]]);
pDC->TextOut(rcClient.right-180,yo+yscale-140+20*i,sHar);
}
pDC->SelectObject(pOldPen);
myPen.DeleteObject();
}
void GetData()
{
double tmp,*pt;
FILE *fp;
CString filenameld;
CString sMeg;
CFileDialog dlgF(TRUE, "NULL", "*.dat");
datasize=-1;
if( dlgF.DoModal() == IDOK)
{
filenameld = dlgF.GetPathName();
fp = fopen( filenameld, "r" );
if (fp != NULL)
{
while(!feof(fp))
{ fscanf(fp,"%lf",&tmp);
datasize++;
}
data=(double *)calloc(datasize, sizeof(double));
pt=data;
rewind(fp);
while(!feof(fp))
{ fscanf(fp,"%lf",pt++);
}
fclose(fp);
sMeg.Format("%d Data Points Loaded!",datasize);
AfxMessageBox(sMeg);
}
}
}
void WINDOW(int windowtype)
{ int i;
double a;
switch(windowtype)
{
case 0: break; //Rectangular
case 1: for( i=0; i<N/2; i++ ) //Hanning Window//
{
a= (1-cos(2*pi*i/(N-1)))/2;
xr[i] = xr[i]*a;
xr[N-1-i] = xr[N-1-i]*a;
}
break;
case 2: for( i=0; i<N/2; i++ ) // Hamming Window
{
a= 0.54 - 0.46 * cos(pi* 2 * i / (N-1));
xr[i] = xr[i]*a;
xr[N-1-i] = xr[N-1-i]*a;
}
break;
case 3: for( i=0; i<N/2; i++ )// Blackman Window
{
a= 0.42 - 0.5 * cos(pi * 2 * i / (N-1))+
0.08 * cos(2.0 * pi * 2 * i / (N-1));
xr[i] = xr[i]*a;
xr[N-1-i] = xr[N-1-i]*a;
}
break;
default:break;
}
}
void FFT()
{ int m,s,t,r,s_total,t_total,p,q,M;
double tr, ti, ur, ui, wr, wi;
// bit reversal first //
int i,j=1,k;
for( i=1; i<=N; i++ )
{ if( i<j )
{ tr = xr[j-1];
ti = xi[j-1];
xr[j-1] = xr[i-1];
xi[j-1] = xi[i-1];
xr[i-1] = tr;
xi[i-1] = ti;
}
k =N/2;
while( k>=2&&k<j ) { j = j-k; k = k/2; }
j = j+k;
}
// recursive algorithm for individual 2 point DFTs //
s_total=N/2; t_total=1;
M=(int)(log(N)/log(2)+0.5);
for( m=1; m<=M; m++)
{
for(s=0;s<=s_total-1;s++)
for(t=0;t<=t_total-1;t++)
{
p=2*s*t_total+t;
q=p+t_total;
r=t*s_total;
wr = cos(2*pi*r/N );
wi = -1.0*sin(2*pi*r/N);
tr = xr[p];
ti = xi[p];
ur=wr*xr[q]-wi*xi[q];
ui=wr*xi[q]+wi*xr[q];
xr[p] = xr[p]+ur;
xi[p] = xi[p]+ui;
xr[q] = tr-ur;
xi[q] = ti-ui;
}
s_total/=2;
t_total*=2;
}
}
void GetResult()
{
int i,har_bin,focus,span;
double a,Pdc,Ps,Pd,Ptotal,signal;
Ptotal=Ps=Pdc=Pd=0;
spect=(double *)calloc(N/2, sizeof(double));
for( i=0; i<N/2; i++ )
{ spect[i] = ( xr[i]*xr[i]+xi[i]*xi[i] ); // compute the spectrum .... //
Ptotal+=spect[i];
}
focus=Max(spect,N/2);
span=(N/200)>5?(N/200):5;
for( i=focus-span;i<=focus+span;i++) Ps+=spect[i];
for( i=0;i<=span;i++) Pdc+=spect[i];
result[0]=f_sample/N*focus; //Fundamental Frequency...//
result[1]=10*log10(Ps/(Ptotal-Ps-Pdc)); //SINAD...//
result[2]=(result[1]-1.76)/6.02; //ENOB...//
f_bin[1]=focus;
signal=spect[focus];
for( i=2; i<=6; i++ )
{
if(((i*focus)%N)<=(N/2)) har_bin=(i*focus)%N;
else har_bin=N-((i*focus)%N);
f_bin[i]=har_bin-1+Max(&spect[har_bin-1],3);
Pd+=spect[har_bin-1]+spect[har_bin]+spect[har_bin+1];;
}
for( i=0,a=0.0; i<N/2; i++ )
{
if((i>span&&i<focus-span)||(i>focus+span))
if( spect[i] > a ) {a = spect[i]; f_bin[0]=i;}
}
result[3]=10*log10(signal/a); //SFDR...//
result[4]=10*log10(Pd/Ps); //THD...//
for( i=0; i<N/2; i++ ) spect[i] = 10*log10(spect[i]/signal);
}
int Max(double*pt,int n)
{ int MaxNo=0;
double tmp=pt[0];
for(int i=1;i<n;i++)
if(pt[i]>tmp){tmp=pt[i]; MaxNo=i;}
return MaxNo;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -