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

📄 displayroutines.cpp

📁 USB 上位机程序 VNA使用,网络分析仪原理使用仪器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
				RxDet->DirIphs[i] = br->ReadInt32();
				RxDet->DirQphs[i] = br->ReadInt32();
				RxDet->DirMag[i] = br->ReadInt32();
			}

			// Read the Directional Coupler error terms 12-26-2005

			RxDet->CouplerPhase = br->ReadDouble();
			RxDet->CouplerMagnitude = br->ReadDouble();


		}
		catch(System::IO::IOException* pe)
		{
			MessageBox::Show(S"Error trying to load Detector Calibration File.\n\r"
				S"Delete the file:   detector.ica   and re-run Detector Calibration", pe->Message,
				MessageBoxButtons::OK, MessageBoxIcon::Error);


			return;
		}

		__finally
		{
			if (br)
				br->Close();
			if (fs)
				fs->Close();
		}

		RxDet->calibrated = true;		// loaded a valid detector calibration
		TxDet->calibrated = true;
		RxDet->DirCalibrated = true;
};
	/// Resolve reflected measured data set to Magnitude and Phase
void CalDataSet::ResolveReflPolar(int ReflPI, int ReflPQ, int ReflMQ, int Frequency, double& rmag, double& rphs,
			bool CouplerComp)
{
	double magnitude, phase;
//	double phasetwiddle;
//	double magtwiddle;
//	double magadd, phaseadd;


	phase = RxDet->IQtoDegrees(ReflPI, ReflPQ);
	magnitude = RxDet->MagTodBRefl(Frequency, ReflMQ);

	// phasetwiddle = double(Frequency)/1000000 * 0.013 * -magnitude;	// phase drift vs. magnitude

#ifdef COUPLERCAL
	if(CouplerComp)			// Subtract coupler V/I tracking error (in dB) if requested
	{
		double angle = RxDet->CouplerPhase - phase;
		if (angle >180.0)
			angle -= 360.0;
		if (angle < -180.0)
			angle += 360.0;
	
		magnitude += (RxDet->CouplerMagnitude *  sin(angle * DEGR2RAD));
	}
#endif

	magnitude = pow(10.0, (magnitude/20.0));		// translate db_return_loss to voltage ratio

	rphs = phase;			// return phase in degrees (-180..+180)
	rmag = magnitude;		// return linear magnitude (0..1)



// twiddle the phase by estimated amp-to-phase conversion
//	rphs += phasetwiddle;
// twiddle the mag to account for -3 dbm level
//rmag *= 1.414;



// New 10-17-2005 - adjust the reflected Magnitude and Phase by the Directivity Cal


	int FreqBase, FreqBaseNext;		// Two adjacent cal frequency points
	double FreqRemainder;			// remainder of freq between cal points
	int Freq = Frequency;

#ifdef DIRECTCAL

	if (RxDet->DirCalibrated)
		{
			// Result is frequency-dependent. Interpolate the frequency between two datasets to construct
			// a linear-frequency approximation of the cal data for the desired frequency.
			// Every 200 KHz from 200K to 1MHz, then every 10 MHz up to 120 MHz.
			// Index:  0    1    2    3    4    5    6    7    8   9   10   11   12   13   14   15   16   17    18    19 
			// Freq:  200k 300k 400k 500k 600k 700k 800k 900k 1M  10M  20M  30M  40M  50M  60M  70M  80M  90M  100M  110M 


			// Build interpolated dataset between two frequencies

			if (Freq <= 1000000)	// 1 MHZ and below
			{
				FreqBase = (Freq - 200000)/100000;
				FreqRemainder = (double)(Freq - (FreqBase + 2) * 100000)/100000;  // Remainder of frequency, value between  0..1
			}
			else if (Freq < 10000000)	// Between 1 and 10 MHz
			{
				FreqBase = 8;
				FreqRemainder = (double)(Freq - 1000000)/9000000;
			}
			else		// 10 MHz to 120 MHz
			{
				FreqBase = (Freq / 10000000) + 8;						// Base is the integer part of the frequency index
				FreqRemainder = (double)(Freq - (FreqBase - 8) * 10000000)/10000000;  // Remainder of frequency, value between  0..1
			}


			if (FreqRemainder < 0.001)
				FreqBaseNext = FreqBase;					// Prevent index overflow
			else
				FreqBaseNext = FreqBase + 1;


			int I, Q, M;		// Interpolate between Directivity Cal points
			
			I = RxDet->DirIphs[FreqBase] + (int)((RxDet->DirIphs[FreqBaseNext] - RxDet->DirIphs[FreqBase]) * FreqRemainder);
			Q = RxDet->DirQphs[FreqBase] + (int)((RxDet->DirQphs[FreqBaseNext] - RxDet->DirQphs[FreqBase]) * FreqRemainder);
			M = RxDet->DirMag[FreqBase] + (int)((RxDet->DirMag[FreqBaseNext] - RxDet->DirMag[FreqBase]) * FreqRemainder);

			double DirPhase = RxDet->IQtoDegrees(I, Q);
			double DirMagnitudedB = RxDet->MagTodBRefl(Frequency, M);
			double DirMagnitudeLin = pow(10.0, (DirMagnitudedB/20.0));		// translate db_return_loss to voltage ratio

			AddPolar(rmag, rphs, -DirMagnitudeLin, DirPhase);	// Subtract Directivity error from Reflection reading

		}	// End if calibrated
#endif


	if (rphs > 180.0)
		rphs -= 360.0;
	if (rphs < -180.0)
		rphs += 360.0;

	return;
}
	/// Resolve transmitted measured data set to Magnitude and Phase
void CalDataSet::ResolveTranPolar(int TranPI, int TranPQ, int TranMQHi, int TranMQLo, int TranMQMid, int Frequency, double& rmag, double& rphs)
{
	double magnitude, phase;

	phase = TxDet->IQtoDegrees(TranPI, TranPQ);
	magnitude = TxDet->MagTodBTran(Frequency, TranMQHi, TranMQLo, TranMQMid);

	// offset phase by 180 degrees for Trans measurements

	phase += 180.0;
	if (phase > 180.0)
		phase -= 360.0;
	if (phase < -180.0)
		phase += 360.0;


	magnitude = pow(10.0, (magnitude/20.0));		// translate db to voltage ratio

	rmag = magnitude;		// return linear magnitude (0..1)
	rphs = phase;			// return phase in degrees (-180..+180)
}

/// Construct Cal error terms from Cal raw data at each frequency point
void CalToErrorTerms(CalDataSet* Cal)
{
    for (int i=0; i<1024; i++)
	{
		std::complex<double> two(2.0, 0.0);
		std::complex<double> rslt(0.0, 0.0);
		
		double realpart, imagpart;

		realpart = Cal->S11shortReal[i];
		imagpart = Cal->S11shortImag[i];
        std::complex<double>	Sshort(realpart, imagpart);

		realpart = Cal->S11openReal[i];
		imagpart = Cal->S11openImag[i];
		std::complex<double> Sopen(realpart, imagpart);

		realpart = Cal->S11termReal[i];
		imagpart = Cal->S11termImag[i];
		std::complex<double> Sterm(realpart, imagpart);

		// Directivity error term
		Cal->EdReal[i] = Cal->S11termReal[i];
		Cal->EdImag[i] = Cal->S11termImag[i];

		// Source mismatch error term
		rslt = ((two * Sterm) - (Sshort + Sopen)) / (Sshort - Sopen);
		Cal->EsReal[i] = real(rslt);
		Cal->EsImag[i] = imag(rslt);

		// Tracking error term
		rslt = ((two * (Sopen - Sterm) * (Sshort - Sterm)) / (Sshort - Sopen));
		Cal->EtReal[i] = real(rslt);
		Cal->EtImag[i] = imag(rslt);
	}

};

/// Convert measured S11 into actual S11 via calibration
void CorrectS11(CalDataSet* Cal, int Frequency, double measmag, double measphs, double& rsltmag, double& rsltphs)
{
	// There are 1024 calibration frequencies, find the two adjacent to the measured frequency.
	// Linearly interpolate (real, imag) between the two cal points

	int i, j;
	double delta, position;
	double realpart, imagpart;

	delta = (MAXCALFREQ - MINCALFREQ)/ (NUMCALPTS - 1);		// frequency separation of cal points

	i = (int)(((double)Frequency - MINCALFREQ) / delta);	// Cal frequency directly below ours
	j = i+1;												// Cal frequency directly above ours
	if(j >= (int)NUMCALPTS)
		j = (int)NUMCALPTS - 1;								// In case we are close to MAX cal frequnecy

	position = (((double)Frequency - MINCALFREQ) / delta) - i ;	// fractional position between i and j

	// transform measured S11 into actual S11

	std::complex<double> rslt;

	realpart = Cal->EdReal[i] + ((Cal->EdReal[j] - Cal->EdReal[i]) * position); // interpolate
	imagpart = Cal->EdImag[i] + ((Cal->EdImag[j] - Cal->EdImag[i]) * position);
    std::complex<double>	Ed(realpart, imagpart);

	realpart = Cal->EsReal[i] + ((Cal->EsReal[j] - Cal->EsReal[i]) * position); // interpolate
	imagpart = Cal->EsImag[i] + ((Cal->EsImag[j] - Cal->EsImag[i]) * position);
    std::complex<double>	Es(realpart, imagpart);

	realpart = Cal->EtReal[i] + ((Cal->EtReal[j] - Cal->EtReal[i]) * position); // interpolate
	imagpart = Cal->EtImag[i] + ((Cal->EtImag[j] - Cal->EtImag[i]) * position);
    std::complex<double>	Et(realpart, imagpart);

	// Convert measured data to rectangular coordinates
    double measreal, measimag;
	double phase_radians = measphs * DEGR2RAD;
	measreal = measmag * cos(phase_radians);
	measimag = measmag * sin(phase_radians);
    std::complex<double>	S11meas(measreal, measimag);

	rslt = ((S11meas - Ed) / (Es * (S11meas - Ed) + Et));

	// Convert results to polar coordinates
	double x = real(rslt);
	double y = imag(rslt);

	double fphase = atan2(y, x) * RAD2DEGR;
	double fmagnitude = sqrt(x*x + y*y);

	rsltmag = fmagnitude;
	rsltphs = fphase;
}
/// Convert measured S21 into actual S21 via calibration
void CorrectS21(CalDataSet* Cal, int Frequency, double measmag, double measphs, double& rsltmag, double& rsltphs)
{
	// There are 1024 calibration frequencies, find the two adjacent to the measured frequency.
	// Linearly interpolate (real, imag) between the two cal points

	int i, j;
	double delta, position;
	double realpart, imagpart;

	delta = (MAXCALFREQ - MINCALFREQ)/ (NUMCALPTS - 1);		// frequency separation of cal points

	i = (int)(((double)Frequency - MINCALFREQ) / delta);	// Cal frequency directly below ours
	j = i+1;												// Cal frequency directly above ours
	if(j >= (int)NUMCALPTS)
		j = (int)NUMCALPTS - 1;								// In case we are close to MAX cal frequnecy

	position = (((double)Frequency - MINCALFREQ) / delta) - i ;	// fractional position between i and j

	realpart = Cal->ThReal[i] + ((Cal->ThReal[j] - Cal->ThReal[i]) * position);		// interpolate between calibration points
	imagpart = Cal->ThImag[i] + ((Cal->ThImag[j] - Cal->ThImag[i]) * position);

	// transform measured S21 into actual S21

	std::complex<double> rslt;
    std::complex<double>	Th(realpart, imagpart);

	// Convert measured data to rectangular coordinates
    double measreal, measimag;
	double phase_radians = measphs * DEGR2RAD;
	measreal = measmag * cos(phase_radians);
	measimag = measmag * sin(phase_radians);
    std::complex<double>	S21meas(measreal, measimag);

	rslt = S21meas / Th;

	// Convert results to polar coordinates
	double x = real(rslt);
	double y = imag(rslt);

	double fphase = atan2(y, x) * RAD2DEGR;
	double fmagnitude = sqrt(x*x + y*y);

	rsltmag = fmagnitude;
	rsltphs = fphase;
}
	/// Load Fixture Calibration Data Set
bool LoadCalDataSet(OpenFileDialog* infile, CalDataSet* Cal)
{
	FileStream* fs;
	BinaryReader* br;

	try
	{
		// Create a filestream & binary reader

		fs = new FileStream(infile->FileName, FileMode::Open, FileAccess::Read);
		br = new BinaryReader(fs);

			// Define header to match file identifying type and version

		String* recognized = new String(S"VNA Calibration Data Set Version 1.0.0");
		String* header;

		header = br->ReadString();		// get string header on infile
		if (String::Compare(recognized, header) != 0)
		{
			MessageBox::Show(
				S"CalDataSet file is incompatible type or version.\n\rExpecting Version 1.0.0",
				S"Error", MessageBoxButtons::OK, MessageBoxIcon::Error);
			br->Close();
			fs->Close();
			return false;
		}

		for (int i=0; i<1024; i++)		// read in the data set
		{
			Cal->EdReal[i] = br->ReadDouble();
			Cal->EdImag[i] = br->ReadDouble();
			Cal->EsReal[i] = br->ReadDouble();
			Cal->EsImag[i] = br->ReadDouble();
			Cal->EtReal[i] = br->ReadDouble();
			Cal->EtImag[i] = br->ReadDouble();
			Cal->ThReal[i] = br->ReadDouble();
			Cal->ThImag[i] = br->ReadDouble();
			// debug - load in the generating dataset
			Cal->S11openReal[i] = br->ReadDouble();
			Cal->S11openImag[i] = br->ReadDouble();
			Cal->S11shortReal[i] = br->ReadDouble();
			Cal->S11shortImag[i] = br->ReadDouble();
			Cal->S11termReal[i] = br->ReadDouble();
			Cal->S11termImag[i] = br->ReadDouble();
		}
		return true;
	}
	catch(System::IO::FileNotFoundException * pe)
	{
		MessageBox::Show(String::Concat(pe->Message,
			S"\n\n\rError trying to read Cal Data Set. The file cannot be found.\n\r"
			S"Load a valid Fixture Calibration file in order to enable Fixture Calibration."),
			S"Fixture Cal File Not Found", MessageBoxButtons::OK, MessageBoxIcon::Warning);
		return false;
	}
	catch(System::IO::IOException* pe)
	{
		MessageBox::Show(String::Concat(pe->Message,
			S"\n\n\rError trying to read Cal Data Set:\n\r", infile->FileName,
			S"\n\n\rEither the file is corrupted or the file version is incompatible.\n\r"
			S"Try creating a new Fixture Cal file, or Load a valid Fixture Calibration file\n\r"
			S"in order to enable Fixture Calibration."),
			S"Fixture Cal Data Error", MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
		return false;
	}
	__finally
	{
		if (br)
            br->Close();
        if (fs)
			fs->Close();
	}
}

	/// Save Fixture Calibration Data Set
void SaveCalDataSet(SaveFileDialog* outfile, CalDataSet* Cal)
{
	FileStream* fs;
	BinaryWriter* bw;

	try
	{
		// Create a filestream & binary writer

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

		// Define header to match file identifying type and version

		String* recognized = new String(S"VNA Calibration Data Set Version 1.0.0");

		bw->Write(recognized);		// put string header on outfile

		for (int i=0; i<1024; i++)		// write out the data set
		{
			bw->Write(Cal->EdReal[i]);
			bw->Write(Cal->EdImag[i]);
			bw->Write(Cal->EsReal[i]);
			bw->Write(Cal->EsImag[i]);
			bw->Write(Cal->EtReal[i]);
			bw->Write(Cal->EtImag[i]);
			bw->Write(Cal->ThReal[i]);
			bw->Write(Cal->ThImag[i]);

			// debug - also write out the measurements
			bw->Write(Cal->S11openReal[i]);
			bw->Write(Cal->S11openImag[i]);
			bw->Write(Cal->S11shortReal[i]);
			bw->Write(Cal->S11shortImag[i]);
			bw->Write(Cal->S11termReal[i]);
			bw->Write(Cal->S11termImag[i]);
		}
    }

⌨️ 快捷键说明

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