// HP35601A test program // GPIB ADDR #15 (HP35601A) // Dr. Simon Schroedle, Started: Jan 18, 2014 // #include "ni4882.h" #include #include #include #define M_E 2.71828182845904523536 #define M_LOG2E 1.44269504088896340736 #define M_LOG10E 0.434294481903251827651 #define M_LN2 0.693147180559945309417 #define M_LN10 2.30258509299404568402 #define M_PI 3.14159265358979323846 #define M_PI_2 1.57079632679489661923 #define M_PI_4 0.785398163397448309616 #define M_1_PI 0.318309886183790671538 #define M_2_PI 0.636619772367581343076 #define M_1_SQRTPI 0.564189583547756286948 #define M_2_SQRTPI 1.12837916709551257390 #define M_SQRT2 1.41421356237309504880 #define M_SQRT_2 0.707106781186547524401 int Device35601 = 0; /* Device unit descriptor */ int Device3585 = 0; /* Device unit descriptor */ int Device3562 = 0; /* Device unit descriptor */ int PrimaryAddress3562 = 12; /* Primary address of the device */ int SecondaryAddress3562 = 0; /* Secondary address of the device */ int PrimaryAddress35601 = 15; /* Primary address of the device */ int SecondaryAddress35601 = 0; /* Secondary address of the device */ int PrimaryAddress3585 = 11; /* Primary address of the device */ int SecondaryAddress3585 = 0; /* Secondary address of the device */ int BoardIndex = 0; /* Interface Index (GPIB0=0,GPIB1=1,etc.) */ void GpibError(const char * msg); /* Error function declaration */ double tracedata[14][1020]; //final data to plot double traceparameters[30]; //various parameters of trace char tracetexts[10][40]; //various trace texts char caltexts[10][40]; //various cal text double calparameters[30]; //various parameters that are not cal constants double Caldata[8][6]; //current cal data int P82_C[11][1012]; //first 10 segments, 1 to 10 is used, segment 0 unused int P85_C[14][1012]; //correction offsets calculated by Phioffs int P82[11][1012]; //first 10 segments, 1 to 10 is used, segment 0 unused int P85[14][1012]; //sements 11 to 13; -4 to 1000 index; //original index "-3" P85[][1007] is valid data flag, 0:invalid; 1: valid //original index "-2" P85[][1008] stopbin //original index "-1" P85[][1009] startbin //original index "0" P85[][1010] Hzpbin (/250, *10) double fac[]={1.0,10.0,100.0,1000.0,10000,100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000}; double FROUND(double x, unsigned int digits) { //round t a fixed number of decimals return round(x*fac[digits])/fac[digits]; } double frand(void) { return ((float)rand()/((float)(RAND_MAX)+1.0)); } double FNPround(double Xi,double Round) { double X,Det,Y; X=Xi; if (Round>0) { X=trunc(X); Det=fmod(X,pow(10,Round)); X=trunc(X / pow(10,Round)); X=X*pow(10,Round); if (Det>=(5*pow(10,(Round-1)))) { X=X+(1*pow(10,Round));} } if (Round==0) { Det=fmod(X,1); X=trunc(X); if ((Det*10)>=5) { X=X+1;} } if (Round<0) { Y=fmod(X,1); X=trunc(X); Y=Y/pow(10,Round); Det=fmod(Y,1); Y=trunc(Y); if (Det>=0.5) {Y=Y+1;} X=X+(Y*pow(10,Round)); } return X; } double FNMax(double a1, double a2) //return max value of set of values { double t; t=a1; if (a2>a1) {t=a2;} return t; } double FNMin(double a0, double a1) //return min value of set of values { double t; t=a0; if (a10) {return 1.0;} if (t==0) {return 0.0;} } double DROUND(double num, int n) { //round to a fixed number of significant digits double d,magnitude; int power; long shifted; if(num == 0) { return 0; } d = ceil(log10(num < 0 ? -num: num)); power = n - (int) d; magnitude = pow(10, power); shifted = round(num*magnitude); return shifted/magnitude; } char latchd[20]={0,0x80,1,0x80,2,0x80,3,0x80,4,0x80,5,0x80,6,0x80,7,0x80,8,0x80,9,0x80}; //latch data latchd[0]=latch 0 latchd[1]=bit latch 0 usw., 0x80 set indicates bit data, 0x80 clear latch select void zerolatch(void)//preset 35601 latches { int i; for (i=1;i<20;i=i+2) { latchd[i]=0x80; } } void writelatch(void) { ibwrt(Device35601, latchd, 20); //write all latch data if (Ibsta() & ERR) { GpibError("ibwrt Error"); } } void CError(const char *msg) //error handler for 35601A unknown command { printf("\n!! Command error: %s\n",msg); exit(1); } void PError(const char *msg) //error handler for incorrect parameter { printf("\n!! Parameter error: %s\n",msg); exit(1); } /* ! RELAY LATCH LATCH 0,1 18560 ! # BIT 18570 ! K1 2 3 INPUT TO FILTERS, AMP 18580 ! K2 1 6 CAL ON 18590 ! K3 1 2 TG TO CAL PATH 18600 ! K4 1 2 SAME AS K3 18610 ! K5 0 5 ARMSTRONG OFF, TG ON 18620 ! K6 0 3 TG TO PLL 18630 ! K7 0 7 TG ON 18640 ! K8 4 7 2MHZ LF FILTER 18650 ! K9 4 7 SAME AS K8 18660 ! K10 4 3 SIGNAL TO PLL CKTS 18670 ! K11 2 7 AMP IN 18680 ! K12 2 5 FILTERS, AMP TO OUTPUT 18690 ! K13 1 4 1.5 GHZ MIXER, 18 GHZ MIXER 18700 ! K14 2 7 SAME AS K11 18710 ! ------------------------ 18720 ! SWITCH LATCH LATCH 18730 ! # BIT 18740 ! S1 9 6 3582A NOISE SOURCE TO SUM 18750 ! S2 1 1 TRACKING GEN TO SUM AMP 18760 ! S3 0 4 PLL CLOSED 18770 ! S4 0 6 SEARCH ON 18780 ! S5 2 6 SUM (xfer fn) TO 3582A 18790 ! S6 2 2 VCO CONTROL TO 3582A 18800 ! S7 3 1 X100 AMP TO 3582A 18810 ! S8 3 3 3585A 50 OHM TO 3582A 18820 ! ----------------------- 18830 ! SWITCH 86 94 18840 ! 18850 ! F0 0 0 100KHZ FILTER, LF BOARD 18860 ! F1 0 1 1KHZ FILTER 18870 ! F2 1 1 10HZ FILTER 18880 ! ----------------------- 18890 ! SWITCH LATCH LATCH 18900 ! # BIT 18910 ! L0 9 3 3582 NOISE INTO CHAN A 18920 ! L1 8 5 HF BOARD INTO LF BOARD 18930 ! L2 8 7 AC COUPLING 18940 ! L3 7 5 AC/DC FROM HF BOARD INTO CHANNEL B 18950 ! L4 7 1 LF PM X5 INTO CHANNEL B 18960 ! L5 9 5 LF PM X20 INTO CHANNEL B (ACTIVE LOW) 18970 ! L6 7 4 LF AM X5 INTO CHANNEL B 18980 ! L7 9 1 LF AM X5 INTO CHANNEL B 18990 ! L8 7 2 LF AM X20 INTO CHANNEL A 19000 ! L9 7 6 HF LOCK/OVERLOAD MONITOR INTO CHAN A 19010 ! L10 7 3 LF AM X20 INTO X5 19020 ! L11 8 3 LF 0=BANDPASS FILTER, 1=X2.5 AMP 19030 ! L12 9 2 LF PM X20 TO PHASE LOCK CONTROL 19040 ! L13 8 4 LF 0=EXTERNAL 10 MHZ, 1=VCXO TO SYNTH 19050 ! L14 8 1 LF SYNTH CONTROL 0=370 KHZ, 1=350 KHZ 19060 ! L15 8 2 LF PHASE LOCK CTRL 0=ADAPT, 1=WIDEBND 19070 ! L16 7 7 LF 3582 NOISE INTO PM X20 19080 ! L17 6 7 ARMSTRONG AM MODULATED 19090 ! L18 6 6 ARMSTRONG PM MODULATED 19100 ! L19 0 1 10 MHZ TO ARMSTRONG MODULATOR 19110 ! L20 0 2 10 MHZ TO LF BOARD 19120 ! L21 3 2 LF PHASE LOCK CTRL, 0=ADAPT,1=N BAND 19130 ! ----------------------- */ const char k_v[40]={0,0,2,3,1,6,1,2,1,2,0,5,0,3,0,7,4,7,4,7,4,3,2,7,2,5,1,4,2,7,0,9,0,9,0,9,0,9,0,9}; const char s_v[20]={0,9,9,6,1,1,0,4,0,6,2,6,2,2,3,1,3,3,0,9}; //const char f_v[20]={8,6,9,4,9,4,0,9,0,9,0,9,0,9,0,9,0,9,0,9}; const char l_v[44]={9,3,8,5,8,7,7,5,7,1,9,5,7,4,9,1,7,2,7,6,7,3,8,3,9,2,8,4,8,1,8,2,7,7,6,7,6,6,0,1,0,2,3,2}; /* 22050 ! DAC LATCH LATCH 22060 ! BITS # BIT 22070 ! 0 5 1 22080 ! 1 4 5 22090 ! 2 4 6 22100 ! 3 4 4 22110 ! 4 5 3 22120 ! 5 5 5 22130 ! 6 5 4 22140 ! 7 5 2 22150 ! POS DAC 3 7 22160 ! NEG DAC 4 2 22170 ! ---------------- 22180 ! GAIN1 22190 ! BIT 22200 ! 0 5 7 4 dB STEPS 22210 ! 1 5 6 22220 ! 2 6 2 22230 ! ---------------- 22240 ! GAIN2 22250 ! BIT 22260 ! 0 6 1 2 dB STEPS 22270 ! 1 6 4 22280 ! 2 6 3 22290 ! ---------------- 22300 ! LEAD LAG 22310 ! BIT 22320 ! 0 3 6 22330 ! 1 6 5 22340 ! 2 9 7 22350 ! ---------------- 22360 ! ATTEN1 22370 ! BIT 22380 ! 0 1 7 x.1 0 dB 22390 ! 1 2 4 x.2 6 dB 22400 ! 2 1 5 x.5 14 dB 22410 ! 3 1 3 x1 20 dB 22420 ! ---------------- 22430 ! ATTEN2 22440 ! BIT 22450 ! 0 3 4 x.5 6 dB (1),x1 0 dB (0) 22460 ! ---------------- */ const char dac_v[16]={5,1,4,5,4,6,4,4,5,3,5,5,5,4,5,2}; //bits 0 to 7 const char dacpos_v[2]={3,7}; const char dacneg_v[2]={4,2}; const char gain1_v[6]={5,7,5,6,6,2}; // 4 db steps,0 to 28 db (7*4db=28) ; bits 0 to 2, same for others const char gain2_v[6]={6,1,6,4,6,3}; // 2 db steps, 6 to 20 db (7*2db=14db, 14db+6db=20db) const char leadlag_v[6]={3,6,6,5,9,7}; const char atten1_v[8]={1,7,2,4,1,5,1,3}; //.1, .2, .5, 1 ; 4 steps; 0/6/14/20 valid numbers (dB) const char atten2_v[2]={3,4}; //set: .5, clear:1.; 2 steps; 0/6 valid numbers (dB) #define NOCOMMAND 0 //writes latch, but no command. #define OVERLOAD 1 #define OUTOFLOCK 2 #define TOGGLEACDC 3 const char delimiters[] = " ,;:"; //command delimiters; use "," as default static char token_s[255]; //just in case if needed for some error handling static char cp_s[255]; void setup_i(const char *commands) { int k_nr,tcnt; char tc,clearl; char *token; char *cp; cp=cp_s; token=token_s; strcpy(cp,commands); // printf("command length: %i\n",strlen(cp)); token = strtok (cp, delimiters); tcnt=0; //count tokens do { tcnt++; //printf("%i >%s<\n",tcnt,token); tc=token[0]; if (tc==45) { clearl=1; } else{ clearl=0;} tc=token[clearl]; if (tc=='K') //handle relais { k_nr=atoi(token+1+clearl); if ((k_nr>0)&&(k_nr<15)) { if (clearl) { latchd[(k_v[k_nr<<1]<<1)+1] &= ~(1<<(k_v[(k_nr<<1) + 1]-1));} else { latchd[(k_v[k_nr<<1]<<1)+1] |= 1<<(k_v[(k_nr<<1) + 1]-1); } } else { CError(token); } } else if (tc=='S') { k_nr=atoi(token+1+clearl); if ((k_nr>0)&&(k_nr<9)) { if (clearl) { latchd[(s_v[k_nr<<1]<<1)+1] &= ~(1<<(s_v[(k_nr<<1) + 1]-1));} else {latchd[(s_v[k_nr<<1]<<1)+1] |= 1<<(s_v[(k_nr<<1) + 1]-1);} } else { CError(token); } } else if (tc=='F') { k_nr=atoi(token+1); if ((k_nr>=0)&&(k_nr<3)) { if (k_nr==0) //100 khz { latchd[(8<<1)+1] &= ~(1<<(6-1)); // latch 8 bit 6 latchd[(9<<1)+1] &= ~(1<<(4-1)); // latch 9 bit 4 printf("LPF set to 100 kHz.\n"); } if (k_nr==1) //1 khz { latchd[(8<<1)+1] &= ~(1<<(6-1)); latchd[(9<<1)+1] |= (1<<(4-1)); printf("LPF set to 1 kHz.\n"); } if (k_nr==2) //10 hz { latchd[(8<<1)+1] |= (1<<(6-1)); latchd[(9<<1)+1] |= (1<<(4-1)); printf("LPF set to 10 Hz.\n"); } } else { CError(token); } } else if (tc=='L') { k_nr=atoi(token+1+clearl); if ((k_nr>=0)&&(k_nr<22)) { if (clearl) { latchd[(l_v[k_nr<<1]<<1)+1] &= ~(1<<(l_v[(k_nr<<1) + 1]-1));} else {latchd[(l_v[k_nr<<1]<<1)+1] |= 1<<(l_v[(k_nr<<1) + 1]-1);} } else { CError(token); } } else {CError(token);} token = strtok (NULL, delimiters); } while (token!=NULL); writelatch(); //latch setzen } void toggle_i(int codei) { switch (codei) { case NOCOMMAND: writelatch(); break; case OVERLOAD: latchd[9] |= 0x01; //overload writelatch(); latchd[9] &= ~(0x01); writelatch(); //printf("overload reset OK\n"); break; case OUTOFLOCK: latchd[7] |= 0x10; //out of lock writelatch(); latchd[7] &= ~(0x10); writelatch(); //printf("out of lock reset OK\n"); break; case TOGGLEACDC: setup_i("-L2"); setup_i("L2"); wait_s01(5); break; default: CError("Invalid TOGGLE command."); } } #define NOVALUE 0x00 //updates latch from valued and sets latch #define DAC 0x01 #define DACPOS 0x02 #define DACNEG 0x03 #define GAIN1 0x04 #define GAIN2 0x05 #define LEADLAG 0x06 #define ATTEN1 0x07 #define ATTEN2 0x08 char valued[9]={0,0,0,0,0,0,0,0,0}; //BIT data: empty, DAC, pos, neg, GAIN1, GAIN2, LEADLAG, ATTEN1, ATTEN2 void value_i(int codei,double valuei) { int c_t; int i_t; double value_t; switch (codei) { case NOVALUE: break; case DAC: value_t=valuei/0.045; //convert 11.475 Volt to 8 bit, resolution about 0.045 V if (value_t>=0) {i_t=(int)value_t;valued[DACPOS]=1;valued[DACNEG]=0;} else {i_t=(int)(-1*value_t); valued[DACPOS]=0;valued[DACNEG]=1;} if ((i_t>=0)&&(i_t<256)) { valued[DAC]=i_t; //printf("\n dac value: %i\n",i_t); } else {CError("Invalid DAC value");} break; case GAIN1: //0 to 28 db in 4 db steps i_t=(int) valuei; //printf("Gain1 %i",i_t); i_t=(i_t>>2)<<2; //make sure it is 4 db steps //printf("Gain1 v %i",i_t); if ((i_t>=0)&&(i_t<=28)) { valued[GAIN1]=i_t; //printf("\n GAIN1 value: %i\n",i_t); } else {CError("Invalid GAIN1 value");} break; case GAIN2: //6 to 20 in 2 db steps i_t=(int) valuei; i_t=(i_t>>1)<<1; //make sure it is 2 db steps if ((i_t>=6)&&(i_t<=20)) { valued[GAIN2]=i_t; //printf("\n GAIN2 value: %i\n",i_t); } else {CError("Invalid GAIN2 value");} break; case LEADLAG: //0 to 7 i_t=(int) valuei; if ((i_t>=0)&&(i_t<=7)) { valued[LEADLAG]=i_t; //printf("\n LEADLAG value: %i\n",i_t); } else {CError("Invalid LEADLAG value");} break; case ATTEN1: i_t=(int) valuei; if ((i_t!=0)&&(i_t!=6)&&(i_t!=14)&&(i_t!=20)) {CError("Invalid ATTEN1 value");} valued[ATTEN1]=i_t; break; case ATTEN2: i_t=(int) valuei; if ((i_t!=0)&&(i_t!=6)) {CError("Invalid ATTEN2 value");} valued[ATTEN2]=i_t; break; default: CError("Invalid VALUE command."); } //set latch values based on valuei data //DAC for (c_t=0;c_t<8;c_t++) { if ((valued[DAC]>>c_t)&0x01) {latchd[(dac_v[c_t<<1]<<1)+1] |= 1<<(dac_v[(c_t<<1) + 1]-1); //printf("value: %i, bit %i set\n",valued[DAC],c_t+1); } else {latchd[(dac_v[c_t<<1]<<1)+1] &= ~(1<<(dac_v[(c_t<<1) + 1]-1));} } if (valued[DACPOS]==0x01) { //printf("POSX %x\n",latchd[7]); latchd[(dacpos_v[0]<<1)+1] |= 1<<(dacpos_v[1]-1); //printf("POSY %x\n",latchd[7]); } else {latchd[(dacpos_v[0]<<1)+1] &= ~(1<<(dacpos_v[1]-1));} if (valued[DACNEG]==0x01) { //printf("NEGX %x\n",latchd[9]); latchd[(dacneg_v[0]<<1)+1] |= 1<<(dacneg_v[1]-1); // printf("NEGY %x\n",latchd[9]); } else {latchd[(dacneg_v[0]<<1)+1] &= ~(1<<(dacneg_v[1]-1));} //GAIN1 for (c_t=0;c_t<3;c_t++) { if ((valued[GAIN1]>>(c_t+2))&0x01) {latchd[(gain1_v[c_t<<1]<<1)+1] |= 1<<(gain1_v[(c_t<<1) + 1]-1);} else {latchd[(gain1_v[c_t<<1]<<1)+1] &= ~(1<<(gain1_v[(c_t<<1) + 1]-1));} } //GAIN2 for (c_t=0;c_t<3;c_t++) { if (((valued[GAIN2]-6)>>(c_t+1))&0x01) {latchd[(gain2_v[c_t<<1]<<1)+1] |= 1<<(gain2_v[(c_t<<1) + 1]-1);} else {latchd[(gain2_v[c_t<<1]<<1)+1] &= ~(1<<(gain2_v[(c_t<<1) + 1]-1));} } //leadlag for (c_t=0;c_t<3;c_t++) { if ((valued[LEADLAG]>>c_t)&0x01) {latchd[(leadlag_v[c_t<<1]<<1)+1] |= 1<<(leadlag_v[(c_t<<1) + 1]-1);} else {latchd[(leadlag_v[c_t<<1]<<1)+1] &= ~(1<<(leadlag_v[(c_t<<1) + 1]-1));} } //ATTEN1 if (valued[ATTEN1]==20) { latchd[(atten1_v[0]<<1)+1] |= 1<<(atten1_v[1]-1); } else {latchd[(atten1_v[0]<<1)+1] &= ~(1<<(atten1_v[1]-1));} if (valued[ATTEN1]==14) { latchd[(atten1_v[2]<<1)+1] |= 1<<(atten1_v[3]-1); } else {latchd[(atten1_v[2]<<1)+1] &= ~(1<<(atten1_v[3]-1));} if (valued[ATTEN1]==6) { latchd[(atten1_v[4]<<1)+1] |= 1<<(atten1_v[5]-1); } else {latchd[(atten1_v[4]<<1)+1] &= ~(1<<(atten1_v[5]-1));} if (valued[ATTEN1]==0) { latchd[(atten1_v[6]<<1)+1] |= 1<<(atten1_v[7]-1); } else {latchd[(atten1_v[6]<<1)+1] &= ~(1<<(atten1_v[7]-1));} //ATTEN2 if (valued[ATTEN2]==6) { latchd[(atten2_v[0]<<1)+1] |= 1<<(atten2_v[1]-1); } else {latchd[(atten2_v[0]<<1)+1] &= ~(1<<(atten2_v[1]-1));} writelatch(); //write all latch data to hp35601a } void print_i_setup(void) { double dacv; printf("\nHP35601A Setup:\n"); dacv=valued[DAC]*0.045; printf("\nDAC "); if (valued[DACNEG]==1) {dacv=-dacv; printf("NEG");} else {printf("POS");} printf(" %3i %.3f V (NEG/POS 0..255, -11.475..+11.475 V)\n",valued[DAC],dacv); printf("GAIN1 %2i dB (0-28 dB)\n",valued[GAIN1]); printf("GAIN2 %2i dB (6-20 dB)\n",valued[GAIN2]); printf("LEADLAG %i (0-7)\n",valued[LEADLAG]); printf("ATTEN1 %2i (0/6/14/20 dB)\n",valued[ATTEN1]); printf("ATTEN2 %i (0/6 dB)\n",valued[ATTEN2]); printf("\n"); } void wait_s01(int s01) //wait 100 ms intervals { clock_t ticks1, ticks2; ticks1=clock(); ticks2=ticks1; while((ticks2/(CLOCKS_PER_SEC/10)-ticks1/(CLOCKS_PER_SEC/10))(M_PI/2.0)) {Pole=M_PI/2.0;} Ang=-atan(W/W1)+atan(W/W2)-atan(W/W3)-M_PI/2.0-atan(0.5/W)-Pole; Fw=-10*log10(1+2*R*cos(Ang)+R*R); return Fw; } /* 11080 ! * NAME: Difcorrection 11086 ! * FUNCTION: Use a differential correction technique to determine 11089 ! * the correct values of W1 and Bw1 used by Fnw 11095 ! * INPUT: X(*), Y(*), W1, W2, W3, Bw1 11101 ! * OUTPUT: W1, Bw1, Maxpointerror */ double X[1050],Y[1050]; double W1,W2,W3,Bw1; double Maxpointerror; double Slope; void Difcorrection(int N) { double Sumslope; // !Sum of squares of slope double Sumfreq; // !Sum of freq correction needed double Corr; // !Freq correction term double Delta; // !Percent change to calculate derivitive double Error; // !Current error for one point double Errsum; // !Sum of all errors double Fw; // !F(w) -- loop correction factor double Fwhigh; // !F(High) double Fwlow; // !F(Low) double High; // !Higher point in search check int I; // !For-next loop counter double Loopbw3; // !Closed loop bandwidth int Loopcount; // !# of times correction loop is executed double Low; // !Lower point in search check // ! INTEGER N // !Number of data points to use in fit double Oldersum; // !Last Errsum value double Peaking; // !Amount of peaking in loop above predicted double Span; // !Frequency range to search for peak double W; // !Radial freq // ! Calculate initial guess for W1 by the amount of extra peaking needed //11170 No_look=0 !SET TO 1 TO LOOK AT DEBUG Loopbw3=Bw1*W3/W2; Span=10.0*M_PI*Loopbw3; Low=0.318197*Span+M_PI*Loopbw3/2.0; High=0.61803*Span+M_PI*Loopbw3/2.0; Fwlow=FNW(Low,1.0E+7,W2,W3,Bw1); Fwhigh=FNW(High,1.0E+7,W2,W3,Bw1); for (Loopcount=1;Loopcount<=8;Loopcount++) { Span=Span*0.61803; if (Fwlow0) {W1=2*M_PI*Loopbw3*(-1.1+6.33/Peaking+0.195/(Peaking*Peaking));} W1=FNMax(W1,2*M_PI*Loopbw3); printf("EXTRA PEAKING=%e\n",Peaking); // ! DEL printf("INITIAL W1=%e\n",W1); // ! DEL printf("W2=%e BW1=%e\n",W2,Bw1); // ! DEL Oldersum=0; Loopcount=0; //11272 Loop: ! for (Loopcount=1;Loopcount<=10;Loopcount++) { // ! Compute correction for W1 -- user-pole-freq Errsum=0; Sumfreq=0; Sumslope=0; for (I=1;I<=N;I++) { W=X[I]*2.0*M_PI; Fw=FNW(W,W1,W2,W3,Bw1); Delta=0.015+0.01*frand(); Slope=(FNW(W,W1+W1*Delta,W2,W3,Bw1)-Fw)/(W1*Delta); Error=Fw-Y[I]; Errsum=Errsum+fabs(Error); Sumslope=Sumslope+Slope*Slope; Sumfreq=Sumfreq-Slope*Error; } if (Errsum<0.04) {Loopcount=999;} // ! Return if total error small if (fabs(Oldersum-Errsum)<0.005) {Loopcount=999;} if (Loopcount<999) { Corr=Sumfreq/Sumslope; if (fabs(Corr)>W1) {Corr=fsgn(Corr)*W1/2.0;} W1=Corr+W1; // ! Compute correction for Bw1 -- open-loop-gain Maxpointerror=0; Errsum=0; Sumfreq=0; Sumslope=0; for (I=1;I<=N;I++) { W=X[I]*2*M_PI; Fw=FNW(W,W1,W2,W3,Bw1); Delta=0.015+0.01*frand(); Slope=(FNW(W,W1,W2,W3,Bw1+Bw1*Delta)-Fw)/(Bw1*Delta); Error=Fw-Y[I]; Maxpointerror=FNMax(Maxpointerror,fabs(Error)); Errsum=Errsum+fabs(Error); Sumslope=Sumslope+Slope*Slope; Sumfreq=Sumfreq-Slope*Error; } } if (Errsum<0.04) {Loopcount=999;} // ! Return if total error small if (Loopcount<999) { // ! Only allow corrections that are less than 1/4 the current value Corr=Sumfreq/Sumslope; if (fabs(Corr)>(Bw1/4.0)) {Corr=Bw1/4.0*fsgn(Corr);} Bw1=Corr+Bw1; Oldersum=Errsum; } }//loopcount //11422 Diffcorrret: ! printf("FINAL W1=%e\n",W1);// ! DEL printf("MAX ERROR IN DIFCORRECTION IS: %e\n\n",Maxpointerror); // ! DEL } double W,W5; /* 10783 ! * FUNCTION: Given a frequency, and other inputs, calculate the 10786 ! * correction factors needed. 10792 ! * INPUT: Amplifier, Vcoport, Mixerfreq, Caldata(*), W1, W2, W3, 10795 ! * Loopbw1, Phaseslope, Vcoslope, F 10801 ! * OUTPUT: Returns correction factor (Still needs Bandwidth and gain) */ double FNCalpoint(int Amplifier,int Vcoport,double Mixerfreq,double W1,double W2,double W3,double Loopbw1,double Phaseslope,double Vcoslope,double F) { double Cal; // !Total calibration for point int Calnum; // !Index into Caldata(*) for coeffecients double C1,C2,C3,C4,C5; // !Calibration coeffecients int I; // !Dummy variable in call to Getfreqparms int Index; // !Measurement index where data point would have been taken Getfreqparms(F,F,&I,&Index); C1=0; C2=0; C3=0; C4=0; C5=0; if (!(Vcoport)) { if (Mixerfreq<9.5E+7) { C1=Caldata[1][1]; C2=Caldata[1][2]; C3=Caldata[1][3]; C4=Caldata[1][4]; // !NO C5 FOR FILTER } if (Amplifier!=0) { if (Index<=4) { C1=C1+Caldata[2][1]+Caldata[2][2]*40.0+Caldata[2][3]*1600.0+Caldata[2][4]*64000.0+Caldata[2][5]/40.0; } else { if (Index==13) {Calnum=5;} if (Index==12) {Calnum=4;} if (Index==11) {Calnum=4;} if (Index<=10) {Calnum=3;} if (Index<=6) {Calnum=2;} C1=C1+Caldata[Calnum][1]; C2=C2+Caldata[Calnum][2]; C3=C3+Caldata[Calnum][3]; C4=C4+Caldata[Calnum][4]; C5=C5+Caldata[Calnum][5]; } } C1=C1+Caldata[7][1]+Caldata[6][1]; if (Index>10) { C2=C2+Caldata[7][2]+Caldata[6][2]; C3=C3+Caldata[7][3]+Caldata[6][3]; C4=C4+Caldata[7][4]+Caldata[6][4]; C5=C5+Caldata[7][5]+Caldata[6][5]; } } Cal=C5/F+C1+F*(C2+F*(C3+F*C4)); if (!((Phaseslope==0) & (Vcoslope==0))) { W5=2.0*M_PI*33500.0; W=2.0*M_PI*F; // ! IF PHASESLOPE=0 THEN THIS IS A DISCRIMINATOR MEASUREMENT if (Phaseslope==0) { Cal=Cal+20.0*log10(Vcoslope)-20.0*log10(F); } if (Vcoport & (Phaseslope!=0)) { Cal=Cal+20.0*log10(Vcoslope)-20.0*log10(F)+10.0*log10((1+(W/W5)*(W/W5))*(1+(W/W2)*(W/W2))/(1+(W/W3)*(W/W3))); } if ((!Vcoport) & (Phaseslope!=0)) { Cal=Cal-20.0*log10(Phaseslope)-FNW(W,W1,W2,W3,Loopbw1); } if (Index<=2) {Cal=Cal+10.0*log10(1+1/(W*W));} // ! NOTE: Cal still needs bandwidth and gain (if amp in) corrections } return Cal; } void w3585(char *buf) { //printf("Command: >%s<\n",buf); //printf("Length: %i bytes\n",strlen(buf)); ibwrt(Device3585, buf, strlen(buf)); //write all latch data if (Ibsta() & ERR) { GpibError("ibwrt Error"); } } void w3585d(char *buf) //for debug only { printf("Command: >%s<\n",buf); printf("Length: %i bytes\n",strlen(buf)); ibwrt(Device3585, buf, strlen(buf)); //write all latch data if (Ibsta() & ERR) { GpibError("ibwrt Error"); } } void r3585(int cnt) { ibrd(Device3585, Buffer, cnt); //read if (Ibsta() & ERR) { GpibError("ibrd Error"); } } void rd3585(void) { unsigned char tbuf[2004]; int i; ibrd(Device3585, tbuf, 2004); //read if (Ibsta() & ERR) { GpibError("ibrd Error"); } for (i=0;i<=1002;i++) { Display3585[i]=(tbuf[2*i]<<8)+tbuf[2*i+1]; } } void autorange85(void) { char tbuf[10]; int checkcount; int rangenum; printf("3585A: autorange85\n"); w3585("RLDV AL0 AL1 SV4 R01"); do { wait_s01(1); w3585("D6T4"); r3585(2); stat=Buffer[0]; // printf("D6 Status: 0x%02X\n",stat&0xff); } while ((stat&0x03)==0x03); rangenum=0; do { rangenum++; sprintf(tbuf,"R%02d",rangenum); w3585(tbuf); toggle_i(OUTOFLOCK); checkcount=0; do { w3585("D6T4"); r3585(2); stat=Buffer[0]; checkcount++; } while (((stat&0x01)==0x01)&&(checkcount<51)); } while ( (rangenum<12) && ((stat&0x01)==0x01)); rangedbv=rangenum*5-43; printf("rangenum: %d\n",rangenum); printf("rangedbv: %d\n",rangedbv); } double Approxfreq,Newfreq; void getbeatnote(void) { int Binn; //Binn number of beatnote int Crossingcount; //Number of zero crossings on 3582A display int Endbinn; //Binn # of last zero crossing double Freq; //Freq of beatnote int I; //For-next loop counter int Lastbin; //Bin number of latest zero crossing int Maxx; //Max of 3585A display, level needed // on 3582A time record to be valid int Minn; //Min level needed on 3582A time record int Numcycles; //Number of cycles on 3582A time record int Order[4]; //The order in which freq spans are checked int Rangenum; //Freq range to be searched int Sign; //Sign of last 3582A display binn int Startbin; //Binn # of first zero crossing int stat; //Status of instrument double T; //Number of seconds in time record int frange; //currently tested range char tbuf[30]; printf("getbeatnote... "); Newfreq=0; Order[1]=1; Order[2]=2; Order[3]=3; if ((Approxfreq<=85000) && (Approxfreq>100)) { Order[1]=2; Order[2]=1; Order[3]=3; } if (Approxfreq<=100) { Order[1]=3; Order[2]=2; Order[3]=1; } frange=1; do { Rangenum=Order[frange]; if (Rangenum<3) { w3585("CN0 FA0HZ PR S2"); if (Rangenum==1) { w3585("FB40MZ RB10KZ S2");} if (Rangenum==2) { w3585("FB85KZ RB300HZ S2");} do { w3585("D6T4"); r3585(2); stat=Buffer[0]; } while ((stat&0x80)==0x80); //wait until sweep complete w3585("C5CLSABOTB0"); rd3585(); Binn=2; Maxx=Display3585[2]; for (I=3;I<=1000;I++) { if (Display3585[I]>=Maxx) { Binn=I; Maxx=Display3585[I]; } //printf("%2u:%2X ",I,Display3585[I]&0xffff); } //printf("Maxx %u\n",Maxx); if (Maxx>=900) //sufficiently large signal found { sprintf(tbuf,"MK%dCN1 S3 RBUP D2 T6",Binn); //printf("%s\n",tbuf); w3585(tbuf); //printf("Read Frq..."); wait_s01(5); r3585(12); Buffer[12]=0x00; // printf(">%s<\n",Buffer); Freq=atof(Buffer); w3585("TA0"); if ((Binn>2)&&(Freq>=100.0)) {Newfreq=Freq;} //printf("%d\n",Binn); //printf("%f\n",Freq); //printf("New: %f\n",Newfreq); } } //end ranges 1 and 2 = 3585a ranges; need to implement 3562a ranges frange++; } while ((frange<=3) && (Newfreq<2)); printf("beat frequency found [Hz]: %8.1f\n",Newfreq); } void Phi(int I,int Numelem,double *X,double *X1) { int K; //printf("call phi %d %d\n",I,Numelem); switch (I) { case 1: for (K=1;K<=Numelem;K++) { X1[K]=(1); } break; case 2: for (K=1;K<=Numelem;K++) { X1[K]=(X[K]); } break; case 3: for (K=1;K<=Numelem;K++) { X1[K]=(X[K]*X[K]); } break; case 4: for (K=1;K<=Numelem;K++) { X1[K]=(X[K]*X[K]*X[K]); } break; case 5: for (K=1;K<=Numelem;K++) { X1[K]=(1/X[K]); } break; } } double FNDot(int Numelem,double *E,double *F) { int I; double Total; //printf("call FNDot\n"); Total=0; for (I=1;I<=Numelem;I++) { Total=Total+E[I]*F[I]; } return Total; } void curvefit(double *X,double *Y,int Numelem,int N,double *C1,double *C2,double *C3,double *C4,double *C5) //Numelem: number of x, y elements; N number of coefficients { int I,J,K; double C[5]; double Element; double X1[100],X2[100],Temp[5][10],V[5],B[5][5]; // ! Compute normal equations //printf("Fit1\n"); for (I=1;I<=N;I++) { Phi(I,Numelem,X,X1); for (J=1;J<=N;J++) { Phi(J,Numelem,X,X2); B[I][J]=FNDot(Numelem,X1,X2); B[J][I]=B[I][J]; } V[I]=FNDot(Numelem,X1,Y); } // !MAT INVERSE GAUSS JORDAN REDUCTION //printf("Fit2\n"); for (I=1;I<=N;I++) { for (J=1;J<=N;J++) { Temp[I][J]=B[I][J]; Temp[I][N+J]=0; //!INIT IDENTITY } Temp[I][I+N]=1; } // !DO DIAG //printf("Fit3\n"); for (I=1;I<=N;I++) { Element=Temp[I][I]; for (K=1;K<=2*N;K++) { Temp[I][K]=Temp[I][K]/Element; } // !SET ELEMENTS OF COL=0 for (K=1;K<=N;K++) { if ((K-I)!=0) { Element=Temp[K][I]; for (J=1;J<=2*N;J++) { Temp[K][J]=Temp[K][J]-(Element*Temp[I][J]); } } } } //printf("Fit4\n"); for(I=1;I<=N;I++) { for (J=1;J<=N;J++) { B[I][J]=Temp[I][J+N]; } } //printf("Fit5\n"); // !INVERSE FINISHED for (I=1;I<=N;I++) { C[I]=0; for (J=1; J<=N; J++) { C[I]=C[I]+B[I][J]*V[J]; } } //printf("Fit6\n"); *C1=C[1]; *C2=C[2]; *C3=C[3]; *C4=C[4]; if (N==4) { *C5=0; } else { *C5=C[5]; } } double Vrangemax; // !Maximum allowable voltage tuning range double Vrangemin; // !Minimum allowable voltage tuning range double Vrange; // !voltage tuning range double Vnom; // nominal tuning voltage double Atten1; // !Setting of attenuator 1 double Atten2; // !Setting of attenuator 2 double Atten1db; // !Setting of attenuator 1 double Atten2db; // !Setting of attenuator 2 double Gain1; // !Setting of Gain1 (dB) double Gain2; // !Setting of Gain2 (dB) double Mixerfreq; //input frequency double Userfrange; //frequency tuning range of user osc double Vcoslope; double Rin; double Fbeatnote,Vbeatnote; //this is the setting used for the phase slope determination //values are set by getvcoslope function double Vnom_new; //suggested Vnom if zero beat too far off initial Vnom; double Lockvoltage; //lock voltage void getvcoslope(void) { double B1,B2,B3,B4,B5; // !Coeffecients from least-squares fit double C1,C2,C3,C4,C5; // !Coeffecients from least-squares fit double Currentfreq; // !Present value of beatnote freq double Deltaf; // !Maximum freq change between beatnotes double Deltav; // !Control voltage step size double F0; // !Freq intercept (Freq at 0 volts) double Favg; // !Average of 4 freqs double F1linear; // !Linear approximation of Frequency(1) double F4linear; // !Linear approximation of Frequency(4) double Freq; // !Freq of user's oscillator double Maxfbeatnote; // max beatnote freq char tbuf[20]; int Rangenum; int Trialcount; double Voltage[10],Voltagea[10],Voltagen[10]; double Frequency[10],Frequencyn[10],Frequency2[10]; double V,Vlower,Vupper,dacv,Vavg; double Lin, Lin2, Linslope; double Total; int i,j; int Maxindex; Vnom_new=Vnom; Deltav=Vrange*0.30; if ((Mixerfreq>=9.5E+7) && (Userfrange>5.0E+7)) { Deltav=Deltav*(5.0E+7/Userfrange);} if ((Mixerfreq<9.5E+7) && (Userfrange>=2.E+6)) { Deltav=Deltav*(2.E+6/Userfrange);} Deltav=0.045*Atten1*(Deltav / (0.045*Atten1)); Deltav=FNMax(0.045*Atten1,Deltav); Deltaf=100000; Maxfbeatnote=200000; if (Mixerfreq>=9.5E+7) { Maxfbeatnote=4.E+6;} ibclr(Device3585); // Clear the 3585 if (Ibsta() & ERR) { GpibError("ibclr Error"); } Rangenum=(int)((rangedbv+13+4)/5+6); //! +4 IS FOR ROUNDING sprintf(tbuf,"SV4R%02d",Rangenum); w3585(tbuf); toggle_i(OVERLOAD); Vcoslope=0.0; Trialcount=0; Freq=4.0E+7; // ! Step thru 4 voltages and get frequencies Vlower=Vnom-1.5*0.045*Atten1*((Deltav+0.5*0.045*Atten1)/(0.045*Atten1)); Vupper=Vnom+1.5*Deltav; // printf("lower: %0.3f upper: %0.3f step: %0.3f \n",Vlower, Vupper, Deltav); for(V=Vlower;V<=Vupper;V=V+Deltav) { if (Vcoslope==0.0) { // printf("Set dac: %0.3f\n",V/Atten1); value_i(DAC,V/Atten1); } if (Vcoslope==0.0) { Approxfreq=Freq+Deltaf; getbeatnote(); Freq=Newfreq; } if (Vcoslope!=0.0) { Freq=fabs(Vcoslope*(V-Vnom)); } //IF Abortflag=1 THEN Abortvcoslope if (Freq!=0) { Trialcount++; if (Trialcount==2) {Deltaf=Freq+Frequency[1];} Voltage[Trialcount]=V; Frequency[Trialcount]=Freq; dacv=valued[DAC]*0.045*Atten1; if (valued[DACNEG]==1) {dacv=-dacv; } Voltagea[Trialcount]=dacv; //actual DAC output voltage printf("Trial %d: Voltage: %0.3f actual Voltage: %0.3f Frq: %0.1f\n",Trialcount,V,dacv,Freq); } }//end of for loop if (Trialcount==4) { printf("Calculating VCO slope... "); Vavg=0; for (i=1;i<=4;i++) { Vavg+=Voltagea[i]; } Vavg=Vavg/4; //average voltage for (i=1;i<=4;i++) { Voltagen[i]=Voltagea[i]-Vavg; } Favg=0; for (i=1;i<=4;i++) { Favg+=Frequency[i]; } Favg=Favg/4; //average frequency for (i=1;i<=4;i++) { Frequencyn[i]=Frequency[i]-Favg; } // printf("%0.3f avg v; %0.3f avg f\n",Vavg,Favg); Lin=99999; for (i=1;i<=4;i++) { Frequency2[i]=Frequency[i]; // printf("Frq #%d: %0.3f n=%0.3f\n",i,Frequency[i],Frequencyn[i]); } for (i=0;i<4;i++) //reverse sign starting from lowest frequency, check for lowest lin dev { if (i!=0) { Frequency[i]=-Frequency[i]; //succesively reverse sign } Linslope=(Frequency[2]-Frequency[3])/(Voltagen[2]-Voltagen[3]); if (Linslope!=0.0) { F0=Frequency[2]-Linslope*Voltagen[2];// ! Get y-intercept (b=y-mx) F1linear=Linslope*Voltagen[1]+F0; //! Get predicted value for f1 F4linear=Linslope*Voltagen[4]+F0; //! Get predicted value for f4 Favg=(Frequency[2]+Frequency[3])/2; if (!((Favg==F1linear) | (Favg==F4linear) | (Favg==Frequency[1]) | (Favg==Frequency[4]))) { Lin2=fabs(log10(fabs((Frequency[1]-Favg)/(F1linear-Favg)))); Lin2=Lin2+fabs(log10(fabs((Frequency[4]-Favg)/(F4linear-Favg)))); //printf("%0.3f\n",Lin2); if (Lin2<=Lin) { Lin=Lin2; for (j=1;j<=4;j++) { Frequency2[j]=Frequency[j]; } } } } } for (i=1;i<=4;i++) { // printf("#%d: DAC Voltage: %8.3f Frequency: %12.3f\n",i,Voltagea[i],Frequency2[i]); } printf("Fitting...\n"); curvefit(Voltagen,Frequency2,4,4,&C1,&C2,&C3,&C4,&C5); for (i=1;i<=4;i++) { Frequency[i]=Frequency2[i]; } //Mat1(Voltagen(*),"+",Vavg,1,4) ! Restore original voltages //Voltagea has actual DAC voltages //Voltagen has voltagea - avg voltage if (Lin>.30) { printf("ERROR: Tuning curve is not linear! Lin parameter (0.3 max): %0.3f\n",Lin); } // ! Calculate Vcoslope at the tuning curve center voltage (Vnom) Vcoslope=(C2+2*C3*(Vnom-Vavg)+3*C4*(Vnom-Vavg)*(Vnom-Vavg))*Atten1; printf("VCO slope of current system (Hz vs. DAC Voltage): %0.4f Hz/V\n",Vcoslope); // ! Check to see if the total frequency tuning range is < .2 Hz if (Vrange*2*fabs(Vcoslope)/Atten1<0.2) { printf("ERROR: Tuning range less than 0.2 Hz!\n"); } Rin=600.0; //VCO input impedance; 35601A has 50 ohm output impendace. printf("Expected VCO slope (Hz vs. VCO input voltage, 600 Ohm): %0.4f Hz/V\n",Vcoslope*((Rin+50)/Rin)/Atten1); Total=0; // calculate avg freq for (i=1;i<=4;i++) { Total=Total+Frequency[i]; } Favg=Total/4; for (i=1;i<=4;i++) { Frequencyn[i]=Frequency[i]-Favg; } printf("Calculate lock point...\n"); for (i=1;i<=4;i++) { // printf("#%d: DAC Voltage: %8.3f avg. Frequency: %12.3f\n",i,Voltagea[i],Frequencyn[i]); } curvefit(Frequencyn,Voltagea,4,4,&B1,&B2,&B3,&B4,&B5); // ! Calculate the predicted Lock voltage and retune if it is // ! not within 15% of the total tuning range (Vnom +-.15*Vrange) // printf("Vavg: %f\n",Vavg); // printf("Favg: %f\n",Favg); Lockvoltage=B1+B2*(-Favg)+B3*(-Favg)*(-Favg)+B4*(-Favg)*(-Favg)*(-Favg); if ((Lockvoltage>(Vnom+0.15*Vrange)) | (Lockvoltage<(Vnom-.15*Vrange)) ) { printf("!! Warning: predicted lock voltage is not within 15%% of the total\\n"); printf(" tuning range, Vnom+-0.15*Vrange!\n"); Vnom_new=0.045*Atten1*((Lockvoltage+0.0225*Atten1*fsgn(Lockvoltage)) / (0.045*Atten1)); printf("!! Suggested Vnom = %0.3f Volt\n\n",Vnom_new); } //Lockvoltage=0.1; // ! Calculate the Vcoslope at the predicted lock point Vcoslope=fabs((C2+2*C3*(Lockvoltage-Vavg)+3*C4*(Lockvoltage-Vavg)*(Lockvoltage-Vavg))*Atten1); printf("Lock point, %e DAC Volt, VCO SLOPE = %e Hz/Volt\n",DROUND(Lockvoltage,3),DROUND(Vcoslope/Atten1,4)); // ! Find the maximum vco frequency < Maxfbeatnote (Fbeatnote) and it's // ! DAC voltage (Vbeatnote). This will be used to measure Phase Slope. Maxindex=1; if (fabs(Frequency[4])>fabs(Frequency[1])) {Maxindex=4;} Fbeatnote=Frequency[Maxindex]; if (fabs(Fbeatnote)>Maxfbeatnote) {Fbeatnote=Maxfbeatnote*fsgn(Fbeatnote);} Vbeatnote=0.045*((B1+B2*(Fbeatnote-Favg)+B3*(Fbeatnote-Favg)*(Fbeatnote-Favg)+B4*(Fbeatnote-Favg)*(Fbeatnote-Favg)*(Fbeatnote-Favg)) / 0.045); Fbeatnote=fabs(FNPround(C1+C2*(Vbeatnote-Vavg)+C3*(Vbeatnote-Vavg)*(Vbeatnote-Vavg)+C4*(Vbeatnote-Vavg)*(Vbeatnote-Vavg)*(Vbeatnote-Vavg),-3)); printf("Beat note at %e DAC Volt, Freq = %e Hz\n",DROUND(Vbeatnote,3),DROUND(Fbeatnote,4)); } else { printf("VCO slope could not be determined. Check setup/select other voltage range.\n"); } } int Mixer; double Mindac; double Stfq,Spfq; double Vswing; int Numsam; double Maxfreq; void getuserparms(void)//this checks parameters and set up oscillator related variables { Vrange=1.8;//+- voltage range Vnom=0.1;//center voltage of tuning curve Mixer=1; //1: 5 MHz to 1.6 GHz; 2: 1.2 to 18 GHz; 3: External 0.02 to 40.1 MHz Mixerfreq=28.8e6;//phase detector frequency Userfrange=1.0e6; //user total freq tuning range if (Mixerfreq>=9.5E+7) {Maxfreq=4.0E+7;} if (Mixerfreq<9.5E+7) {Maxfreq=1.E+6;} if ((Vnom>10.0)|(Vnom<-10.0)) { PError("Vnom out of range, use -10 to 10 Volts"); } Vrangemax=12-fabs(Vnom); if (fabs(Vnom)<=2) {Vrangemax=10.035;} Vrangemin=0.18; if (fabs(Vnom)>0.765) {Vrangemin=0.36;} if (fabs(Vnom)>1.395) {Vrangemin=0.99;} if (fabs(Vnom)>3.96) {Vrangemin=1.98;} Vrange=fabs(Vrange); if ((VrangeVrangemax)) { PError("Tuning range error!"); } if ((Vrange+fabs(Vnom))>12) { PError("Center voltage+tuning range must be in -12 to 12 Volt range!"); } Vswing=fabs(Vrange)+fabs(Vnom); Atten1=0.1; Atten1db=20; if (Vswing>1.2) {Atten1=0.2;Atten1db=14;} if (Vswing>2.4) {Atten1=0.5;Atten1db=6;} if (Vswing>6) {Atten1=1.0;Atten1db=0;} Mindac=0.045*Atten1; Vnom=Mindac*(floor(FNPround(Vnom/Mindac,-10))); Vrange=Mindac*(floor(FNPround(Vrange/Mindac,-10))); Vswing=fabs(Vrange)+fabs(Vnom); Atten1=0.1; Atten1db=20; if (Vswing>1.2) {Atten1=0.2;Atten1db=14;} if (Vswing>2.4) {Atten1=0.5;Atten1db=6;} if (Vswing>6) {Atten1=1.0;Atten1db=0;} Mindac=0.045*Atten1; Vnom=Mindac*(floor(FNPround(Vnom/Mindac,-10))); Vrange=Mindac*(floor(FNPround(Vrange/Mindac,-10))); printf("Center voltage of tuning curve: %0.3f Volt\n",Vnom); printf("Voltage tuning range: +- %0.3f Volt\n",Vrange); Atten2=1; Atten2db=0; if (Vrange<=(5*Atten1)) {Atten2=0.5; Atten2db=6.0;} if (Userfrange>1.0e6) { printf("Total frequency tuning range (user defined): %0.3f\n",Userfrange); } if (Userfrange<=1.0e6) { printf("Total frequency tuning range (user defined): less than or equal 1 MHz!\n"); } switch (Mixer) { case 1: printf("Internal 5 MHz to 1.6 GHz mixer used.\n"); if ((Mixerfreq<4.9e6)|(Mixerfreq>1600e6)) { PError("Frequency must be in 4.9 MHz to 1600 MHz range. Check frequency or select other mixer!"); } break; case 2: printf("Internal 1.2 to 18 GHz mixer used.\n"); if ((Mixerfreq<1200e6)|(Mixerfreq>18000e6)) { PError("Frequency must be in 4.9 MHz to 1600 MHz range. Check frequency or select other mixer!"); } break; case 3: printf("External mixer. Connect mixer IF port to 35601A SIGNAL INPUT port.\n"); break; default: PError("No mixer selected!"); break; } printf("Phase detector input frequency: %0.1f Hz\n",Mixerfreq); Stfq=25000;//start freq Spfq=1e6;//stop freq Stfq=DROUND(Stfq,5); Spfq=DROUND(Spfq,5); if (Spfq<=Stfq) {printf("!!Error: Stop frequeny must be greater than start frequency!\n");} Numsam=1;//number of averages if ((Numsam<1)|(Numsam>999)) {printf("!!Error: Number of sample must be in range of 1 to 999!\n");} } //this version modified for 3562a fft analyzer! void Getfreqparms(double Beginfreq,double Endfreq, int *Beginindex,int *Endindex) { if (Endfreq<=4) {*Endindex=3;} //lowest index for 3562a if (Endfreq>4) {*Endindex=4;} if (Endfreq>10) {*Endindex=5;} if (Endfreq>40) {*Endindex=6;} if (Endfreq>100) {*Endindex=7;} if (Endfreq>400) {*Endindex=8;} if (Endfreq>1000) {*Endindex=9;} if (Endfreq>4000) {*Endindex=10;} if (Endfreq>25000) {*Endindex=11;} //3585a indices if (Endfreq>500000) {*Endindex=12;} if (Endfreq>5e6) {*Endindex=13;} if (Beginfreq<4) {*Beginindex=3;} //index 3 is lowest index for 3562a if (Beginfreq>=4) {*Beginindex=4;} if (Beginfreq>=10) {*Beginindex=5;} if (Beginfreq>=40) {*Beginindex=6;} if (Beginfreq>=100) {*Beginindex=7;} if (Beginfreq>=400) {*Beginindex=8;} if (Beginfreq>=1000) {*Beginindex=9;} if (Beginfreq>=4000) {*Beginindex=10;} if (Beginfreq>=25000) {*Beginindex=11;} //3585a indices if (Beginfreq>=500000) {*Beginindex=12;} if (Beginfreq>=5e6) {*Beginindex=12;} } //3562a has 801 bins! int P[14][3]={{0,0,0}, //entry seg 0 data are startbin stopbin and fmax {0,0,0}, //entry seg 1 {0,0,0}, //entry seg 2 {4,800,4}, //seg 3 is lowest used for 3562a {320,800,10}, //4 {200,800,40}, //5 {320,800,100}, //6 {200,800,400}, //7 {320,800,1000}, //8 {200,800,4000}, //9 {128,800,25000}, //10 {50,1000,50}, // 11 (SEGS 11-13 HAVE FMAX/10000) {100,1000,500}, // 12 {125,1000,4000} // 13 }; //these are indices -2, -1, 0 to initialize P85 and P82 //new indices are 1008 1009 1010 int Amplifier=1; //K11 amplifier in or out int AutoK11=1; //K11 amplifier out if overload int Oldfilter=-1; int Startindex,Stopindex; void getdata(void) //perform actual data taking for a phase noise measurement { int Rangenum; int Reflevel85; int Start85; int Stop85; int Index85; char tbuf[100]; int SRQstate; char SerialPollResponse ; int Spectrum[1050]; int I; for(I=11;I<=13;I++) { P85[I][1007]=0;//this is the data valid flag P85[I][1008]=P[I][0]; P85[I][1009]=P[I][1]; P85[I][1010]=P[I][2]; } for(I=1;I<=10;I++) { P82[I][1007]=0;//this is the data valid flag P82[I][1008]=P[I][0]; P82[I][1009]=P[I][1]; P82[I][1010]=P[I][2]; } if (Maxfreq<=1e6) {P85[12][1009]=200;} //limit 3585a to 2 MHz if 2 MHz filter is in. //** if (Amplifier==1) {setup_i("K11");} else {setup_i("-K11");} //** setup_i("K10,K12,S8,L1,L2,L3"); //set up for measurement wait_s01(20); toggle_i(OUTOFLOCK); autorange85(); if (rangedbv>=-3) { printf("!!Warning: High noise power! Consider removing amplifer to avoid compression!\n"); if (AutoK11==1) { setup_i("-K11,S8"); printf("Note AutoK11: K11 amp has been removed to avoid compression!\n"); Amplifier=0; autorange85(); } } Rangenum=(rangedbv+13)/5+6; Reflevel85=rangedbv; Rangenum=FNMax(1,Rangenum-2); // ! Down range by 10 dB ibclr(Device3585); // Clear the 3585 if (Ibsta() & ERR) { GpibError("ibclr Error"); } wait_s01(3); sprintf(tbuf,"AL0SV4R12RL%dDVR%02d",Reflevel85,Rangenum); w3585(tbuf); //setup 3585a //**missing: check if locked Getfreqparms(Stfq,Spfq,&Startindex,&Stopindex); //Sweepflag=0; // ! Get start and stop indexes for 3582A and 3585A // Start82=0 Start85=0; // Stop82=0 Stop85=0; // IF Startindex<=10 THEN Start82=Startindex // IF Startindex<=10 THEN Stop82=FNMin(10,(Stopindex)) if (Startindex<11) {printf("!!Error: Freq index too low; not yet supported! Start index set to 11!\n");} if (Stopindex>=11) {Start85=FNMax(11,(Startindex));} if (Stopindex>=11) {Stop85=Stopindex;} Index85=Stop85; // ! Set up 3585A to take measurement w3585("PRRLDVAR0FA0HZMK1001S2D2"); if (Index85==13) {w3585("C1 FB40MZ RB30KZ VB100HZ ST20SC RC4SV4");} if (Index85==12) {w3585("C1 FB5MZ RB10KZ VB30HZ ST20SC RC4SV4");} if (Index85==11) {w3585("C1 FB500KZ RB1KZ VB10HZ ST50SC RC4SV4");} w3585("T5"); //3517 Segment85loop: ! loop here until sweep done (SRQ) //3520 Phioff(P85(*),Index85,Vcoindex,Measuretype,Amplifier,Mixerfreq,Caldata(*),W1,W2,W3,Loopbw1,Phaseslope,Vcoslope,Vcofreq) //3529 Seg85waitloop: ! // sprintf(tbuf,"SV4R%02d",Rangenum); // w3585(tbuf); printf("3585A start index: %d\n",Start85); printf("3585A stop index: %d\n",Stop85); do {//index85 loop printf("waiting for 3585A data at index %d...\n",Index85); do { TestSRQ(BoardIndex,&SRQstate); //printf("%d",SRQstate&0x01); wait_s01(5); } while (!(SRQstate&0x01)); TestSRQ(BoardIndex,&SRQstate); //printf("%d",SRQstate&0x01); //printf ( "Device asserted SRQ.1\n" ); ibrsp ( Device3585, &SerialPollResponse); //TestSRQ(BoardIndex,&SRQstate); //printf("%d",SRQstate&0x01); //printf ( "SRQ cleared.2\n" ); w3585("C5 CL SA TB0 BO"); rd3585();//read data into Display3585 variable for (I=0;I<=1000;I++) { Spectrum[I]=(Display3585[I+1]);//first point is always 0xffff //if (I<15) {printf("%d: %u\n",I,Spectrum[I]);} } Spectrum[1000]=Spectrum[1000]&(int)1023; for (I=0;I<=1005;I++) { Spectrum[I]=10*(Reflevel85-100)+Spectrum[I]; //if (I<5) {printf("%d: %d\n",I,Spectrum[I]);} } // ! SPECTRUM now contains raw spectrum data *10 for (I=0;I<=1000;I++) { P85[Index85][I]=Spectrum[I]; // tracedata[Index85][I]=((double)Spectrum[I])/10.0; } P85[Index85][1007]=1; //valid trace // tracedata[Index85][1007]=1.0; //valid trace Index85=Index85-1; //**missing: check if still locked if (Index85==13) {w3585("C1 FB40MZ RB30KZ VB100HZ ST20SC RC4SV4");} if (Index85==12) {w3585("C1 FB5MZ RB10KZ VB30HZ ST20SC RC4SV4");} if (Index85==11) {w3585("C1 FB500KZ RB1KZ VB10HZ ST50SC RC4SV4");} w3585("D2T5"); //start next sweep } while (Index85>=Start85); } /* 11884 ! * NAME: Phaseslope 11887 ! * 11890 ! * FUNCTION: Measure the phase slope of the beatnote from the mixer. 11893 ! * 11896 ! * INPUT: Voltage, Atten1, Freq, Mixerfreq, Caldata(*), Rangedbv, Amplifier 11899 ! * OUTPUT: Phaseslope, Vpeak ! If Measuretype=0 then this routine is used to measure Phase Slope. 11986 ! The formula used to calculate phase slope is: 11989 ! 11992 ! 2^.5 * (V0 - 3*V1 + 5*V2 - 7*V3 + 9*V4 ...) 11995 ! V0-Vx are rms values of each harmonic component 11998 ! 12001 ! Cutoffamp designates minimum levels that each 12004 ! harmonic must be greater than to be of significance. 12007 ! 12010 ! Phaseslope can be in error if there is a significant amount of 12013 ! dc offset from the mixer. This is taken into account by the 12016 ! term COS( ASN( Mixerdc/V0 )). 12019 ! 12022 ! If Measuretype#0 then this routine is used to measure the amplitude of the 12025 ! input signal. No harmonics are needed so Fmax is set to 12028 ! twice the expected frequency. */ double Cutoffamp[19]={0.0,-100.0,0.0, -49.5,0.0,-54.0, 0.0,-57.0,0.0, -59.0,0.0,-61.0, 0.0,-62.3,0.0, -63.5,0.0,-64.7,0.0}; // !Amplitude rel to peak where harmonic becomes insignificant double Phaseslope; double Mixerdc; double Vpeak; void Getphaseslope(double Voltage,double Freq, int Measuretype,int Caltype) { int Binc; // !For-next loop counter int Binn; // !Approximate display bin of response double Famp; // !Amplitude of particular freq double Famp1; // !Amplitude of fundamental double Fb; // !Maxfreq on 3585A span double Fmax; // !Max freq needed to measure phaseslope double Fullscale; // !Reflevel of 3582A int Harmonic; // !Harmonic number being checked double Hzpbin; // !Hz per display bin int Maxbin; // !Bin # of max response int Maxx; // !Value of max response double Mixerdc1; // !Total dc in path double Mixerdc2; // !Residual dc in path int Numharmonics; // !Number of harmonics to be checked int Rangenum; // !Range number of 3585A int Sens; // !Sensitivity setting of 3582A double Sign; // !Sign of current harmonic value to be added int Span; // !Span number of 3582A int Stat; // !Result of STATUS read of instrument char tbuf[100]; int I; int Display[1050]; int Minbinnt; double FNCp; printf("measuring phase slope...\n"); Mixerdc=0; if (Measuretype==0) { value_i(DAC,Voltage/Atten1);} //set beat note toggle_i(OVERLOAD); Fmax=Freq*10.0; if ((Measuretype==2) | (Measuretype==1) & (Caltype!=2)) { Fmax=Freq*2.0; // ! DISCRIMINATOR OR QUADRATURE CAL } if (Freq>=2500) //3585a used if >=2.5 khz { ibclr(Device3585); // Clear the 3585 if (Ibsta() & ERR) { GpibError("ibclr Error"); } wait_s01(3); Rangenum=(int)((rangedbv+13+4)/5+5);// !+4 IS FOR ROUNDING Rangenum=FNMax(1,Rangenum); Rangenum=FNMin(12,Rangenum); Fb=1000.0*(Fmax / 1000.0+1.0); // // !calculate max freq needed Fb=FNMin(4.01E+7,Fb); sprintf(tbuf,"R%02dFB%8.1fHZ PR RL UP UP RC4 SV4 S2S2",Rangenum,Fb); w3585(tbuf); //setup 3585a do { w3585("D6T4"); r3585(2); stat=Buffer[0]; } while ((stat&0x80)==0x80); //wait until sweep complete w3585("C5CLSA BO TB0"); rd3585(); for (I=0;I<=1001;I++) { Display[I]=Display3585[I]; } Display[0]=Display[0]&1023; Display[1000]=Display[1000]&1023; Maxbin=0;//to avoid compiler warning Maxx=-200; Hzpbin=Fb/1000; Minbinnt=(int)(Freq/5.0/Hzpbin); //temporary variable for type conversion for (Binn=Minbinnt;Binn<=1000;Binn++) { if(Display[Binn]>Maxx) {Maxbin=Binn;} Maxx=FNMax(Display[Binn],Maxx); } Hzpbin=Fb/1000; Freq=Maxbin*Hzpbin; w3585("RLDVD7T4"); r3585(100); //printf("\n%s\n",Buffer); for (I=3;I<10;I++) //extract ref level info { tbuf[I-3]=Buffer[I]; } tbuf[6]=0; //printf("\n>%s<\n",tbuf); Fullscale=atof(tbuf); //printf("%f\n",Fullscale); Sign=1.0; Phaseslope=0; Numharmonics=9; if ((Measuretype==2) | (Measuretype==1) & (Caltype!=2)) { Numharmonics=1; // !IF Measuretype#0, NOT A BEATNOTE; this is for carrier ampl measurement } for (Harmonic=1; Harmonic<=Numharmonics; Harmonic=Harmonic+2) { Binn=(int)(Freq*Harmonic/Hzpbin); Maxx=-1; for (Binc=FNMax(10,Binn-25);Binc<=FNMin(1000,Binn+25);Binc++) { Maxx=FNMax(Maxx,Display[Binc]); } Famp=(double)Fullscale-(1000.0-(double)Maxx)/10; printf("found harmonic no. %d: amplitude: %f\n",Harmonic,Famp); FNCp=FNCalpoint(Amplifier,0,Mixerfreq,0,0,0,0,0,0,Freq*Harmonic); Famp=Famp+FNCp; printf("%0.2f FNCalp, corrected amplitude: %0.2f\n",FNCp,Famp); if (Harmonic==1) {Famp1=Famp;} if ((Famp-Famp1)>=Cutoffamp[Harmonic]) { Phaseslope=Phaseslope+Sign*(double)Harmonic*pow(10,((double)Famp)/20); Sign=Sign*(-1.0); } else { printf("Harmonic no. %d below cut-off, %f!\n",Harmonic,Cutoffamp[Harmonic]); Harmonic=10000; //end loop } } if (Amplifier==1) {Phaseslope=Phaseslope/50;} // 40 db amp has 34 db=x50 amplification into 50 ohm because of series resistor! if ((Measuretype==2) & (Amplifier==1) & ((Caltype==2) | (Caltype==3))) {Famp1=Famp1-34;} //with amp present, 40 db amp has 34 db gain into 50 ohm if (!((Measuretype==2) | (Measuretype==1) & (Caltype!=2))) { /* 12541 OUTPUT I3582;"PRS HLT AA0 AB1 MD2 IM3 SC1 RP0 MN1 MP0 SP10 BS5 RUN" 12544 OUTPUT I3582;"AR" 12547 OUTPUT I3582;"AR" 12550 WAIT .7 12553 CALL Getdc(Mixerdc1) 12556 Setupinterface(" K2,-K12") 12559 OUTPUT I3582;"AR" 12562 WAIT .7 12565 Getdc(Mixerdc2) 12568 Setupinterface("-K2,K12") 12571 Mixerdc=Mixerdc1-Mixerdc2 */ } Phaseslope=Phaseslope*pow(2.0,0.5); Vpeak=pow(10,(Famp1/20))*pow(2.0,0.5); // !peak value of fundamental, convert RMS to peak if (Measuretype==0) { // PRINT "MIXERDC=";FNPround(Mixerdc,-4);"Volts VPEAK=";FNPround(Vpeak,-4);"Volts" printf("Measured mixer DC = %e (dummy) Volt; Vpeak = %e Volt\n",FNPround(Mixerdc,-4),FNPround(Vpeak,-4)); if (fabs(Mixerdc/Vpeak)>0.5) {printf("!! Error REF 314;DC OFFSET FROM MIXER > 1/2 PEAK VOLTAGE\n");} Phaseslope=Phaseslope*cos(asin(Mixerdc/Vpeak)); //correct for (small) DC component printf("Measured phase slope = %e Volt/Radian\n",FNPround(Phaseslope,-3)); if ((Phaseslope<0.0195)|(Vpeak<0.0195)) {printf("!! Error REF 312: PHASE SLOPE LESS THAN 20.0 mV\n");} if (Phaseslope>10.0) {printf("!! Error REF 313; PHASE SLOPE GREATER THAN 10 V\n");} } /* } else //use lf analyzer { */ } } void Lockcheck(int *Lockflag) { //*** need to add! *Lockflag=1; /* 10255 ! * 10258 ! * NAME: Lockcheck 10261 ! * 10264 ! * FUNCTION: Check to see if the PLL is locked. 10267 ! * 10270 ! * INPUT: Phaseslope 10273 ! * 10276 ! * OUTPUT: Lockflag 10279 ! * 10282 Lockcheck:SUB Lockcheck(INTEGER Lockflag) 10285 COM /Loc_flags/ INTEGER C9835,I3582,I3585,I35601a,Clock,Plotter,Abortflag,Printer 10288 COM /Settings/ Latch(0:9) 10291 COM /Parm1/ REAL Cfq,Phaseslope,Vcoslope,I85amp,Loopbw1 10294 COM /Parm2/ REAL Vpeak,Vnom,Vrange,W1,W2,Mixerfreq,Errorspec,Mixerdc 10297 REAL Vswing 10300 REAL Gain 10303 REAL Gain1 10306 REAL Gain2 10309 REAL Dac ! DAC VOLTAGE 10312 REAL Dc ! Dc value from hf-board into 3582A 10315 REAL Atten1 ! Atten1 from hf_board 10318 REAL Atten2 10321 REAL Orgdac 10324 REAL Mixerdcg ! 10327 REAL I ! For-next loop counter 10330 INTEGER Lockcount! Number of times lock has been checked 10333 INTEGER Loopcount! Loop counter 10336 INTEGER Maxx ! Maximum of 3585A display 10339 INTEGER Rangenum ! Range setting for the 3585A 10342 ON KEY 19,5 GOTO Abortlockkey 10345 ALLOCATE Display(0:1001) 10348 ENABLE 10351 Lockflag=0 10354 Vswing=ABS(Vrange)+ABS(Vnom) 10357 Atten1=1/10 10360 IF Vswing>1.2 THEN Atten1=1/5 10363 IF Vswing>2.4 THEN Atten1=1/2 10366 IF Vswing>6 THEN Atten1=1 10369 Atten2=1 10372 IF Vrange<=5*Atten1 THEN Atten2=.5 10375 Gain=2*(20*LGT(Vrange/Atten1/Vpeak) DIV 2) 10378 IF Gain>54 THEN Gain=54 10381 Gain=Gain-12+6 10384 Gain=Gain+6*(Atten=.5) 10387 Gain2=20-Gain MOD 4 10390 IF Gain<18 THEN Gain2=Gain 10393 Gain2=FNMax(6,Gain2) 10396 Gain1=Gain-Gain2 10399 Mixerdcg=-1*(Atten2*Mixerdc*10^((Gain1+Gain2+6)/20)) 10402 Dac=Vnom/Atten1 10405 Orgdac=Dac 10408 ! 10411 ! CHECK FOR BEATNOTE IF NO BEATNOTE THEN CHECK FOR PLL 10414 ! 10417 IF ABS(Mixerdcg)>.10*Phaseslope THEN Highbeat 10420 GOSUB Beatsearch 10423 IF Beatflag=0 THEN Checkflip!NO BEAT CHECK LOCK 10426 ! OPEN LOOP 10429 Setupinterface("-K10") 10432 WAIT 2.2 10435 ! CLOSE LOOP 10438 Setupinterface("K10") 10441 WAIT 1.2 10444 GOSUB Beatsearch 10447 IF Beatflag=1 THEN Lockcheckexit 10450 Checkflip: ! 10453 Setupinterface("-L0,L9") 10456 DISP CHR$(130)&CHR$(127)&CHR$(128)&"CHECKING LOCK" 10459 OUTPUT I3582;"PRS,SC1,MN1,AC2,MP0" 10462 Loopcount=0 10465 Lockcheckloop: ! 10468 WAIT .5 10471 GOSUB Checklk ! Check OUT OF LOCK FLIP on 3582A 10474 Loopcount=Loopcount+1 10477 IF (Loopcount<2) AND (Lockflag=0) THEN Lockcheckloop 10480 GOTO Lockcheckexit 10483 ! 10486 ! POSSIBLE HIGHFREQ BEATNOTE NEED TO BRING IT IN 10489 ! 10492 Highbeat:! 10495 ! FIND DAC STEP VOLTAGE 10498 IF (Dac-Mixerdcg<=0) AND (Dac>0) THEN Steps=-.2 10501 IF (Dac-Mixerdcg>0) AND (Dac>0) THEN Steps=-1 10504 IF Dac=0 THEN Steps=SGN(Mixerdcg)*.2*(-1) 10507 IF (Dac-Mixerdcg>=0) AND (Dac<0) THEN Steps=.2 10510 IF (Dac-Mixerdcg<0) AND (Dac<0) THEN Steps=1 10513 IF (SGN(Dac)<>SGN(Mixerdcg)) AND (SGN(Dac)<>0) THEN Steps=Steps*(-1) 10516 Finalv=Dac-Mixerdcg 10519 IF ABS(Finalv)>10.4 THEN Finalv=10.4*SGN(Finalv) 10522 GOSUB Movedac 10525 GOSUB Beatsearch 10528 Finalv=Orgdac 10531 Steps=Steps*(-1) 10534 IF Beatflag=0 THEN GOSUB Movedac 10537 IF Beatflag=0 THEN Checkflip 10540 ! 10543 ! OPEN LOOP 10546 ! 10549 Setupinterface("-K10") 10552 WAIT 2 10555 Setupinterface("K10") 10558 WAIT 1 10561 GOSUB Beatsearch 10564 GOSUB Movedac 10567 IF Beatflag=1 THEN Lockcheckexit 10570 GOTO Checkflip 10573 Abortlockkey: ! 10576 DISP "MEASUREMENT ABORTED BY USER" 10579 BEEP 10582 WAIT 1 10585 Abortflag=1 10588 GOTO Lockcheckexit 10591 Abortlock1: ! 10594 DISP "REF 311; DAMAGING INPUT SIGNAL, MEASUREMENT ABORTED" 10597 Errorbeep 10600 WAIT 2 10603 Abortflag=1 10606 GOTO Lockcheckexit 10609 Lockcheckexit:! 10612 SUBEXIT 10615 ! 10618 ! CHECK FOR PRESENCE OF BEATNOTE 10621 ! 10624 Beatsearch:! 10627 CLEAR I3585 10630 Rangenum=(20*LGT(Phaseslope)+13)/5+6 10633 OUTPUT I3585 USING "K,ZZ,K";"R",Rangenum,"RC4 SV4 S2" 10636 Toggle("OUT OF LOCK") 10639 OUTPUT I3585;"S2" 10642 Sweepwait:OUTPUT I3585;"D6T4" 10645 ENTER I3585 USING "#,B";Stat 10648 IF BIT(Stat,7) THEN Sweepwait 10651 OUTPUT I3585;"C5CLSATB0BO" 10654 ENTER I3585 USING "#,W";Display(*) 10657 OUTPUT I3585;"S1" 10660 Display(0)=0 10663 Display(1)=0 10666 Display(1001)=0 10669 Total=0 10672 FOR I=0 TO 1001 10675 IF Display(I)>900 THEN 10678 Display(I)=1 10681 ELSE 10684 Display(I)=0 10687 END IF 10690 Total=Total+Display(I) 10693 NEXT I 10696 Beatflag=1 10699 IF Total=0 THEN Beatflag=0 10702 RETURN 10705 ! 10708 ! MOVE DAC VOLTAGE 10711 ! 10714 Movedac:! 10717 IF Mixerdcg=0 THEN RETURN 10720 FOR I=Dac TO Finalv-Steps STEP Steps 10723 Dac=Dac+Steps 10726 Setupbits("DAC",Dac) 10729 NEXT I 10732 Setupbits("DAC",Finalv) 10735 Dac=Finalv 10738 RETURN 10741 ! 10744 ! 10747 ! 10750 Checklk: ! 10753 Lockflag=0 10756 Toggle("OUT OF LOCK") 10759 WAIT .5 10762 Getdc(Dc) 10765 IF Dc>2 THEN Abortlock1 10768 IF (Dc>=.9) AND (Dc<=2) THEN RETURN 10771 Lockflag=1 ! SET LOOP LOCKED FLAG 10774 RETURN ! **FF** ** 10777 SUBEND 10780 ! * */ } void Lagleadcalc(void) { W2=2.0*M_PI*Zerofreq[(int)Laglead]; W3=1.0/(R25*C8+1.0/W2); Loopbw3=Loopbw1*W3/W2; // ! Check to see if open loop bw is less than lag-lead pole freq W3 if (Loopbw1= than pole-freq W3 and less than // ! lag-lead zero freq W2 if ((Loopbw1>=W3/(2.0*M_PI)) & (Loopbw120.0) {setup_i("-L0,L9,-S1,-S5,K7,K6,S2");} //connect tracking gen? if (Loopbw3<=20.0) {setup_i("L0,-L9,S1,S5,-K7,-K6,-S2");} //connect noise source? if ((Loopbw3>250000) & (Laglead!=7)) { printf("!! Error: Loop bandwidth error REF 323; UNABLE TO ACHIEVE PHASE LOCK!\n"); } else { printf("BW OK: LOOP BANDWIDTH=%0.2f Hz\n",FNPround(Loopbw3,-2));} Vcofreq=Loopbw3/4.0; } void waitfor3585(void) { char stat; do { w3585("D6T4"); r3585(2); stat=Buffer[0]; } while ((stat&0x80)==0x80); //wait until sweep complete } void Charloop() //int Pdv,int Vcoindex { int Binn; // !Bin # of display int Bwincrease; // !0=ok to increase bandwidth, 1=already increased double C1,C2,C3,C4,C5; // !Curve fit coeffecients // double C8; // !Capacitor in lag-lead double Corner; // !Freq of pole in lag-lead int Count; // !Index counter double Fw; // !Value of transfer function at w double Gain; // !Amount of gain in programmable gains // double Gain1; // !0->28 dB in 4 dB steps // double Gain2; // !6->20 dB in 2 dB steps double Hzpbin; // !Hz per display bin double Hzpbin2; // !Hz per bin used for plot of loop int I; // !For-next loop counter int J; // !For-next loop counter double Junk; // !Dummy variable for non-usable value read from the 3585A int Lockflag; // !0=loop not locked, 1=loop locked double Loopbw2; // ! int Maxindex; // !Index where max response occured double Maxpointerror; // !Max error determined by Difcorrection double Maxx; // !Value of max response int N; // !Number of points for differential correction int Numsamples; // !Number of samples on 3582A XFER function double Oldloopbw1; // !Initial calculation of Loopbw1 // double R25; // !Resistor in lag-lead double Rc2pi; // !Product of 2*PI*R*C int Sens; // !Sensitivity setting of the 3582A int Span; // !Span number of the 3582A int Stat; // !Status read from the 3582A or 3585A double Wi; // !Radian freq double X[101]; // !Freq's to be used for curve fit double X1; // !Freq to be put in X(*) double Y[101]; // !Amp's to be used for curve fit double Zero; // !Desired Leadfreq in lag-lead int forcellg2; int retrychar; //retry characterization at other laglead int Display[1050]; char tbuf[100]; // ! Zero freqs are calculated from the resistor selected by // ! the following formula: f=1/(2*PI*(R+100)*C8) // ! 100 is the switch resistance // C8=3.3E-8; // ! .033 uf // R25=4.823E+5 // ! 482K ohm printf("\nCharacterizing the loop...\n"); ibclr(Device3585); // Clear the 3585 if (Ibsta() & ERR) { GpibError("ibclr Error"); } wait_s01(3); // ! DETERMINE GAIN SETTINGS Gain=2.0*(20.0*log10(Vrange/Atten1/Vpeak) / 2.0); if (Gain>54.0) {Gain=54.0;} Loopbw1=fabs(Phaseslope*Vcoslope*pow(10,Gain/20.0)); // ! OPEN LOOP BW printf("LOOP BW1 (uncorrected)=%e\n",Loopbw1); Loopbw1=Loopbw1/pow(10,(FNCalpoint(0,0,Mixerfreq,0,0,0,0,0,0,10000.0)/20.0)); // ! ADJUST PHASESLOPE TO MEASUREMENT POINT printf("LOOP BW1 (FNCalp corrected)=%e\n",Loopbw1); Gain=Gain-12.0+6.0; // !TAKE OUT x4(12dB) AMPLIFIER AND 6dB PAD if (Atten2==0.5) {Gain=Gain+6;} // !ADD 6 dB IF ATTEN2=.5 Gain2=20.0-fmod(floor(Gain),4.0); // !CHOOSE 20 OR 18 dB FOR GAIN2 if (Gain<18) {Gain2=Gain;} // !USE LESS IF GAIN<18 Gain2=floor(Gain2/2.0)*2.0; Gain2=FNMax(6,Gain2); // !GAIN2 HAS 6 dB MIN Gain1=Gain-Gain2; // !PUT REMAINING GAIN IN GAIN1 Gain1=floor(Gain1/4.0)*4.0; Loopbw1_actual=fabs(Phaseslope*Vcoslope*pow(10,(Gain1+Gain2)/20.0)); // ! OPEN LOOP BW value_i(GAIN1,Gain1); value_i(GAIN2,Gain2); value_i(DAC,Vnom/Atten1); // value_i(DAC,Lockvoltage); //only for unstable osciallators that are not within 15% range setup_i("L2,K10,S3"); //close loop wait_s01(20); toggle_i(OUTOFLOCK); printf("GAIN=%0.2f\n",Gain); printf("GAIN1=%0.2f\n",Gain1); printf("GAIN2=%0.2f\n",Gain2); printf("VCOSLOPE=%e Hz/V\n",Vcoslope/Atten1); printf("PHASESLOPE=%e V/rad\n",Phaseslope); printf("VPEAK=%0.2f V\n",Vpeak); printf("LOOP BW1=%e\n",Loopbw1); printf("LOOP BW1 (with actual gain)=%e\n",Loopbw1_actual); //Loopbw1=Loopbw1_actual; //printf("Note: using LOOP BW1 calcuated based on actual gain!\n"); printf("Note: using LOOP BW1 calcuated based on %0.2f dB Gain!\n",Gain); // ! Calculate BW assuming far out zero Corner=1.0/(2.0*M_PI*R25*C8); Loopbw2=sqrt(Loopbw1*Corner); // ! Geometric mean, approximate cross-over printf("CORNER=%e\n",Corner); printf("LOOP BW2=%e\n",Loopbw2); // ! DETERMINE WHICH ZERO TO USE Zero=Loopbw2/sqrt(2.0); Laglead=0.0; for (I=11;I>=0;I--) { if (Zerofreq[I]7) { printf("!! Error REF 320; EXTERNAL LAG-LEAD MUST BE USED!\n"); Laglead2=2; //lead lag for 35601A hardware, 0 to 7 Laglead=4; // Effective lead lag, leadlag2 to 11 Bwincrease=1; // ! DON'T ALLOW LAGLEAD TO BE CHANGED value_i(LEADLAG,Laglead2);// ! FORCE LAGLEAD2 } Lagleadcalc(); if (forcellg2) {value_i(LEADLAG,Laglead2);} // ! FORCE LAGLEAD2 retrychar=0; do { //this is the loop for characterization //15745 ! CHECK TO SEE IF LOOP IS LOCKED Lockcheck(&Lockflag); if (Lockflag!=1) { // ! IF NOT LOCKED, TRY TO INCREASE LOOP BANDWIDTH if ((Bwincrease==1) | (Laglead==0)) { printf("!! Error: No lock, and cannot increase loop bandwidth any further!\n"); } else { Laglead=Laglead-1; // !INCREASE LOOP BANDWIDTH printf("RETRY WITH NEW LAG LEAD CHOICE=%0.1f\n",Laglead); Bwincrease=1; Lagleadcalc(); Lockcheck(&Lockflag); if (Lockflag!=1) { printf("!! Error: No lock, even with other lag lead!\n"); } } } //15799 Startcharloop: ! /* 15802 IF No_look THEN Skipplot 15805 IF Pdv<>9836 THEN Skipplot 15808 GINIT 15811 GCLEAR 15814 PEN 1 15817 GRAPHICS ON 15820 Beginexp=INT(LGT(Loopbw3)-2) 15823 ! 15826 VIEWPORT 0,100,10,100 15829 LORG 5 15832 CSIZE 3,.6 15835 MOVE 70,95 15838 LABEL USING "#,K";"THEORETICAL & ACTUAL 'LOOP SUPPRESSION' FACTORS" 15841 ! 15844 VIEWPORT 0,100,20,90 15847 WINDOW Beginexp,Beginexp+4,-10,10 15850 LINE TYPE 4,.30 15853 GRID 1,1,Beginexp,0 15856 LINE TYPE 1 15859 FRAME 15862 PENUP 15865 Skipplot: ! 15868 ! */ // ! USE 3585A FOR LOOP BANDWIDTHS >20 HZ if (Loopbw3<20) { printf("!! Warning: loop characterization for Bandwidth <20 Hz not yet implemented!\n");} //follows: 3585 characerization Hzpbin=(Loopbw3*4.0/10)*0.01; // ! Span=BW3*4. Hzpbin in Units of .01 Hz. ibclr(Device3585); // Clear the 3585 if (Ibsta() & ERR) { GpibError("ibclr Error"); } wait_s01(3); sprintf(tbuf,"FB%8.1fHZ,R10,I1,SV4,S2",1000*Hzpbin); w3585(tbuf); //setup 3585a //optional, to inspect: w3585("SV1 S1"); //save in register 1, single sweep // EnableLocal( BoardIndex, PrimaryAddress3585 ); // Local // if (Ibsta() & ERR) { // GpibError("EnableLocal Error"); // } printf("\nOBSERVE 3585 DISPLAY OF LOOP SUPRESSION CHARACTERISTIC.\n"); printf("EXCESSIVE NOISE MAY CAUSE ACCURACY SPEC DEGRADATION \n"); printf("CHECK LOOP SUPPRESSION ON 3585A, THEN PRESS ANY KEY\n"); getchar(); ibclr(Device3585); // Clear the 3585 if (Ibsta() & ERR) { GpibError("ibclr Error"); } wait_s01(3); w3585("RC1"); //recall register 1 wait_s01(10); //end of optional section toggle_i(OUTOFLOCK); printf("\nMEASURING CLOSED LOOP RESPONSE...\n"); wait_s01(10); w3585("S2"); // !Start the sweep waitfor3585(); w3585("SAAB1"); setup_i("-S3,-S4"); // ! Open loop for reference sweep w3585("S2"); // !Start the sweep waitfor3585(); setup_i("-K7,-K6,-S2,S3,S4"); // !Close loop again w3585("C5CLSABO"); rd3585(); for (I=0;I<=1000;I++) //cut out first point which has no display data. { Display[I]=Display3585[I+1]; } Display[1000]=Display[1000]&1023; Display[0]=Display[0]&1023; for (I=0;I<=1000;I++) { Display[I]=500-Display[I]; // !SCALE FROM -500 TO 500 } if (Display[1000]<-10) { printf("!! Error REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT (<-1 dB at end of sweep)!\n"); // !Check for < -1 dB far out } I=1001; do { I--; } while ((!( (Display[I]<-80)&(Display[I-1]<-80) )) | (I<2)); printf("Found -8 dB at bin %d, %0.1f Hz\n",I,Hzpbin*I); if (I<2) { printf("!! Error REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT! <-8 dB not found!\n"); } // ! -8 dB point found, increase loop bandwidth if invalid if ((I>500) & (Bwincrease==0)) { printf("Warning: -8 dB too far out. Trying to increase loop BW...\n"); if (Laglead>0) { Laglead=Laglead-1; // !INCREASE LOOP BANDWIDTH printf("RETRY WITH NEW LAG LEAD CHOICE=%0.1f\n",Laglead); Bwincrease=1; Lagleadcalc(); retrychar=1; } } } while (retrychar); if (I>500) { printf("!! Error REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT! <-8 dB too far out!\n"); } } double Freq1; // !Freq of first bin of 3585A display double Freq2; // !Freq of 2nd bin of 3585A display int Path; // !Number of the current path being checked double Maxcorr; // !Max correction for a particular segment double Maxerror; // !Max fit error for a particular segment double Overallmaxcorr; // !Max of all Maxcorr double Overallmaxerror; // !Max of all Maxerror void Calpath(void) { int Display[1010]; //(-1:1000) // int Reflevel; // !Reference level of 3585A int Count; // !Counter double F[100]; // !Freq's for curve fit double Freq; // !Freq double Hzpbin; // !Hz per display bin int I; // !For-next loop counter int J; // !For-next loop counter int Start; // !Bin of display where calibration starts double Y[100]; // !Amplitude for each Frequency in F(*) double Correction; w3585("MK1D2T4"); r3585(12); //intf(">%s<",Buffer); Freq1=atof(Buffer); w3585("MK2D2T4"); r3585(12); //intf(">%s<",Buffer); Freq2=atof(Buffer); //printf("Path: %d, Freq %0.1f Freq2 %0.1f\n",Path,Freq1,Freq2); w3585("AB1 C5CL SA AB0 TA0 BO"); rd3585(); for (I=0;I<1001;I++) { Display[I]=Display3585[I+1]; //first bit is ffff } Display[0]=Display[0]&1023; Display[1000]=Display[1000]&1023; Reflevel=5; for (I=0;I<1001;I++) { Display[I]=Display[I]+(100*(Reflevel-10)); } for (I=0;I<1001;I++) { Display[I]=Display[I]*(-1); } Hzpbin=Freq2-Freq1; Count=1; Start=0; if (Path==1) {Start=10;} // ! 2 MHz LPF if (Path==2) {Start=100;} //464 IF (Plotter<>0) OR (C9835=0) THEN PENUP Maxcorr=-200; Maxerror=-200; //4473 IF Doplot THEN LINE TYPE 1 for (I=1;I<=81;I++) { F[I]=0; Y[I]=0; } for (I=Start;I<=1000;I=I+13) { Freq=I*Hzpbin+Freq1; F[Count]=Freq; Y[Count]=((double)Display[I])/100.0; Maxcorr=FNMax(fabs(Y[Count]),Maxcorr); // IF Doplot THEN PLOT LGT(Freq),Y(Count),1 Count=Count+1; } // ! IF PATH=1 THEN ONLY GET 4 2 MHZ FILTER COEFFECIENTS if (Path==1) { curvefit(&F,&Y,Count-1,4,&Caldata[Path][1],&Caldata[Path][2],&Caldata[Path][3],&Caldata[Path][4],&Caldata[Path][5]); } else { curvefit(&F,&Y,Count-1,5,&Caldata[Path][1],&Caldata[Path][2],&Caldata[Path][3],&Caldata[Path][4],&Caldata[Path][5]); } //14512 IF Doplot THEN PENUP //14515 IF Doplot THEN LINE TYPE 3,.3 for (I=Start;I<=1000;I=I+25) { Freq=I*Hzpbin+Freq1; Correction=Caldata[Path][1]+Caldata[Path][2]*Freq+Caldata[Path][3]*Freq*Freq+Caldata[Path][4]*Freq*Freq*Freq+Caldata[Path][5]/Freq; //14527 IF Doplot THEN PLOT LGT(Freq),Correction,1 Maxerror=FNMax(fabs((double)Display[I]/100.0-Correction),Maxerror); } Overallmaxcorr=FNMax(Maxcorr,Overallmaxcorr); Overallmaxerror=FNMax(Maxerror,Overallmaxerror); } char lf3585[2]={10,0}; void Cal(void) { double Amp; // !Amplitude of 3585A tracking generator char tbuf[100]; int levelok; // Doplot=0;// !SET TO 0 TO SUPPRESS PLOT // Look=0;// !SET TO 1 TO LOOK AT INSERTION LOSS printf("Calibrating interface box unflatness...\n"); ibclr(Device3585); // Clear the 3585 if (Ibsta() & ERR) { GpibError("ibclr Error"); } wait_s01(3); // Mat2(C(*),"*",0,1,7,1,5) Caldata[7][1]=0.095; Caldata[7][2]=1.65E-8; Caldata[7][3]=-4.5E-16; Caldata[7][4]=5.75E-24; Caldata[7][5]=-5900.0; Overallmaxcorr=0.0; Overallmaxerror=0.0; zerolatch(); toggle_i(OVERLOAD); setup_i("K2,K3,K4,K5,K7"); w3585("AR0 AL0 RL -49DM DD1DB R01 RC4"); //setup 3585a levelok=0; do { w3585("S2D1T6"); r3585(13); Amp=atof(Buffer); printf("3585A Amplitude: %0.1f dBm\n",Amp); if (abs(Amp+54)<=1) {levelok=1;} else { w3585("S1"); printf("ADJUST 3585A TRACKING GEN FOR CENTER OF 3585A SCREEN, THEN PRESS KEY!\n"); w3585("LA ADJUST 3585A TRACKING GEN FOR CENTER OF 3585A SCREEN\n");w3585(lf3585); getchar(); } }while (!levelok); w3585("AL1 R05 FS FA 100000HZ FB 40.1 MZ PR RBDN DD1DB RC4 SV4 DA S1"); w3585("LA CONNECT TG DIRECTLY TO 50 OHM INPUT"); w3585(lf3585); printf("CONNECT 3585A TRACKING GENERATOR OUTPUT DIRECTLY TO 3585A 50 OHM INPUT,\n THEN PRESS KEY!\n"); getchar(); w3585("S2 S2"); waitfor3585(); Path=7; setup_i("-K2,-K3,-K4,-K5,-K7"); w3585("LACONNECT TG TO 40 MHZ INPUT, RECONNECT 50 OHM INPUT");w3585(lf3585); printf("CONNECT TRACKING GEN. TO 35601A SIGNAL INPUT, RECONNECT 50 OHM INPUT OF 3585A,\n THEN PRESS KEY!\n"); getchar(); printf("CALIBRATING INSERTION LOSS...\n"); w3585("SA S2S2"); waitfor3585(); Calpath(); setup_i("K2,K3,K4,K5,K7"); w3585("AR0 AL0 RL -49DM DD1DB R01 RC4 S2 "); //14104 OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"INSERTION LOSS",Maxcorr,Maxerror printf(">>Insertion Loss %0.3f %0.3f\n\n",Maxcorr,Maxerror); printf("RECONNECT 3585A TRACKING GEN. TO 35601A TRACKING GEN. INPUT,\n THEN PRESS KEY!\n"); w3585("TB0TA1LARECONNECT TRACKING GENERATOR TO PROPER 35601A CONNECTION");w3585(lf3585); getchar(); //Path1: ! printf("CALIBRATING AMPLIFIER FLATNESS; RESULTS ARE [MAXCORR] [MAXERROR]\n"); // ! CALIBRATE 2 MHZ LOW PASS FILTER ON HF BOARD TO 1MHz Path=1; setup_i("K1,K12"); w3585("RL -49DM FA0HZ FB1MZ PR RBDN RC4 SV4 DA S2 S2"); w3585("LA 2MHZ FILTER IN");w3585(lf3585); waitfor3585(); setup_i("K8"); // !K8 AND K9 MOVE TOGETHER w3585("SA S2 S2"); waitfor3585(); Calpath(); printf(">>2 MHz Filter %0.3f %0.3f\n",Maxcorr,Maxerror); //14161 OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"2 MHz FILTER",Maxcorr,Maxerror //14167 ! CALIBRATE AMPLIFIER PATH TO 400 HZ Path=2; setup_i("-K8,-K9"); w3585("FA5HZ FB405HZ PR RC4 SV4 TB0 S2 S2"); w3585("LA STRAIGHT THROUGH, AMPLIFIER IN");w3585(lf3585); waitfor3585(); setup_i("K11"); w3585("RL -15DM SA S2 S2"); waitfor3585(); Calpath(); printf(">>x100 AMP to 400 Hz %0.3f %0.3f\n",Maxcorr,Maxerror); //14197 OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"x100 AMP TO 400 Hz",Maxcorr,Maxerror // ! CALIBRATE AMPLIFIER PATH FROM 400 TO 25000 HZ Path=3; setup_i("-K11"); w3585("RL-49DM FA400HZ FB25400HZ PR RBDN RC4 SV4 TB0 S2 S2"); waitfor3585(); setup_i("K11"); w3585("RL -15DM SA S2 S2"); waitfor3585(); Calpath(); printf(">>x100 AMP 400 TO 25 KHz %0.3f %0.3f\n",Maxcorr,Maxerror); //14230 OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"x100 AMP 400 TO 25 KHz",Maxcorr,Maxerror // ! CALIBRATE AMPLIFIER FROM 25000 TO 5 MHz Path=4; setup_i("-K11"); w3585("RL -49DM FA 25000HZ FB 5000000 HZ PR RBDN RC4 SV4 TB0 S2 S2"); w3585("LA STRAIGHT THROUGH, AMPLIFIER IN ");w3585(lf3585); waitfor3585(); setup_i("K11"); w3585("RL -15DM SA S2 S2"); waitfor3585(); Calpath(); printf(">>x100 AMP 25 KHz TO 5 MHz %0.3f %0.3f\n",Maxcorr,Maxerror); //14266 OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"x100 AMP 25 KHz TO 5 MHz",Maxcorr,Maxerror Path=5; setup_i("-K11"); w3585("RL -49DM FA 5000000HZ FB 40000000HZ PR RBDN RC4 SV4 TB0 S2 S2"); w3585("LA STRAIGHT THROUGH, AMPLIFIER IN ");w3585(lf3585); waitfor3585(); setup_i("K11"); w3585("RL -15DM SA S2 S2"); waitfor3585(); Calpath(); printf(">>x100 AMP 5 MHz TO 40 MHz %0.3f %0.3f\n",Maxcorr,Maxerror); //14296 OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"x100 AMP 5 MHz TO 40 MHz",Maxcorr,Maxerror // ! CALIBRATE STRAIGHT THROUGH PATH (NO AMP) FROM 25000 TO 40 MHz Path=6; setup_i("-K1,-K11,-K12"); w3585("RL -49DM FA 25000HZ FB 40000000HZ PR RBDN RC4 SV4 TB0 S2 S2"); w3585("LA STRAIGHT THROUGH, AMPLIFIER OUT ");w3585(lf3585); waitfor3585(); setup_i("K1,K12"); w3585("SA S2 S2"); waitfor3585(); Calpath(); printf(">>STRAIGHT 25 KHz TO 40 MHz %0.3f %0.3f\n",Maxcorr,Maxerror); setup_i("-K1,-K12"); //14332 OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"STRAIGHT 25 KHz TO 40 MHz",Maxcorr,Maxerror //14338 BEEP //14341 IF Look=0 THEN GOTO No_output //14344 OUTPUT Printer USING "//,K,K";".02 TO 40 Hz AMPLIFIER CORRECTION WILL BE:",C(2,1)+C(2,2)*40+C(2,3)*1600+C(2,4)*40^3+C(2,5)/40 //14347 OUTPUT Printer USING "//,5(K,3X)";"INSERTION LOSS COEFFECIENTS:",C(7,1),C(7,2),C(7,3),C(7,4),C(7,5) //14350 ! OUTPUT Printer USING "///"; //14353 No_output:! //14356 IF (Printer<>0) AND (Doplot=1) THEN DUMP GRAPHICS printf(">> 0.02 TO 40 Hz AMPLIFIER CORRECTION WILL BE: %0.5f\n",Caldata[2][1]+Caldata[2][2]*40+Caldata[2][3]*1600+Caldata[2][4]*40*40*40+Caldata[2][5]/40); printf("\nINSERTION LOSS COEFFICIENTS:\n%0.4e %0.4e %0.4e %0.4e %0.4e\n",Caldata[7][1],Caldata[7][2],Caldata[7][3],Caldata[7][4],Caldata[7][5]); zerolatch(); setup_i("F0"); if ((Overallmaxerror>1.0) | (Overallmaxcorr>=3.5)) { printf("!! Error REF 317; UNABLE TO CALIBRATE 35601A\n"); } else { printf("\n35601A calibration complete!\n\n"); } } /* 16858 ! * NAME: Phioff 16864 ! * FUNCTION: Calculate the correction factors for a particular 16867 ! * segment of data. 16873 ! * INPUT: Plotindex, Vcoindex, Amplifier, 16876 ! * Mixerfreq, Caldata(*), W1, W2, W3, Loopbw1, Phaseslope, 16879 ! * Vcoslope, Vcofreq 16885 ! * OUTPUT: Plotdata(*) */ // note: Caldata needs to contain current cal data to be used (not necessarily the C cal data determined by Cal! void Phioff(int Plotdata[][1012], int Plotindex,int Vcoindex,int Measuretype,int Amplifier,double Mixerfreq,double W1,double W2,double W3,double Loopbw1,double Phaseslope,double Vcoslope,double Vcofreq) { double Ang; // !Phase angle of loop correction double Bwcorr; // !Bandwidth correction double C1,C2,C3,C4,C5; // !Signal path correction coeffecients int Calnum; // !Index into Caldata(*) for coeffecients double Corr; // !Correction- bwcorr,phaseslope or vcoslope & gain int Cutoff; // !Index beyond which loop corrections=0 double F; // !Freq in Hz double Fw; // !F(w), loop correction factor int Gain; // !Gain from low noise amp double Hzpbin; // !Number of Hz per data point int I; // !For-next loop counter int Maxi; // !Max number of points to calibrate double Pole; // double R; // !Magnitude of loop correction double Rc2pi; // !(R*C*2PI)^2 used in AC COUPLER correction double W; // !Freq in radians/sec double W5; // !Lead freq in lead-lag double Wloopbw1; // !Loop bandwidth double Ww; // !W squared double Ww1; // !W1 squared double Ww2; // !W2 squared double Ww3; // !W3 squared double Ww5; // int Phioffdone; printf("Calculating Phi offset...\n"); // ! Measuretype 0 -- vco control // ! Vcoslope#0 Phaseslope#0 Loopbw1#0 Loopbw3#0 // ! // ! Measuretype 1 -- no vco control // ! Vcolsope=0 Phaseslope#0 Loopbw1=0 Loopbw3=0 // ! // ! Measuretype 2 -- discriminator // ! Vcolsope#0 Phaseslope=0 Loopbw1=0 Loopbw3=0 Phioffdone=0; Rc2pi=(1.0E+5*1.0E-5*2.0*M_PI)*(1.0E+5*1.0E-5*2.0*M_PI); Plotdata[Plotindex][1007]=2; //valid data flag - corrected data if (Plotindex<=10) { //**3582 Hzpbin=((double)(Plotdata[Plotindex][1010]))/250.0; //these variables are set by getdata Hzpbin=((double)(Plotdata[Plotindex][1010]))/800.0; //these variables are set by getdata //**3562 Bwcorr=-10.0*log10(363.0/(25000.0/Plotdata[Plotindex][1010])); Bwcorr=-10.0*log10(119.0/(25000.0/((double)Plotdata[Plotindex][1010])));//this is for the 3562a if (Plotindex<=Vcoindex) { // AC COUPLER CORRECTION: (HIGH PASS FILTER) // HPF : 1/(1+1/RCs) // HPF CORRECTION : 1+1/RCs // 10*LGT( |1+1/RCs| ^2 ) // 10*LGT(1+1/(RCW)^2) // // LAG LEAD : (1+s/W2)/(1+s/W3) // 10*LGT( |1+s/W3|^2 / |1+s/W3|^2 ) // 10*LGT( (1+(W/W2)^2) / (1+(W/W3)^2)) // where W=(2*PI*F) // // LEAD: (1+s/W5) -> 10*LGT(|1+s/W5|^2) -> 10*LGT(1+(W/W5)^2) // COMBINING ALL TERMS: // 10*LGT( (1+1/(RCW)^2) * (1+(W/W5)^2) * (1+(W/W2)^2) / (1+(W/W3)^2) ) // RC=100K*10uF =1 W5=2.0*M_PI*33500.0; Ww2=W2*W2; Ww3=W3*W3; Ww5=W5*W5; Corr=10.0*(C1+Bwcorr+20.0*log10(fabs(Vcoslope))); //**for (I=1;I<=255;I++) for (I=1;I<=800;I++) { F=I*Hzpbin; Ww=2.0*M_PI*2.0*M_PI*F*F; Plotdata[Plotindex][I]=(int)(Corr-10*20*log10(F)+10*10*log10((1+1/Ww)*(1+Ww/Ww5)*(1+Ww/Ww2)/(1+Ww/Ww3))); } printf("Phioff: Plotindex<=VCOindex Correction done!\n"); Phioffdone=1; } else { Cutoff=(int)(Vcofreq*40/Hzpbin); //**3562 Cutoff=(int)FNMin(255,(double)(Cutoff)); Cutoff=(int)FNMin(800.0,(double)(Cutoff)); Cutoff=(int)FNMax(0,(double)(Cutoff)); Gain=40; //**3562 Maxi=255; Maxi=800; printf("Cutoff (LF) %i\n",Cutoff); } } else { if (Plotindex==11) {Bwcorr=-27.96-0.5;}// !-.5 IS FOR PEAK DETECT CORRECTION if (Plotindex==12) {Bwcorr=-37.96;} // !-10*LGT(BW)+2.03857 if (Plotindex==13) {Bwcorr=-42.73;} // Hzpbin=((double)Plotdata[Plotindex][1010])*10.0; Gain=40-6; Cutoff=(int)(FNMin(1000.0,Vcofreq*70.0/Hzpbin)); Cutoff=(int)FNMax((double)(Cutoff),0); Maxi=1000; printf("Cutoff (HF) %i\n",Cutoff); } if (!Phioffdone) { //17071 Fwcalc: ! // ! CALDATA DEFINITION // ! 1) 0-1 MHz 2MHz filter // ! 2) 0-400 Hz amplifier // ! 3) 400-25KHz amplifier // ! 4) 25KHz-5MHz amplifier // ! 5) 5KHz-40MHz amplifier // ! 6) 5MHz-40MHz no amplifier // ! 7) Insertion loss C1=0; C2=0; C3=0; C4=0; C5=0; if (Amplifier==0) {Gain=0;} if (!(Mixerfreq>=9.5E+7)) { C1=Caldata[1][1];// !2 MHz filter correction C2=Caldata[1][2]; C3=Caldata[1][3]; C4=Caldata[1][4];// !NO C5 FOR FILTER } if (Amplifier!=0) { if (Plotindex<=4) { C1=C1+Caldata[2][1]+Caldata[2][2]*40.0+Caldata[2][3]*1600.0+Caldata[2][4]*64000.0+Caldata[2][5]/40.0; // ! Calibrate amplifier for freqs < 40 Hz } else { if (Plotindex==13) {Calnum=5;} // Amplifier 5 MHz to 40 MHz if (Plotindex==12) {Calnum=4;} // Amplifier 25 KHz to 5 MHz if (Plotindex==11) {Calnum=4;} // Amplifier 25 KHz to 5 MHz //**3582 if (Plotindex<=10) {Calnum=3;} // Amplifier 400 Hz to 25 KHz //**3582 if (Plotindex<=6) {Calnum=2;} // Amplifier 40 Hz to 400 Hz if (Plotindex<=10) {Calnum=3;} // Amplifier 400 Hz to 25 KHz if (Plotindex<=7) {Calnum=2;} // Amplifier 40 Hz to 400 Hz C1=C1+Caldata[Calnum][1]; C2=C2+Caldata[Calnum][2]; C3=C3+Caldata[Calnum][3]; C4=C4+Caldata[Calnum][4]; C5=C5+Caldata[Calnum][5]; } } // Calibrate insertion loss C1=C1+Caldata[7][1]+Caldata[6][1]; if (!(Plotindex<=10)) { C2=C2+Caldata[7][2]+Caldata[6][2]; C3=C3+Caldata[7][3]+Caldata[6][3]; C4=C4+Caldata[7][4]+Caldata[6][4]; C5=C5+Caldata[7][5]+Caldata[6][5]; } // do the actual data correction if (Measuretype==0) { Ww1=W1*W1; Ww2=W2*W2; Ww3=W3*W3; Wloopbw1=2.0*M_PI*Loopbw1; Corr=10.0*(Bwcorr-20.0*log10(Phaseslope)-(double)Gain); printf("C[I] %e %e %e %e %e\n",C1,C2,C3,C4,C5); printf("BWcorr %0.3f\n",Bwcorr); printf("Phaseslope corr %0.3f\n",-20.0*log10(Phaseslope)); printf("Gain corr %0.3f\n",-(double)Gain); printf("Corr %0.3f\n",Corr/10); printf("Hzpbin %0.3f\n",Hzpbin); printf("Plotindex %i\n",Plotindex); printf("Hz Stopindex %0.3f\n",Hzpbin*((double)Plotdata[Plotindex][1009])); for (I=1; I<=Cutoff; I++) { F=I*Hzpbin; W=2.0*M_PI*F; Ww=W*W; // W0=1/2 W0^2=.25 R=Wloopbw1/W*sqrt((1+Ww/Ww2)*(1.0+0.25/Ww)/((1.0+Ww/Ww3)*(1.0+Ww/Ww1))); Pole=W/1.75E+6; if (Pole>(M_PI/2.0)) {Pole=M_PI/2.0;} Ang=-atan(W/W1)+atan(W/W2)-atan(W/W3)-M_PI/2.0-atan(0.5/W)-Pole; Fw=-10.0*log10(1.0+2.0*R*cos(Ang)+R*R); F=FNMax(F,Hzpbin*((double)Plotdata[Plotindex][1009])); //stopindex stored in 1009 Plotdata[Plotindex][I]=(int)(Corr-10.0*Fw+10.0*(C5/F+C1+F*(C2+F*(C3+F*C4)))); //**3562 needs to be checked if (Plotindex<=2) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+(int)(100.0*log10(1.0+1.0/Ww));} } for (I=Cutoff+1;I<=Maxi;I++) { F=I*Hzpbin; F=FNMax(F,Hzpbin*(double)(Plotdata[Plotindex][1009])); Plotdata[Plotindex][I]=(int)(Corr+10*(C5/F+C1+F*(C2+F*(C3+F*C4)))); //**3562 needs to be checked if (Plotindex<=2) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+(int)(100.0*log10(1.0+1.0/(Rc2pi*F*F)));} } } else //Cal no vco if (Measuretype==1) { Corr=10*(Bwcorr-20*log10(Phaseslope)-Gain); for (I=1;I<=Maxi;I++) { F=I*Hzpbin; F=FNMax(F,Hzpbin*(Plotdata[Plotindex][1009])); Plotdata[Plotindex][I]=Corr+10.0*(C5/F+C1+F*(C2+F*(C3+F*C4))); if (Plotindex<=2) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+100.0*log10(1.0+1.0/(Rc2pi*F*F));} } } else //Cal discrim if (Measuretype==2) { // VCOSLOPE IS THE RECIPROCAL OF THE DISCRIMINATOR CONSTANT // S PHI(F)=V^2 * (Hz/V)^2 / F^2 = S NU / F^2 Corr=10.0*(Bwcorr+20.0*log10(Vcoslope)-Gain); for (I=1;I<=Maxi;I++) { F=I*Hzpbin; F=FNMax(F,Hzpbin*(Plotdata[Plotindex][1009])); Plotdata[Plotindex][I]=Corr+10.0*(-20.0*log10((double)I*Hzpbin)+C5/F+C1+F*(C2+F*(C3+F*C4))); if (Plotindex<=2) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+100.0*log10(1.0+1.0/(Rc2pi*F*F));} } } else { printf("!! Error: Unknown measurement type: %d\n",Measuretype); } } } #define C_Phaseslope 0 #define C_Gain1 1 #define C_Gain2 2 #define C_Atten1 3 #define C_Atten2 4 #define C_Vcoslope 5 #define C_Vpeak 6 #define C_DAC 7 void writef_cal(char fname[100]) { calparameters[C_Phaseslope]=Phaseslope; calparameters[C_Vcoslope]=Vcoslope; calparameters[C_Vpeak]=Vpeak; FILE *f = fopen(fname, "wb"); printf("Storing cal data in file %s ...",fname); fwrite(caltexts, sizeof(char), sizeof(caltexts), f); fwrite(calparameters, sizeof(char), sizeof(calparameters), f); fwrite(Caldata, sizeof(char), sizeof(Caldata), f); fclose(f); printf(" Done.\n"); } void readf_cal(char fname[100]) { FILE *f = fopen(fname, "r"); printf("Reading cal data from file %s ...",fname); fread(caltexts, sizeof(char), sizeof(caltexts), f); fread(calparameters, sizeof(char), sizeof(calparameters), f); fread(Caldata, sizeof(char), sizeof(Caldata), f); fclose(f); printf(" Done.\n"); Phaseslope=calparameters[C_Phaseslope]; Vcoslope=calparameters[C_Vcoslope]; Vpeak=calparameters[C_Vpeak]; printf("VCOSLOPE=%e Hz/V\n",Vcoslope/Atten1); printf("PHASESLOPE=%e V/rad\n",Phaseslope); printf("VPEAK=%0.2f V\n",Vpeak); } void writef_trace(char fname[100]) { FILE *f = fopen(fname, "wb"); printf("Storing trace data in file %s ...",fname); fwrite(tracetexts, sizeof(char), sizeof(tracetexts), f); fwrite(traceparameters, sizeof(char), sizeof(traceparameters), f); fwrite(tracedata, sizeof(char), sizeof(tracedata), f); fclose(f); printf(" Done.\n"); } void writef_tracetxt(char fname[100]) { int I,J; int startbin,stopbin; double hzpbin; double freq; FILE *f = fopen(fname, "wb"); printf("Storing trace data (text) in file %s ...",fname); //fwrite(traceparameters, sizeof(char), sizeof(traceparameters), f); //fwrite(traceparameters, sizeof(char), sizeof(traceparameters), f); fprintf(f,"PHASE NOISE TRACE DATA\n"); for (I=1;I<=13;I++) { if (tracedata[I][1007]>0.1) //valid segment { if (I>=11) { startbin=P85[I][1008]; stopbin=P85[I][1009]; hzpbin=(double)P85[I][1010]; } else { startbin=P82[I][1008]; stopbin=P82[I][1009]; hzpbin=(double)P82[I][1010]; } if (I>10) {hzpbin=hzpbin*10;} else //{hzpbin=hzpbin/250;} {hzpbin=hzpbin/800.0;} //fprintf(f,"SEG %i\n",I); //printf("%i %i %i\n",I,startbin,stopbin); //printf("%i %i %i\n",I,P85[I][0],P85[I][1]); for (J=startbin;J<=stopbin;J++) { freq=hzpbin*(double)J; // fprintf(f,"TRA: %i: %0.3f Hz, %0.2f dBc\n",J-startbin,freq,tracedata[I][J]); if (I>=11) { fprintf(f,"%i %i %0.2f %0.1f %0.1f %0.1f\n",I,J-startbin,freq,tracedata[I][J],0.1*(double)P85_C[I][J],tracedata[I][J]+0.1*(double)P85_C[I][J]); } else { fprintf(f,"%i %i %0.2f %0.1f %0.1f %0.1f\n",I,J-startbin,freq,tracedata[I][J],0.1*(double)P82_C[I][J],tracedata[I][J]+0.1*(double)P82_C[I][J]); } } } } //fwrite(tracedata, sizeof(char), sizeof(tracedata), f); fprintf(f,"EOF\n"); fclose(f); printf(" Done.\n"); } int Measuretype_t, Caltype_t; void do_trace_corr() //calculated trace data from valid P82, P85 data { int I,J; //for the 3562a data for (I=3;I<=10;I++) //segment 3 is lowest segment fo 3562a { if (P82[I][1007]==1) { P82_C[I][1008]=P82[I][1008]; P82_C[I][1009]=P82[I][1009]; P82_C[I][1010]=P82[I][1010]; printf("Correction... LF Segment %i\n",I); Phioff(P82_C,I,Vcoindex,Measuretype_t,Amplifier,Mixer,W1,W2,W3,Loopbw1,Phaseslope,Vcoslope,Vcofreq); } } for (I=3;I<=10;I++) { if (P82[I][1007]==1) //valid data { for(J=0;J<=800;J++) { tracedata[I][J]=((double)P82[I][J])/10.0; } tracedata[I][1007]=1.0; //valid data } } //Phioff(int Plotdata[][1012], int Plotindex,int Vcoindex,int Measuretype,int Amplifier,double Mixerfreq,double W1,double W2,double W3,double Loopbw1,double Phaseslope,double Vcoslope,double Vcofreq) for (I=11;I<=13;I++) { if (P85[I][1007]==1) { P85_C[I][1008]=P85[I][1008]; P85_C[I][1009]=P85[I][1009]; P85_C[I][1010]=P85[I][1010]; printf("Correction... HF Segment %i\n",I); Phioff(P85_C,I,Vcoindex,Measuretype_t,Amplifier,Mixer,W1,W2,W3,Loopbw1,Phaseslope,Vcoslope,Vcofreq); } } for (I=11;I<=13;I++) { if (P85[I][1007]==1) //valid data { for(J=0;J<=1000;J++) { tracedata[I][J]=((double)P85[I][J])/10.0; } tracedata[I][1007]=1.0; //valid data } } } void w3562(char *buf) { ibwrt(Device3562, buf, strlen(buf)); if (Ibsta() & ERR) { GpibError("ibwrt Error"); } } void w3562b(char *buf, int len) { ibwrt(Device3562, buf, len); if (Ibsta() & ERR) { GpibError("ibwrt Error"); } } void w3562d(char *buf) //for debug only { printf("Command: >%s<\n",buf); printf("Length: %i bytes\n",strlen(buf)); ibwrt(Device3562, buf, strlen(buf)); if (Ibsta() & ERR) { GpibError("ibwrt Error"); } } void r3562(int cnt) { ibrd(Device3562, Buffer, cnt); //read if (Ibsta() & ERR) { GpibError("ibrd Error"); } } unsigned char Display3562[20000]; double Display3562t[810]; //0 to 800, 801 data points double Display3562p[80]; //parameters double Display3562bn[10000]; //binary void rd3562(int len) { ibrd(Device3562, Display3562, len); //read if (Ibsta() & ERR) { GpibError("ibrd Error"); } } void rd3562b(int len) { ibrd(Device3562, Display3562bn, len); //read if (Ibsta() & ERR) { GpibError("ibrd Error"); } } char istate3562[1000];//instrument state int istate3562_set=0; void i3562_savestate(void) { int i; int datal; w3562("DSAN"); r3562(4); //printf("%c %c\n",Buffer[0],Buffer[1]); datal=Buffer[2]; datal=datal<<8; datal|=Buffer[3]; istate3562[0]=Buffer[2];//length data istate3562[1]=Buffer[3];//length data printf("3562A: %i bytes state dump received\n",datal); r3562(datal); if (datal==768) { for (i=0;i0) { w3562("LSAN#A"); w3562b(istate3562,istate3562_set+2);//dump 2 bytes length and 768 bytes state data printf("Recalled 3562A state OK.\n"); } else { printf("!! Error: Cannot recall 3562A state - no state saved.\n"); } } int rangelevel3562[11]={0,0,27,20,10,0,-10,-20,-30,-40,-50}; //values in dbvrms char range_s3562[20]; int range_3562; double i3562_irtodouble(int i) //convert 3562 internal float to double { long int m_t; int e_t; double d1,d2,d3; m_t=(Display3562[i]<<16)|(Display3562[i+1]<<8)|(Display3562[i+2]); e_t=(signed char) Display3562[i+3]; d1=(double)(m_t&0x7fffff); if ((m_t&0x800000)==0x800000) { d1=-(8388608.0-d1); //0x800000 hex 2 complements } d2=(double)e_t; d3=pow(2,e_t)*d1/pow(2,23); return d3; } void i3562_autorange(void) { int i,j; unsigned long LocalIbsta; char SpollByte; ibclr(Device3562); /* Clear the device */ //w3562("PRST;LNRS;PSP2;FLAT;FLT1;FLT2;MGDB;PSPC;AUTO0;CH2;"); w3562("AVOF;"); w3562("SRQE;ISM64;"); w3562("FRS100kHz;"); printf("3562 autorange... dBVrms = "); i=2; // 2 is highest range j=0; do { sprintf(range_s3562,"C2RG%iDBV;",rangelevel3562[i]); w3562(range_s3562); //set range w3562("STRT"); //start, otherwise it doesn't sense overrange wait_s01(30); LocalIbsta = ibrsp (Device3562, &SpollByte); if (LocalIbsta & ERR) { printf ("\n!!Error: ibrsp failed. No more callbacks.\n"); } //printf("%x \n",(unsigned char)SpollByte); printf("%i ",rangelevel3562[i]); if ((SpollByte&0x8f)==0x0b)//status change { w3562("SOV2;"); r3562(1); //printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]); if (Buffer[0]==0x32) { printf(" Overload!"); j=200; } } else { wait_s01(10);} //spoll every 1 s i++; } while (!((i>=11)|(j==200))); //no more than 100 seconds if (i==11) { if (j!=200){j=200;i=12;}};//if overrange is not reached in 10th range, set to 10th. i=i-2; if (j!=200) { printf("\n!!Error: 3562A autorange not complete!\n"); range_3562=0; } else { printf("\n3562 autorange complete. Range: %i, %i\n",i,rangelevel3562[i]); range_3562=i; } } void i3562_setrange_c2(int range_i)//ranges 2 to 10 { ibclr(Device3562); /* Clear the device */ sprintf(range_s3562,"C2RG%iDBV;",rangelevel3562[range_i]); w3562(range_s3562); //set range } void i3562_pwrspec_init(void) //init for pwr spectrum { ibclr(Device3562); /* Clear the device */ w3562("PRST;LNRS;PSP2;FLAT;FLT1;FLT2;MGDB;PSPC;AUTO0;CH2;STBL;PSUN;VTRM;VLTS;"); w3562("YSCL-150,10DB;"); wait_s01(50); w3562("NAVG1ENT;");//1 avg stable mean w3562("FRS1000Hz;C2RG3DBV;"); w3562("SRQE;ISM4;");//enable SRQ and set end of meas mask w3562("STRT");//run to acquire some dummy data } void i3562_pwrspec(int segment_i,int range_i, int avg_i) //acquire pwr spectrum { unsigned long LocalIbsta; char SpollByte; time_t t; int i,j,c1,c2,k; char t_s[100]; char tbuf[100]; int datal,datal2; double d_t,d1,d2,d3; double maxrange,perdiv; long int m_t; int e_t; int timeout; ibclr(Device3562); /* Clear the device */ sprintf(tbuf,"NAVG%iENT;FRS%iHz;C2RG%iDBV;",avg_i,P[segment_i][2],rangelevel3562[range_i]); w3562d(tbuf); w3562("SRQE;ISM4;");//enable SRQ and set end of meas mask w3562("STRT"); if (segment_i>6) {timeout=10;} else {timeout=100;} //1 s or 10 s timeout //getchar(); i=0; do { LocalIbsta = ibrsp (Device3562, &SpollByte); if (LocalIbsta & ERR) { printf ("!!Error:ibrsp failed. No more callbacks.\n"); } printf("%x ",(unsigned char)SpollByte); //w3562("IS?"); //rd3562(2); //printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]); if ((SpollByte&0x8f)==0x0b)//status change { w3562("IS?;"); r3562(2); printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]); //printf("%x %x\n",(unsigned char)Buffer[0]&0x04,(unsigned char)Buffer[1]); if ((Buffer[1]&0x04)==0x04) { i=200; } else {i=300;}//some other SRQ must have occured } else { wait_s01(timeout);} //spoll every 1 s or 10 s i++; } while (i<150); //no more than 150 //1500 seconds if (i!=201) { printf("!!Error: 3562A acquisition timeout! %i\n",i); } else {printf("3562A: Acquisition complete!\n");} ibclr(Device3562); /* Clear the device */ w3562("DDBN"); //dump binary r3562(4); datal=Buffer[2]; datal=datal<<8; datal|=Buffer[3]; printf("3562A: %i bytes binary data dump received\n\n",datal); rd3562(datal); c1=0; for (i=168;i0)&&(Display3562t[i+1]<0)) printf("-: %i ",i); if ((Display3562t[i]<0)&&(Display3562t[i+1]>0)) printf("+: %i ",i); } } } void main() { char *commandset=(char *) malloc (255); //command string separated by komma //char *token=(char *) malloc (255); //char *cp=(char *) malloc (255); unsigned long LocalIbsta; char SpollByte; time_t t; int i,j; /* Intializes random number generator */ srand((unsigned) time(&t)); //for (i=0;i<1000;i++) {printf("%0.5f ",frand());} //writef_trace("c:\\werkstatt\\pn\\testtrace.bnoise"); //tracedata[11][1007]=1; //tracedata[12][1007]=1; //tracedata[13][1007]=1; //writef_tracetxt("c:\\werkstatt\\pn\\testtrace.pdat"); /***************************************************************************** * Initialization - Done only once at the beginning of your application. *****************************************************************************/ Device35601 = ibdev( /* Create a unit descriptor handle */ BoardIndex, /* Board Index (GPIB0 = 0, GPIB1 = 1, ...) */ PrimaryAddress35601, /* Device primary address */ SecondaryAddress35601, /* Device secondary address */ T10s, /* Timeout setting (T10s = 10 seconds) */ 1, /* Assert EOI line at end of write */ 0); /* EOS termination mode */ if (Ibsta() & ERR) { /* Check for GPIB Error */ GpibError("ibdev Error"); } ibclr(Device35601); /* Clear the device */ if (Ibsta() & ERR) { GpibError("ibclr Error"); } Device3585 = ibdev( /* Create a unit descriptor handle */ BoardIndex, /* Board Index (GPIB0 = 0, GPIB1 = 1, ...) */ PrimaryAddress3585, /* Device primary address */ SecondaryAddress3585, /* Device secondary address */ T10s, /* Timeout setting (T10s = 10 seconds) */ 1, /* Assert EOI line at end of write */ 0); /* EOS termination mode */ if (Ibsta() & ERR) { /* Check for GPIB Error */ GpibError("ibdev Error"); } ibclr(Device3585); /* Clear the device */ if (Ibsta() & ERR) { GpibError("ibclr Error"); } Device3562 = ibdev( /* Create a unit descriptor handle */ BoardIndex, /* Board Index (GPIB0 = 0, GPIB1 = 1, ...) */ PrimaryAddress3562, /* Device primary address */ SecondaryAddress3562, /* Device secondary address */ T10s, /* Timeout setting (T10s = 10 seconds) */ 1, /* Assert EOI line at end of write */ 0); /* EOS termination mode */ if (Ibsta() & ERR) { /* Check for GPIB Error */ GpibError("ibdev Error"); } ibclr(Device3562); /* Clear the device */ if (Ibsta() & ERR) { GpibError("ibclr Error"); } /* range_3562=7; i3562_pwrspec_init(); i3562_pwrspec(10,range_3562,4); i3562_pwrspec(10,range_3562,4); getchar(); exit(1); */ //i3562_timeb(); toggle_i(NOCOMMAND); //make sure the GPIB is working with 35601a interface toggle_i(OVERLOAD); // commandset= "-K6,-K7,-K1,-K13,K8,K9,-K11,K12,K10,S3,-S4"; // commandset= "-K1,-K13,K8,K9,K11,K12,K10,S3,-S4"; //40 db gain //commandset= "K6,K7,S2,-K1,-K13,K8,K9,-K11,K12,K10,S3,-S4"; //tracking gen // commandset= "-K6,-K7,-K1,-K13,K8,K9,-K11,K12,-K10,-S1,-S2,-S3,-S4";//loop open //printf("%f\n",DROUND(22423432.3434234,9)); //Cal(); //printf("PRESS ANY KEY!\n"); //getchar(); zerolatch(); /* setup_i("K1,K8,K9,K11,S7,L1,L3,L5,L8,L9,K12,-K10,-S3,-S4"); setup_i("F1"); toggle_i(TOGGLEACDC); getchar(); setup_i("F2"); toggle_i(TOGGLEACDC); getchar(); setup_i("F0"); toggle_i(TOGGLEACDC); getchar(); getchar(); exit(1); */ Gain1=6.0; Gain2=6.0; Amplifier=0; getuserparms(); //readf_cal("c:\\werkstatt\\pn\\testcal.cal"); //need to watch out for atten1 values etc value_i(DAC,0.00);//0.1 value_i(GAIN1,Gain1);//6 value_i(GAIN2,Gain2);//20 value_i(LEADLAG,0);//2 value_i(ATTEN1,Atten1db);//0 value_i(ATTEN2,Atten2db);//0 setup_i("K12,K10,S3,S8,L1,L3,L5,L8,L9,S4"); //close loop //printf("...\n\n"); //getchar(); Measuretype_t=0; //phase noise measurement Caltype_t=2; //beatnote measurement of constant setup_i("L1,L3,L5,L8,L9,K12,-K10,-S3,-S4"); //loop is open if (Mixerfreq<9.5E+7) {setup_i("K8,K9"); printf("2 MHz LPF is IN\n");} // ! 2MHz LPF if (Mixerfreq>=9.5E+7) {setup_i("-K8,-K9"); printf("2 MHz LPF is OUT\n");} //LFP out if (Mixer==1) {setup_i("-K13");} if (Mixer==2) {setup_i("K13");} if (Mixer<3) {setup_i("-K1");} //internal mixers if (Mixer==3) {setup_i("K1");} //External mixer print_i_setup(); //printf("%f\n",FNPround(21172.213143213,-4)); readf_cal("c:\\werkstatt\\pn\\testcal.cal"); Approxfreq=28800e3; autorange85(); getvcoslope(); Getphaseslope(Vbeatnote,Fbeatnote,Measuretype_t,Caltype_t); // writef_cal("c:\\werkstatt\\pn\\testcal.cal"); // readf_cal("c:\\werkstatt\\pn\\testcal.cal"); // printf("Press key...\n"); // getchar(); Charloop(); // printf("Press key to start PN measurement...\n"); // getchar(); printf("Setting up for PN measurement...\n"); // print_i_setup(); zerolatch(); setup_i("K12,K10,S3,S8,L1,L3,L5,L8,L9,S4"); //close loop value_i(DAC,Lockvoltage);//0.1 value_i(GAIN1,Gain1);//6 value_i(GAIN2,Gain2);//20 value_i(LEADLAG,Laglead);//2 value_i(ATTEN1,Atten1db);//0 value_i(ATTEN2,Atten2db);//0 // print_i_setup(); // printf("lead and atten is set...\n"); // getchar(); setup_i("K12,K10,S3,S8,L1,L3,L5,L8,L9,S4"); //close loop //printf("close sent\n"); //printf("Ampl %i\n",Amplifier); //getchar(); Amplifier=1; if (Amplifier==1) {setup_i("K11");} else {setup_i("-K11");} if (Amplifier==0) { setup_i("S8");} if (Amplifier==1) { setup_i("S7");} //route the correct signal to the LF board if (Mixerfreq<9.5E+7) {setup_i("K8,K9"); printf("2 MHz LPF is IN\n");} // ! 2MHz LPF if (Mixerfreq>=9.5E+7) {setup_i("-K8,-K9"); printf("2 MHz LPF is OUT\n");} //LFP out if (Mixer==1) {setup_i("-K13");} if (Mixer==2) {setup_i("K13");} if (Mixer<3) {setup_i("-K1");} //internal mixers if (Mixer==3) {setup_i("K1");} //External mixer //value_i(DAC,Lockvoltage);//set DAC for lock voltage // printf("DAC set at: %0.3f Volt\n",Lockvoltage); // print_i_setup(); commandset= "-K6,-K7,K12,K10,-S1,-S2,S3,S4";//loop closed setup_i(commandset); wait_s01(20); toggle_i(OUTOFLOCK); //printf("Press key to start PN measurement...\n"); //getchar(); printf("Start PN measurement...\n"); printf("Running getdata...\n"); getdata(); //** need to add autorange after each filter change range_3562=7; i3562_pwrspec_init(); setup_i("F0"); //seg 3: F2; seg 4-6 F1, seg 7- F0; toggle_i(TOGGLEACDC); i3562_pwrspec(10,range_3562,30); i3562_pwrspec(9,range_3562,30); i3562_pwrspec(8,range_3562,30); i3562_pwrspec(7,range_3562,30); setup_i("F1"); //seg 3: F2; seg 4-6 F1, seg 7- F0; toggle_i(TOGGLEACDC); i3562_pwrspec(6,range_3562,5); //5 i3562_pwrspec(5,range_3562,4); //4 /* i3562_pwrspec(4,range_3562,3); //3 setup_i("F2"); //seg 3: F2; seg 4-6 F1, seg 7- F0; toggle_i(TOGGLEACDC); i3562_pwrspec(3,range_3562,2); //3 */ setup_i("F0"); //seg 3: F2; seg 4-6 F1, seg 7- F0; toggle_i(TOGGLEACDC); do_trace_corr(); writef_tracetxt("c:\\werkstatt\\pn\\test10e amp 5khz 8645a 288000.pnd"); /***************************************************************************** * Uninitialization - Done only once at the end of your application. *****************************************************************************/ ibonl(Device35601, 0); /* Take the device offline */ if (Ibsta() & ERR) { GpibError("ibonl Error"); } ibonl(Device3585, 0); /* Take the device offline */ if (Ibsta() & ERR) { GpibError("ibonl Error"); } exit(0); } /***************************************************************************** * Function GPIBERROR * This function will notify you that a NI-488 function failed by * printing an error message. The status variable IBSTA will also be * printed in hexadecimal along with the mnemonic meaning of the bit * position. The status variable IBERR will be printed in decimal * along with the mnemonic meaning of the decimal value. The status * variable IBCNT will be printed in decimal. * * The NI-488 function IBONL is called to disable the hardware and * software. * * The EXIT function will terminate this program. *****************************************************************************/ void GpibError(const char *msg) { printf("%s\n", msg); printf("Ibsta() = 0x%x <", Ibsta()); if (Ibsta() & ERR ) printf(" ERR"); if (Ibsta() & TIMO) printf(" TIMO"); if (Ibsta() & END ) printf(" END"); if (Ibsta() & SRQI) printf(" SRQI"); if (Ibsta() & RQS ) printf(" RQS"); if (Ibsta() & CMPL) printf(" CMPL"); if (Ibsta() & LOK ) printf(" LOK"); if (Ibsta() & REM ) printf(" REM"); if (Ibsta() & CIC ) printf(" CIC"); if (Ibsta() & ATN ) printf(" ATN"); if (Ibsta() & TACS) printf(" TACS"); if (Ibsta() & LACS) printf(" LACS"); if (Ibsta() & DTAS) printf(" DTAS"); if (Ibsta() & DCAS) printf(" DCAS"); printf (" >\n"); printf ("Iberr() = %d", Iberr()); if (Iberr() == EDVR) printf(" EDVR \n"); if (Iberr() == ECIC) printf(" ECIC \n"); if (Iberr() == ENOL) printf(" ENOL \n"); if (Iberr() == EADR) printf(" EADR
\n"); if (Iberr() == EARG) printf(" EARG \n"); if (Iberr() == ESAC) printf(" ESAC \n"); if (Iberr() == EABO) printf(" EABO \n"); if (Iberr() == ENEB) printf(" ENEB \n"); if (Iberr() == EOIP) printf(" EOIP \n"); if (Iberr() == ECAP) printf(" ECAP \n"); if (Iberr() == EFSO) printf(" EFSO \n"); if (Iberr() == EBUS) printf(" EBUS \n"); if (Iberr() == ESTB) printf(" ESTB \n"); if (Iberr() == ESRQ) printf(" ESRQ \n"); if (Iberr() == ETAB) printf(" ETAB \n"); if (Iberr() == ELCK) printf(" ELCK \n"); if (Iberr() == EARM) printf(" EARM \n"); if (Iberr() == EHDL) printf(" EHDL \n"); if (Iberr() == EWIP) printf(" EWIP \n"); if (Iberr() == ERST) printf(" ERST \n"); if (Iberr() == EPWR) printf(" EPWR \n"); printf("Ibcnt() = %u\n", Ibcnt()); printf("\n"); /* Call ibonl to take the device and interface offline */ //ibonl(Device, 0); exit(1); }