⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 childview.cpp

📁 高速ADC(模数转换器)精度分析
💻 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 + -