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

📄 displayroutines.cpp

📁 USB 上位机程序 VNA使用,网络分析仪原理使用仪器
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	catch(System::IO::IOException* pe)
	{
		MessageBox::Show(S"Error", pe->Message);
	}

	__finally
	{
		if (fs)
            fs->Flush();
		if (bw)
			bw->Close();
		if (fs)
			fs->Close();
	}

}




/// Convert Log Tx Level to linear value needed by DAC register
unsigned short TxLevLinear(int tranLevel)
{
	// 0 dbm is the max level. Corresponds to 4095 decimal for IDAC control register.
	// 0 dbm -> 4095     -20 dbm -> 410    -40 dbm -> 41

	unsigned short linlevel = (unsigned short)((double)MAX_DDS_LEVEL * pow(10.0,(((double)tranLevel)/20.0)) + 0.5);
	return (linlevel);
};
/// Convert linear DAC level to dBm.  4095 = 0 dBm.
float dBFromLinear(int DAClevel)
{
	float dB = (float)(20.0 * log10 ((float(DAClevel)/(float)MAX_DDS_LEVEL)));
	return (dB);
};


/// Convert Return Loss (S11 mag) to SWR, then to Y-coordinate.
int ToDisplayAsSWR(double mag, int height, int scaledB)
{

	/// Derive vertical plot value using dB scale factor as SWR range.
	/// scaledB has value 10, 5, 2 or 1 dB/division.
	/// Interpret it as 10 SWR units full scale - i.e. 1 to 11
	/// or as 5 units (1 to 6), 2 units (1..3), or as 1 unit (1..2)

	if (mag > 1.0)		// clip display if S11 mag is greater than unity
		mag = 1.0;		// indicates something wrong in compensation

	int vertical;
	double swr = ( 1.0 + mag ) / ( 1.0 - mag);

	vertical = (int)(((swr - 1.0) / (double)scaledB) * (double)height);

	vertical = height - vertical;			// flip display -- SWR = 1 is at bottom line of display

	if (vertical > height)					// crop display - probably a better way to do this
		vertical = height;
	if (vertical < 0)
		vertical = 0;

	return(vertical);						// return Y as positive number

}
	/// Export S-parameters to file.
void ExportSParams(int mode,  FrequencyGrid * FG, 
				double S11Mag __gc[],  double S11Phs __gc[],
				double S21Mag __gc[],  double S21Phs __gc[],
				double S22Mag __gc[],  double S22Phs __gc[],
				double S12Mag __gc[],  double S12Phs __gc[])
{
	/// Uses Mag/Phase Forward and Reverse held in internal storage variables.
	/// mode: 0 -> S2P rectangular mode, 1 -> S2P polar mode, 2-> CSV rectangular mode

	double FwdTranMagdB, FwdTranPhsDeg, FwdReflMagdB, FwdReflPhsDeg;
	double RevTranMagdB, RevTranPhsDeg, RevReflMagdB, RevReflPhsDeg;
	double FwdTranRe, FwdTranIm, FwdReflRe, FwdReflIm;
	double RevTranRe, RevTranIm, RevReflRe, RevReflIm;

	FileStream* fs;
	StreamWriter* sw;

	SaveFileDialog* outfile = new SaveFileDialog();
	if(mode<2)	// S2P format
		outfile->Filter = "s-parameter 2-port files (*.s2p)|*.s2p";
	else		// CSV format
		outfile->Filter = "CSV format files (*.csv)|*.csv";

	outfile->AddExtension = true;
	if (outfile->ShowDialog() != DialogResult::OK)
		return;

	try
	{
		// Create a filestream & stream writer

		fs = new FileStream(outfile->FileName, FileMode::Create, FileAccess::Write);
		sw = new StreamWriter(fs);

			// Write Header for S-parameter file

			sw->WriteLine(S"! Vector Network Analyzer VNA R2");		// put string header on outfile
			sw->WriteLine(S"! Tucson Amateur Packet Radio");		// put string header on outfile
			DateTime today = DateTime::Now;
			sw->Write(S"! ");
			sw->Write(today.ToLongDateString());
			sw->Write(S"   ");
			sw->WriteLine(today.ToLongTimeString());

		// Header line defines type of file
		if (mode==1)	// S2P polar
		{
			sw->WriteLine(S"! Frequency         S11                 S21                  S12                  S22");
			sw->WriteLine(S"# HZ  S  DB R 50");	// polar is in DB amplitude and degrees WRT 50 ohms
		}
		if (mode==0)	// S2P rectangular
		{
			sw->WriteLine(S"! Frequency              S11                           S21                            S12                            S22");
			sw->WriteLine(S"# HZ  S  RI R 50");	// rectangular is in Real and Imaginary WRT 50 ohms
		}
		if (mode==2)	// CSV rectangular
		{
			sw->WriteLine(S"50+j0,\"=COMPLEX(50,0)\",,Unity,\"=COMPLEX(1,0)\"");
			sw->WriteLine(S",");
			sw->WriteLine(S"Frequency (Hz.),S11,S21,S12,S22,,Zin,Zout");
		}

		// write out the parameters

		if (mode==1)											// S2P polar format
			for(int i=0; i<FG->Points; i++)
			{
				FwdReflMagdB = 20.0 * log10(S11Mag[i]);
				FwdReflPhsDeg = S11Phs[i];
				FwdTranMagdB = 20.0 * log10(S21Mag[i]);
				FwdTranPhsDeg = S21Phs[i];
				RevTranMagdB = 20.0 * log10(S12Mag[i]);
				RevTranPhsDeg = S12Phs[i];
				RevReflMagdB = 20.0 * log10(S22Mag[i]);
				RevReflPhsDeg = S22Phs[i];

				sw->Write(FG->Frequency(i).ToString("D9"));			sw->Write(S"    ");
				sw->Write(FwdReflMagdB.ToString("F3"));			sw->Write(S"  ");
				sw->Write(FwdReflPhsDeg.ToString("F3"));			sw->Write(S"    ");
				sw->Write(FwdTranMagdB.ToString("F3"));			sw->Write(S"  ");
				sw->Write(FwdTranPhsDeg.ToString("F3"));			sw->Write(S"    ");
				sw->Write(RevTranMagdB.ToString("F3"));			sw->Write(S"  ");
				sw->Write(RevTranPhsDeg.ToString("F3"));			sw->Write(S"    ");
				sw->Write(RevReflMagdB.ToString("F3"));			sw->Write(S"  ");
				sw->WriteLine(RevReflPhsDeg.ToString("F3"));



			}
		if (mode==0)												// S2P rectangular format
			for(int i=0; i<FG->Points; i++)
			{
				FwdReflRe = S11Mag[i] * cos(S11Phs[i] * DEGR2RAD);
				FwdReflIm = S11Mag[i] * sin(S11Phs[i] * DEGR2RAD);
				FwdTranRe = S21Mag[i] * cos(S21Phs[i] * DEGR2RAD);
				FwdTranIm = S21Mag[i] * sin(S21Phs[i] * DEGR2RAD);
				RevTranRe = S12Mag[i] * cos(S12Phs[i] * DEGR2RAD);
				RevTranIm = S12Mag[i] * sin(S12Phs[i] * DEGR2RAD);
				RevReflRe = S22Mag[i] * cos(S22Phs[i] * DEGR2RAD);
				RevReflIm = S22Mag[i] * sin(S22Phs[i] * DEGR2RAD);

				sw->Write(FG->Frequency(i).ToString("D9"));		sw->Write(S"    ");
				sw->Write(FwdReflRe.ToString("E5"));				sw->Write(S"  ");
				sw->Write(FwdReflIm.ToString("E5"));				sw->Write(S"    ");
				sw->Write(FwdTranRe.ToString("E5"));				sw->Write(S"  ");
				sw->Write(FwdTranIm.ToString("E5"));				sw->Write(S"    ");
				sw->Write(RevTranRe.ToString("E5"));				sw->Write(S"  ");
				sw->Write(RevTranIm.ToString("E5"));				sw->Write(S"    ");
				sw->Write(RevReflRe.ToString("E5"));				sw->Write(S"  ");
				sw->WriteLine(RevReflIm.ToString("E5"));
			}

		if (mode==2)												// CSV rectangular format
			for(int i=0; i<FG->Points; i++)
			{
				FwdReflRe = S11Mag[i] * cos(S11Phs[i] * DEGR2RAD);
				FwdReflIm = S11Mag[i] * sin(S11Phs[i] * DEGR2RAD);
				FwdTranRe = S21Mag[i] * cos(S21Phs[i] * DEGR2RAD);
				FwdTranIm = S21Mag[i] * sin(S21Phs[i] * DEGR2RAD);
				RevTranRe = S12Mag[i] * cos(S12Phs[i] * DEGR2RAD);
				RevTranIm = S12Mag[i] * sin(S12Phs[i] * DEGR2RAD);
				RevReflRe = S22Mag[i] * cos(S22Phs[i] * DEGR2RAD);
				RevReflIm = S22Mag[i] * sin(S22Phs[i] * DEGR2RAD);

				sw->Write(FG->Frequency(i).ToString("D9"));		sw->Write(S",");
				sw->Write(S"\"=COMPLEX({0},{1})\",",FwdReflRe.ToString("E5"),FwdReflIm.ToString("E5"));
				sw->Write(S"\"=COMPLEX({0},{1})\",",FwdTranRe.ToString("E5"),FwdTranIm.ToString("E5"));
				sw->Write(S"\"=COMPLEX({0},{1})\",",RevTranRe.ToString("E5"),RevTranIm.ToString("E5"));
				sw->Write(S"\"=COMPLEX({0},{1})\",,",RevReflRe.ToString("E5"),RevReflIm.ToString("E5"));

				// build row number - data starts in the 7th row of the spreadsheet
				int rownum = i+7;
				String * Row = rownum.ToString();

				// Zin (S11 converted to impedance)
				//=IMPRODUCT(50ohms,(IMDIV(IMSUM(unity,S11),IMSUB(unity,S11)))
				sw->Write(S"\"=IMPRODUCT($B$4,(IMDIV(IMSUM($E$4,$B{0}),IMSUB($E$4,$B{0}))))\",",Row);
				//Zout (S22 converted to impedance)
				sw->WriteLine(S"\"=IMPRODUCT($B$4,(IMDIV(IMSUM($E$4,$E{0}),IMSUB($E$4,$E{0}))))\",",Row);
			}


		sw->WriteLine();

    }
	catch(System::IO::IOException* pe)
	{
		MessageBox::Show(S"File Output Error", pe->Message);
	}
	__finally
	{
		if (sw)
            sw->Flush();
		if (sw)
			sw->Close();
		if (fs)
			fs->Close();
	}

}

	/// Store S-parameters to internal temporary storage.
void StoreSParams(bool calmode, FrequencyGrid * FG, CalDataSet * CalData,
				unsigned short trace2 __gc[], unsigned short trace3 __gc[], unsigned short trace4 __gc[],
				unsigned short trace7 __gc[], unsigned short trace8 __gc[], unsigned short trace9 __gc[],
				unsigned short trace11 __gc[], unsigned short trace12 __gc[],
				double reflMag __gc[],  double reflPhs __gc[],  double tranMag __gc[], double tranPhs __gc[])
{
	/// Store Forward caller gives us pointers to Forward storage,
	///   store Reverse caller gives us pointers to Reverse storage
	/// calmode: 1 -> use fixture calibration

	double fmagnitude;			// 0 to 1
	double fphase;				// -180 to +180	
	double& rmag = fmagnitude;
	double& rphs = fphase;

	for (int i=0; i<FG->Points; i++)	// Display measurements on the frequency grid
	{
		// Compute S11 or S22
		CalData->ResolveReflPolar(trace3[i], trace4[i], trace2[i], FG->Frequency(i), rmag, rphs, true);
		if (calmode)
			CorrectS11(CalData, FG->Frequency(i), fmagnitude, fphase, rmag, rphs);

		reflMag[i] = fmagnitude;	// store reflected component in polar form
		reflPhs[i] = fphase;

		
		// Compute S21 or S12
		CalData->ResolveTranPolar(trace8[i], trace9[i], trace7[i], trace11[i], trace12[i], FG->Frequency(i), rmag, rphs);
		if (calmode)
			CorrectS21(CalData, FG->Frequency(i), fmagnitude, fphase, rmag, rphs);

		tranMag[i] = fmagnitude;	// store transmitted component in polar form
		tranPhs[i] = fphase;

	}

}


// Linear interpolation of Xval between Xlow and Xhigh yielding Y result between Ylow and Yhi
//double public Interpolate(int Xval, int Xlow, int Ylow, int Xhi, int Yhi)
//{
//    float slope = ((float)Yhi - (float)Ylow) / ((float)Xhi-(float)Xlow);
//	double result = (float)Ylow + (((float)Xval - (float)Xlow) * slope);
//	return(result);
//}
//double public Interpolate(float Xval, float Xlow, float Ylow, float Xhi, float Yhi)
//{
//    float slope = (Yhi - Ylow) / (Xhi-Xlow);
//	double result = Ylow + ((Xval - Xlow) * slope);
//	return(result);
//}

// Median filtering routine.  Input is 7 measurements [0..6]. Returns the median value.
int Median7(unsigned short data __gc[], int index)
{
	int i, j;
	unsigned short temp;
	unsigned short numbers[7];

	for (i=0; i<7; i++)			// make a local copy of the data
		numbers[i] = data[index + i];		// don't alter what was given to us

	// bubble sort the elements
	for (i=6; i>=0; i--)
        for (j=1; j<=i; j++)
            if (numbers[j-1] > numbers[j])
			{
				temp = numbers[j-1];
				numbers[j-1] = numbers[j];
				numbers[j] = temp;
			}

	return(numbers[3]);	// the median value
}

// Median filtering routine.  Input is 7 measurements. Returns the median value.
int Median7i(int numbers __gc[])
{
	int i, j;
	unsigned short temp;

	// bubble sort the elements
	for (i=6; i>=0; i--)
        for (j=1; j<=i; j++)
            if (numbers[j-1] > numbers[j])
			{
				temp = numbers[j-1];
				numbers[j-1] = numbers[j];
				numbers[j] = temp;
			}

	return(numbers[3]);	// the median value
}
// Range routine. Determine range of middle 5 samples in a group of 7 samples.
// If the range is small, then the samples look like one another even if one
// of them is a glitch.
int Range(unsigned short data __gc[], int index)
{
	int i, j;
	unsigned short temp;
	unsigned short numbers[7];

	for (i=0; i<7; i++)			// make a local copy of the data
		numbers[i] = data[index + i];		// don't alter what was given to us

	// bubble sort the elements
	for (i=6; i>=0; i--)
        for (j=1; j<=i; j++)
            if (numbers[j-1] > numbers[j])
			{
				temp = numbers[j-1];
				numbers[j-1] = numbers[j];
				numbers[j] = temp;
			}

	return(numbers[5]-numbers[1]);	// the range of central samples
}


// DrawLine routines that checks and bounds points to within display rectangle.
// The gr->SetClip() function should do this, but certain values of arguments to DrawLine outside the
// clipped region cause it to throw an exception rather than clip. These routines fix that problem.
void DrawLineBound(System::Drawing::Graphics * gr, System::Drawing::Rectangle r,
				   System::Drawing::Pen * pen, int x1, int y1, int x2, int y2)
{
	if(x1 < r.X)			// bound x1, x2, y1, y2 within the rectangle r
		x1 = r.X;
	if(x1 > r.Right)
		x1 = r.Right;
	if(x2 < r.X)
		x2 = r.X;
	if(x2 > r.Right)
		x2 = r.Right;
	if(y1 < r.Y)
		y1 = r.Y;
	if(y1 > r.Bottom)
		y1 = r.Bottom;
	if(y2 < r.Y)
		y2 = r.Y;
	if(y2 > r.Bottom)
		y2 = r.Bottom;

	gr->DrawLine(pen, x1, y1, x2, y2);	// draw the bounded line
}
void DrawLineBound(System::Drawing::Graphics * gr, System::Drawing::Rectangle r,
				   System::Drawing::Pen * pen, System::Drawing::Point p1, System::Drawing::Point p2)
{
	DrawLineBound(gr, r, pen, p1.X, p1.Y, p2.X, p2.Y);	// draw the bounded line
}
void AddPolar(double& mag, double& phase, double magadd, double phaseadd)
{
	double x, y;

	x = mag * cos(phase*DEGR2RAD);
	y = mag * sin(phase*DEGR2RAD);

	x += magadd * cos(phaseadd*DEGR2RAD);
	y += magadd * sin(phaseadd*DEGR2RAD);

	mag = sqrt(x*x+y*y);
	phase = atan2(y,x) * RAD2DEGR;
}

// Convert MeasurementDelay string to target's loop count
int MeasureDelayStringToCount(String * value)
{

//	time delay is very roughly 30 usec + loopcount * 40 microseconds
//  Values other than "FAST" use the "SLOW" mode of the buffer

	if(String::Compare(value, S"Fast") == 0)
		return 0;
	if(String::Compare(value, S"30 us") == 0)
		return 0;
	if(String::Compare(value, S"100 us") == 0)
		return 2;
	if(String::Compare(value, S"300 us") == 0)
		return 6;
	if(String::Compare(value, S"1 ms") == 0)
		return 16;
	if(String::Compare(value, S"3 ms") == 0)
		return 48;
	if(String::Compare(value, S"10 ms") == 0)
		return 160;

	return 0;	// no delay if unexpected string 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -