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

📄 displayroutines.cpp

📁 USB 上位机程序 VNA使用,网络分析仪原理使用仪器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	for (freq = 0; freq<21; freq++)		// compute at each frequency index
	{
		sumx = 0; sumy = 0;
		sumxsq = 0; sumysq = 0; sumxy = 0;
		sumf = 0;

		for (level=0; level<26; level++)			// compute from 0 dbm to -25 dbm 
		{
            sumx += Mag[freq, level];
			sumy += -level;
			sumxsq += Mag[freq, level] * Mag[freq, level];
			sumysq += level * level;
			sumxy += Mag[freq, level] * -level;
		}
		m[freq] = (double)(n * sumxy - sumx * sumy) / (double)( n * sumxsq - sumx * sumx);
		b[freq] = (double)(sumy - m[freq] * sumx) / (double)n;
		r[freq] = (double)(n * sumxy - sumx * sumy) / sqrt((double)(n * sumxsq - sumx * sumx)* (n * sumysq - sumy * sumy));

		for (level=50; level<=59; level++)			// find count where detector curve flatens out
         	sumf += Mag[freq, level];				// Take average of bottom 10 level readings
		
		flat[freq] = (double)sumf/10.0;

		// 10-24-2005  Adjust 'b' (intercept) to align with 0 db.
		// b[freq] -=  m[freq] * Mag[freq, 0] + b[freq] - pow(10.0, ((flat[freq] + t1 - Mag[freq, 0]) / t2));
	}

		// Test whether the AmpCal results are good or poor from 500 KHz to 100 MHz

		for (freq=3; freq<19; freq++)
		{
			if(r[freq] < 0.92)		// poor correlation between cal measurememnts and detector model
				return(false);
		}
		return(true);				// good correlation

}
/// Convert VNA I/Q raw count readings to degrees
double Detector::IQtoDegrees(int I, int Q)
{
	double degrees;

	degrees = RAD2DEGR * atan2((double)(centerPhase - Q),(double)(I - centerPhase));
	if (degrees > 180.0)
		degrees -= 360.0;
	if (calibrated)
		degrees += pherror[(int)degrees+180];	// index to phase table is offset by 180 degrees

	// pherror could change degress to be outside the range -180 to +180 - wrap the phase

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

	return (degrees);

	//// find whether I or Q is closer to centerline
	//if (abs(I - centerPhase) < abs(Q - centerPhase))	// I is closer
	//{
	//	if (Q < centerPhase)
	//	    degrees = 90.0 - ((float)(I - centerPhase) / (float)(upperPhase - lowerPhase)) * 90.0;
	//	else
	//		degrees = -90.0 + ((float)(I - centerPhase) / (float)(upperPhase - lowerPhase)) * 90.0;
	//}
	//else		// Q is closer
	//{
	//	if (I < centerPhase)
	//		degrees = -quadratureError + 180.0 - ((float)(centerPhase - Q) / (float)(upperPhase - lowerPhase)) * 90.0;
	//	else
	//	    degrees = -quadratureError + ((float)(centerPhase - Q) / (float)(upperPhase - lowerPhase)) * 90.0;
	//}

}/// Convert detector magnitude count to dB. via piecewise linear fit
double Detector::MagTodBRefl(int Freq, int Mag)
	{
		double result;
		int FreqBase, FreqBaseNext;		// Two adjacent cal frequency points
		double FreqRemainder;			// remainder of freq between cal points
		double dBResultFLow, dBResultFHigh;	// Intermediate interpolation results

		if (calibrated)
		{
			// 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;


		// Mag is the S11 raw ADC count measured with +0 dbm Tx Level
		// Compute dbm from y = mx + b.  Coefficients previously derived from linear regression

		dBResultFLow = m[FreqBase] * Mag + b[FreqBase];
		dBResultFHigh = m[FreqBaseNext] * Mag + b[FreqBaseNext];

		// Tweak the bottom end of the reading for detector bottoming out.  Based on 'flat' and
		// emperically derived correction.

		dBResultFLow = dBResultFLow - pow(10.0, ((flat[FreqBase] + t1 - Mag) / t2));
		dBResultFHigh = dBResultFHigh - pow(10.0, ((flat[FreqBaseNext] + t1 - Mag) / t2));

        // interpolate result between FLow and FHigh

		result = dBResultFLow + (dBResultFHigh - dBResultFLow) * FreqRemainder;

		return(result);

		}
		else									// uncalibrated measurement
			return(((Mag-MAXTRANMAGNITUDE)/57.0));			// roughly 57 counts per dB
	}

/// Convert detector magnitude count to dB. via table lookup
double Detector::MagTodBTran(int Freq, int Mag0, int Mag34, int Mag17)
	{
//		bool	HotSig;					// TRUE = receiving hot signal, use Mag34
		double result;
		int FreqBase, FreqBaseNext;		// Two adjacent cal frequency points
		double FreqRemainder;			// remainder of freq between cal points
//		int Mag;
		double dBResultFLow, dBResultFHigh;	// Intermediate interpolation results
		const int t1 = 110;				// twiddle factors for detector floor correction
		const int t2 = 110;

		if (calibrated)
		{
			// 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 

			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;

		// V1.4 and previous algorithm

		// Mag0 is the S21 raw ADC count measured with +0 dbm Tx Level
		//    Use Mag0 when the loss of the load is greater than 40 db
		// Mag40 is the S21 raw ADC count measured with -40 dbm Tx Level
		//    Use Mag40 when the loss of the load is less than 40 db
		//
		// Some examples:
		//		Load has 0 db  loss: Mag0 = ~3500 overload		Mag34 = ~2900
		//		Load has 20 db loss: Mag0 = ~3800 overload		Mag34 = ~1900
		//		Load has 40 db loss: Mag0 = ~3000				Mag34 = ~870
		//		Load has 60 db loss: Mag0 = ~1900				Mag34 = ~870
		//		Load has 80 db loss: Mag0 = ~870				Mag34 = ~870
		//
		// So the algorithm is:  if Mag0 > ~3000, then use Mag43.  The value used is
		// when (m * Mag0 + b) > 3  Which is when Mag0 > -37 dbm.

		//if ((m[FreqBase] * Mag0 + b[FreqBase]) > 3.0)
		//{
		//	Mag = Mag34;				// use attenuated signal
		//	HotSig = true;
		//}
		//else
		//{
		//	Mag = Mag0;					// use unattenuated signal
		//	HotSig = false;
		//}

		//// Compute dbm from y = mx + b.  Coefficients previously derived from linear regression

		//dBResultFLow = m[FreqBase] * Mag + b[FreqBase];
		//dBResultFHigh = m[FreqBaseNext] * Mag + b[FreqBaseNext];

		//// Tweak the bottom end of the reading for detector bottoming out.  Based on 'flat' and
		//// emperically derived correction.

		//dBResultFLow = dBResultFLow - pow(10.0, ((flat[FreqBase] + t1 - Mag) / t2));
		//dBResultFHigh = dBResultFHigh - pow(10.0, ((flat[FreqBaseNext] + t1 - Mag) / t2));

		//// interpolate result between FLow and FHigh

		//result = dBResultFLow + (dBResultFHigh - dBResultFLow) * FreqRemainder;

		//if(!HotSig)
		//	 result -= 40.0;							// possibly make 40.0 a table value??
		//else
		//	// Using -34 as the Hot level (was -40)
		//	result -=6.0;

		//return(result);





// New algorithm for V1.5 - use Mag0 until resultant amplitude is > 0 db,
// then use Mag17 until it's resultant amplitude is > 0 db, then use Mag34


		// copy to local values so we can debug
		int Hi, Mid, Lo;
		Hi = Mag0, Mid = Mag17, Lo = Mag34;

		// Compute dbm from y = mx + b.  Coefficients previously derived from linear regression

		dBResultFLow = m[FreqBase] * Mag0 + b[FreqBase];
		dBResultFHigh = m[FreqBaseNext] * Mag0 + b[FreqBaseNext];

		// Tweak the bottom end of the reading for detector bottoming out.  Based on 'flat' and
		// emperically derived correction.

		dBResultFLow = dBResultFLow - pow(10.0, ((flat[FreqBase] + t1 - Mag0) / t2));
		dBResultFHigh = dBResultFHigh - pow(10.0, ((flat[FreqBaseNext] + t1 - Mag0) / t2));

        // interpolate result between FLow and FHigh

		result = dBResultFLow + (dBResultFHigh - dBResultFLow) * FreqRemainder;

		if(result <= 0)
			return(result-(double)TARGETLOMAG-6.0);


		// Compute dbm from y = mx + b.  Coefficients previously derived from linear regression

		dBResultFLow = m[FreqBase] * Mag17 + b[FreqBase];
		dBResultFHigh = m[FreqBaseNext] * Mag17 + b[FreqBaseNext];

		// Tweak the bottom end of the reading for detector bottoming out.  Based on 'flat' and
		// emperically derived correction.

		dBResultFLow = dBResultFLow - pow(10.0, ((flat[FreqBase] + t1 - Mag17) / t2));
		dBResultFHigh = dBResultFHigh - pow(10.0, ((flat[FreqBaseNext] + t1 - Mag17) / t2));

        // interpolate result between FLow and FHigh

		result = dBResultFLow + (dBResultFHigh - dBResultFLow) * FreqRemainder;

		if(result<= 0)
			return(result-(double)TARGETMIDMAG-6.0);

		
		// Compute dbm from y = mx + b.  Coefficients previously derived from linear regression

		dBResultFLow = m[FreqBase] * Mag34 + b[FreqBase];
		dBResultFHigh = m[FreqBaseNext] * Mag34 + b[FreqBaseNext];

		// Tweak the bottom end of the reading for detector bottoming out.  Based on 'flat' and
		// emperically derived correction.

		dBResultFLow = dBResultFLow - pow(10.0, ((flat[FreqBase] + t1 - Mag34) / t2));
		dBResultFHigh = dBResultFHigh - pow(10.0, ((flat[FreqBaseNext] + t1 - Mag34) / t2));

        // interpolate result between FLow and FHigh

		result = dBResultFLow + (dBResultFHigh - dBResultFLow) * FreqRemainder;

		return(result-6.0);

		}
		else												// uncalibrated measurement
			return(((Mag34-MAXTRANMAGNITUDE)/57.0) + 8.0);			// roughly 57 counts per dB

	}
	// New 10-17-2005 Directivity Cal
void Detector::DirectivityCal(int DirectivityMag __gc[,])  // Record directivity data
	{
		// Store the raw ADC counts from the Directivity Calibration
		// The consuming routine needs to convert them to mag+phase

		for (int i=0; i<21; i++)
		{
			DirMag[i] = DirectivityMag[i, 0];
			DirIphs[i] = DirectivityMag[i, 1];
			DirQphs[i] = DirectivityMag[i, 2];
		}
	}

/// CalDataSet Constructor - allocate memory for Calibration Data
CalDataSet::CalDataSet(String* StartUpDir)	
{
RxDet = new Detector();		// construct AD8702 objects
TxDet = new Detector();

EdReal = new double __gc[1024]; EdImag = new double __gc[1024];
EsReal = new double __gc[1024]; EsImag = new double __gc[1024];
EtReal = new double __gc[1024]; EtImag = new double __gc[1024];
ThReal = new double __gc[1024]; ThImag = new double __gc[1024];
S11shortReal = new double __gc[1024]; S11shortImag = new double __gc[1024];
S11openReal = new double __gc[1024]; S11openImag = new double __gc[1024];
S11termReal = new double __gc[1024], S11termImag = new double __gc[1024];

/// Try to read in the detector.ica file to pre-load the Detector calibration constants
/// If the file does not exist, warn user to run detector cal first

		FileStream* fs;
		BinaryReader* br;

		String * filename = String::Concat(StartUpDir, S"\\detector.ica");
		try
		{
			// Create a filestream & binary reader

			fs = new FileStream(filename, FileMode::Open, FileAccess::Read);
			br = new BinaryReader(fs);
		}
		catch(System::IO::IOException* pe)
		{
			MessageBox::Show(S"Detector Calibration File Not Found.\n\r"
				S"Be sure to run   Calibration->Detector Calibration...   first", pe->Message,
				MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
			if (br)
				br->Close();
			if (fs)
				fs->Close();
			return;
		}

		// Define header to match file identifying type and version

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

		header = br->ReadString();		// get string header on infile
		if (String::Compare(recognized, header) != 0)
		{
			MessageBox::Show(
				S"detector.ica file is incompatible type or version.\n\rExpecting Detector Version 2.0.2"
				S"\n\rRe-run Detector Calibration because the file format \n\rmay have been changed by a new software release",
				S"Error", MessageBoxButtons::OK, MessageBoxIcon::Error);
			br->Close();
			fs->Close();
			return;
		}

	
		// read in the AD8302 Phase Detector constants and error table

		try
		{
			RxDet->centerPhase = br->ReadInt32();
			RxDet->lowerPhase = br->ReadInt32();
			RxDet->upperPhase = br-> ReadInt32();
			for (int degree = 0; degree<360; degree++)
				RxDet->pherror[degree] = br->ReadDouble();

			TxDet->centerPhase = br->ReadInt32();
			TxDet->lowerPhase = br->ReadInt32();
			TxDet->upperPhase = br->ReadInt32();
			for (int degree = 0; degree<360; degree++)
				TxDet->pherror[degree] = br->ReadDouble();

			// Read in the AD8302 Amplitude Detector coefficient tables

			for (int FreqIdx=0; FreqIdx<21; FreqIdx++)
			{
				RxDet->m[FreqIdx] = br->ReadDouble();
				RxDet->b[FreqIdx] = br->ReadDouble();
				RxDet->r[FreqIdx] = br->ReadDouble();
				RxDet->flat[FreqIdx] = br->ReadDouble();
			}

			for (int FreqIdx=0; FreqIdx<21; FreqIdx++)
			{
				TxDet->m[FreqIdx] = br->ReadDouble();
				TxDet->b[FreqIdx] = br->ReadDouble();
				TxDet->r[FreqIdx] = br->ReadDouble();
				TxDet->flat[FreqIdx] = br->ReadDouble();
			}

			// Read in the Internal Crystal Frequency Error
			// Test the value to make sure it's within reasonable range.
			FreqError = br->ReadInt32();
			if (Math::Abs(FreqError) > 3000000)
				FreqError = 0;
	

			// Read in the directivity calibration raw values   10-18-2005
			for (int i=0; i<21; i++)
			{

⌨️ 快捷键说明

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