📄 instrumentcal.h
字号:
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 + -