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

📄 instrumentcal.h

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

				progressBar1->Value = i;
				if(i%20 == 0)
					progressBar1->Update();
			}

			if(Cal->RxDet->PhaseCal(Iphase, Qphase))		// TRUE if cal sucessful
			{
				RxPhaseStat->Image = ICO1Label->Image;				// checkmark
				CalStepPass[0] = true;
			}
			else
			{
				RxPhaseStat->Image = ICO2Label->Image;				// 'x'
				CalStepPass[0] = false;
				ShowCalStepFailMessage();
			}

			RxPhaseStat->Visible = true;
		 }
		 /// Transmission Phase Detector Calibration button click handler
private: System::Void TxPhaseButton_Click(System::Object *  sender, System::EventArgs *  e)
		 {
			 // Transmission Phase Detector Calibration

			VNA_RXBUFFER *RxBuf = new VNA_RXBUFFER;
			VNA_TXBUFFER *TxBuf = new VNA_TXBUFFER;
			int Fdesired;

			progressBar1->Value = 0;

			// run a sweep of ~1024 points, calibrating Tx phase detector
			// skip really low frequencies and really high frequencies
			for (long i=0; i<1024; i++)
			{
				// Compute spot frequency

				Fdesired = Convert::ToInt32(200000.0+( i*(120000000.0-200000.0)/1024.0));

				TxBuf->TxAccum = FG->DDS(Fdesired);	
				TxBuf->IDAClevelHi = MAX_DDS_LEVEL;		// Max transmit level
				TxBuf->ReplyType = 0;
				TxBuf->MeasureDelay = 0;
				TxBuf->QDAClevel = QDAC_ZERODBM;	// Reference level

				// Take 7 readings at the same frequency
				for(int k=0; k<7; k++)
				{
                    VNA->WriteRead(TxBuf, RxBuf);
					BufferI[k] = RxBuf->TranPI;
					BufferQ[k] = RxBuf->TranPQ;
				}

				Iphase[i] = Median7i(BufferI);		// use median filter to smooth raw reading
				Qphase[i] = Median7i(BufferQ);

				progressBar1->Value = i;
				if(i%20 == 0)
					progressBar1->Update();
			}
		
			if(Cal->TxDet->PhaseCal(Iphase, Qphase))	// TRUE if phase cal was sucessful
			{
				TxPhaseStat->Image = ICO1Label->Image;				// checkmark
				CalStepPass[1] = true;
			}
			else
			{
				TxPhaseStat->Image = ICO2Label->Image;				// 'x'
				CalStepPass[1] = false;
				ShowCalStepFailMessage();
			}

			TxPhaseStat->Visible = true;
		 }

		 /// OK button click handler
private: System::Void OKbutton_Click(System::Object *  sender, System::EventArgs *  e)
		 {

			double mag, phase;
			double& rmag = mag;
			double& rphase = phase;
			double b1, b2;
			int Fdesired;
			int FreqIdx;

			 // Check that all relevant groups of data have been run, else
			 // display error message and give chance to rerun missing sets.

			for (int k = 0; k<NUMCALSTEPS; k++)
				if(CalStepPass[k] == false)
			{
				MessageBox::Show(S"Some calibration steps not completed or failed."
					S"  Be sure to complete all required steps before finishing."
					S"\n\rClose this window, then 'Cancel' if you do not wish to save Detector Cal data.",
					S"Error: Missing Steps", MessageBoxButtons::OK, MessageBoxIcon::Error);
				return;
			}


			// Normalize 'b'  in y = mx + b   for (ShortDB + OpenDB) / 2

			for (FreqIdx=0; FreqIdx<21; FreqIdx++)
			{

				// Compute spot frequency

				if (FreqIdx < 9)
					Fdesired = Convert::ToInt32((FreqIdx + 2) * 100000);	// every 100 KHz starting at 200 khz.
				else
					Fdesired = Convert::ToInt32((FreqIdx-8) * 10000000);	// every ten MHz.


                Cal->ResolveReflPolar(ReflMagPhOpen[FreqIdx, 1], ReflMagPhOpen[FreqIdx, 2],
					ReflMagPhOpen[FreqIdx, 0], Fdesired, rmag, rphase, false);
				b1 = 20.0 * log10(mag);	// convert to dB

                Cal->ResolveReflPolar(ReflMagPhShort[FreqIdx, 1], ReflMagPhShort[FreqIdx, 2],
					ReflMagPhShort[FreqIdx, 0], Fdesired, rmag, rphase, false);
				b2 = 20.0 * log10(mag);	// convert to dB

				Cal->RxDet->b[FreqIdx] -= (b1+b2)/2.0;		// 'b' value is halfway between open and short values
			}

			// Derive phase-angle dependent directional coupler error.  The model is a sine-wave error
			// with two terms: magnitude and phase-offset. Optimization criteria minimizes MSE
			// from the 1024-point Detector Shorted Calibration run by varying angle-offset and magnitude.
			// 0 db is the zero value for the MSE minimizer.
			// ReflDetailMagPhShort[,] contains the raw ADC readings from a 1024 point sweep

			double SquaredError = 1000000;	// 'large' error
			int PhaseEstimate;				// best estimate for models's phase offset
			double MagEstimate = 0.5;		// initial estimate for model's magnitude
			int angle;
			double error;
			double temp;
#define BEGINF	50							// Start MSE summation at about 5 MHz
#define ENDF	850							// Complete MSE summation at about 90 MHz

			// Search for phase-angle offset giving smallest MSE

			for (int offset = -180; offset< +180; offset++)	// Check over full range
			{
				// Compute Sum Squared Error

				error = 0;
				for(int j=BEGINF; j<ENDF; j++)
				{

					Fdesired = Convert::ToInt32(200000.0+( j*(120000000.0-200000.0)/1024.0));
					Cal->ResolveReflPolar(ReflDetailMagPhShort[j, 1], ReflDetailMagPhShort[j, 2],
						ReflDetailMagPhShort[j, 0], Fdesired, rmag, rphase, false);

					angle = (int)(phase - (double)offset);
					if (angle > 180)
						angle -= 360;
					if (angle < -180)
						angle += 360;

					temp = (20.0 * log10(mag)) - MagEstimate * sin(angle * DEGR2RAD);
					error += (temp * temp);
				}
				if (error < SquaredError)	// Save if it's the minimum (MSE)
				{
					SquaredError = error;
					PhaseEstimate = offset;
				}
			}

			// Search for magnitude giving smallest MSE at the just-determined offset angle

			SquaredError = 1000000;	// 'large' error
			for (double magnitude = 0.0; magnitude<1.2; magnitude += 0.01)	// Check over 0 to 1.2 dB
			{
				// Compute Sum Squared Error

				error = 0;
				for(int j=BEGINF; j<ENDF; j++)
				{

					Fdesired = Convert::ToInt32(200000.0+( j*(120000000.0-200000.0)/1024.0));
					Cal->ResolveReflPolar(ReflDetailMagPhShort[j, 1], ReflDetailMagPhShort[j, 2],
						ReflDetailMagPhShort[j, 0], Fdesired, rmag, rphase, false);

					angle = (int)(phase - (double)PhaseEstimate);
					if (angle > 180)
						angle -= 360;
					if (angle < -180)
						angle += 360;

					temp = (20.0 * log10(mag)) - magnitude * sin(angle * DEGR2RAD);
					error += (temp * temp);
				}
				if (error < SquaredError)	// Save if it's the minimum (MSE)
				{
					SquaredError = error;
					MagEstimate = magnitude;
				}
			}

			// Re-compute phase search with improved value of MagEstimate

			SquaredError = 1000000;	// 'large' error
			for (int offset = -180; offset< +180; offset++)	// Check over full range

				// BUGBUG - narrow the phase search range the second time around?

			{
				// Compute Sum Squared Error

				error = 0;
				for(int j=BEGINF; j<ENDF; j++)
				{

					Fdesired = Convert::ToInt32(200000.0+( j*(120000000.0-200000.0)/1024.0));
					Cal->ResolveReflPolar(ReflDetailMagPhShort[j, 1], ReflDetailMagPhShort[j, 2],
						ReflDetailMagPhShort[j, 0], Fdesired, rmag, rphase, false);

					angle = (int)(phase - (double)offset);
					if (angle > 180)
						angle -= 360;
					if (angle < -180)
						angle += 360;

					temp = (20.0 * log10(mag)) - MagEstimate * sin(angle * DEGR2RAD);
					error += (temp * temp);
				}
				if (error < SquaredError)	// Save if it's the minimum (MSE)
				{
					SquaredError = error;
					PhaseEstimate = offset;
				}
			}

			Cal->RxDet->CouplerPhase = PhaseEstimate;
			Cal->RxDet->CouplerMagnitude = MagEstimate;


			// Save Instrument Calibration values to detector.ica

			FileStream* fs;
			BinaryWriter* bw;

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

				fs = new FileStream(filename, FileMode::Create, FileAccess::Write);
				bw = new BinaryWriter(fs);
			}
			catch(System::Exception* pe)
			{
				MessageBox::Show(S"Error. Could not Write Detector Calibration file.", pe->Message,
					MessageBoxButtons::OK, MessageBoxIcon::Error);
				return;
			}

			// Define header to match file identifying type and version

			String* recognized = new String(S"VNA Detector Calibration Data Set Version 2.0.2");
			bw->Write(recognized);		// put string header on outfile

			// write the AD8302 Phase Detector constants and error tables
			bw->Write(Cal->RxDet->centerPhase);
			bw->Write(Cal->RxDet->lowerPhase);
			bw->Write(Cal->RxDet->upperPhase);
			for (int degree = 0; degree<360; degree++)
				bw->Write(Cal->RxDet->pherror[degree]);

			bw->Write(Cal->TxDet->centerPhase);
			bw->Write(Cal->TxDet->lowerPhase);
			bw->Write(Cal->TxDet->upperPhase);
			for (int degree = 0; degree<360; degree++)
				bw->Write(Cal->TxDet->pherror[degree]);

			// write the AD8302 Amplitude Detector tables

			for (int i=0; i<21; i++)
			{
                bw->Write(Cal->RxDet->m[i]);
                bw->Write(Cal->RxDet->b[i]);
                bw->Write(Cal->RxDet->r[i]);
				bw->Write(Cal->RxDet->flat[i]);
			}
			
			for (int i=0; i<21; i++)
			{
                bw->Write(Cal->TxDet->m[i]);
                bw->Write(Cal->TxDet->b[i]);
                bw->Write(Cal->TxDet->r[i]);
				bw->Write(Cal->TxDet->flat[i]);
			}

			// write the frequency error (or zero if none entered)

			bw->Write(FG->Ferror);

			// Write the Directivity Calibration raw values 10-18-2005

			for (int i=0; i<21; i++)
			{
				bw->Write(Cal->RxDet->DirIphs[i]);
				bw->Write(Cal->RxDet->DirQphs[i]);
				bw->Write(Cal->RxDet->DirMag[i]);
			}

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

			bw->Write(Cal->RxDet->CouplerPhase);
			bw->Write(Cal->RxDet->CouplerMagnitude);

			fs->Flush();
			fs->Close();

			DialogResult = DialogResult::OK;		// Close the form
		 }


		 /// Transmission Amplitude Detector Calibration button click handler
private: System::Void TxLowAmpButton_Click(System::Object *  sender, System::EventArgs *  e)
		 {
			
			// Transmission Amplitude detector Calibration - with 40 dB attenuator in path
			 
			VNA_RXBUFFER *RxBuf = new VNA_RXBUFFER;
			VNA_TXBUFFER *TxBuf = new VNA_TXBUFFER;
			int Fdesired;

			TxBuf->ReplyType = 0;
			TxBuf->MeasureDelay = 0;		    // No delay
			TxBuf->QDAClevel = QDAC_ZERODBM;	// Reference level

⌨️ 快捷键说明

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