// 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) //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 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>t) {t=a2;} return t; } double FNMax3(double a1, double a2, double a3) //return max value of set of values { double t; t=a1; if (a2>t) {t=a2;} if (a3>t) {t=a3;} 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,u_nr; 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 ((!clearl)&&((k_nr>=5)&&(k_nr<=8))) { for (u_nr=5;u_nr<=8;u_nr++) //clear latches for 3582a input selector {latchd[(s_v[u_nr<<1]<<1)+1] &= ~(1<<(s_v[(u_nr<<1) + 1]-1));} printf("S5 to S8 cleared\n"); } 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))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=13;} } int rangedbv; int stat; unsigned char Buffer[10000]; /* Read buffer */ unsigned int Display3585[1002]; double Loopbw1,Loopbw2,Loopbw3,W1,W2,W3; double Loopbw1_actual; double Vcofreq,Spec; int Vcoindex, Vcoport; double Laglead; double Zerofreq[]={9.95,40.1,115.9,306,784,1.985E3,5E3,12.58E3,31612,79421,199511,501164}; // !Actual Leadfreqs for each lag-lead // ! Plus 4 EXTERNAL lag-leads double Laglead2; // !Effective Lag-lead if external lag-lead used double C8=3.3E-8; // ! .033 uf double R25=4.823E+5; // ! 482K ohm /* 10984 ! * NAME: Fnw 10990 ! * FUNCTION: Compute the xfer function value at W 10996 ! * INPUT: W, W1, W2, W3, Bw1 11002 ! * OUTPUT: Returns the xfer funtion value */ double FNW(double W,double W1,double W2,double W3,double Bw1) { double Ang; // !Phase angle of loop correction double Fw; // !F(w) -- loop correction factor double Pole; double R;// !Magnitude of loop correction double Ww;// !W squared double Ww1;// !W1 squared double Ww2;// !W2 squared double Ww3;// !W3 squared Ww=W*W; Ww1=W1*W1*4.0; Ww2=W2*W2; Ww3=W3*W3; // ! W0=1/2 R=2*M_PI*Bw1/W*sqrt((1+Ww/Ww2)*(1+0.25/Ww)/(1+Ww/Ww3)/(1+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*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; 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 printf("\nLoopbw1: %0.1f W3: %0.1f W2: %0.1f \n", Loopbw1,W3,W2); Loopbw3=Loopbw1*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,Loopbw1); Fwhigh=FNW(High,1.0E+7,W2,W3,Loopbw1); // printf("Loopbw3: %0.1f Span: %0.1f\n", Loopbw3,Span); 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=%0.1f\n",Peaking); // ! DEL printf("INITIAL W1=%0.1f\n",W1); // ! DEL //printf("W2=%0.1f Loopbw1=%0.1f\n",W2,Loopbw1); // ! 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,Loopbw1); Delta=0.015+0.01*frand(); Slope=(FNW(W,W1+W1*Delta,W2,W3,Loopbw1)-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 Loopbw1 -- 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,Loopbw1); Delta=0.015+0.01*frand(); Slope=(FNW(W,W1,W2,W3,Loopbw1+Loopbw1*Delta)-Fw)/(Loopbw1*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)>(Loopbw1/4.0)) {Corr=Loopbw1/4.0*fsgn(Corr);} Loopbw1=Corr+Loopbw1; Oldersum=Errsum; } }//loopcount //11422 Diffcorrret: ! printf("FINAL W1=%0.1f\n",W1);// ! DEL printf("MAX ERROR IN DIFCORRECTION IS: %0.2e\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 waitfor3585(void) { char stat; do { w3585("D6T4"); r3585(2); stat=Buffer[0]; } while ((stat&0x80)==0x80); //wait until sweep complete } 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); } 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[2100]; //0 to 800, 801 data points for spectrum, 0 to 2047, 2048 points for time 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("RST;SNGL;"); // wait_s01(300); 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 wait_s01(20); } 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;",avg_i,P[segment_i][2]); w3562(tbuf); if (rangelevel3562[range_i]==100) { w3562("C2RG-10DBV;AU2U;");//AUTORANGE } else { sprintf(tbuf,"C2RG%iDBV;",rangelevel3562[range_i]); w3562(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); // } dsum=0.0; for (i=0;i<2047;i++) { dsum+=Display3562t[i]; } dsum=dsum/2048.0; for (i=0;i<2047;i++) { Display3562i[i]=(int)( (Display3562t[i]-dsum)/maxrange*512.0); //scale to -512 to +512 } i3562_timeb_valid=1; } } void i3562_charloop_init(int frange_i,int avg_i) { char tbuf[100]; ibclr(Device3562); /* Clear the device */ w3562("PRST;LNRS;FRSP;FRQR;HANN;FLT1;FLT2;MGDB;AUTO0;CH12;"); w3562("YSCL-40,40DB;"); wait_s01(50); w3562("SRCE;RND;SRLV0.50VRMS;"); wait_s01(5); sprintf(tbuf,"FRS%iHz;EXP;AVG%iENT;",frange_i,avg_i); w3562(tbuf); w3562("C2RG-10DBV;AU2U;C1RG-10DBV;AU1U;");//AUTORANGE w3562("SRQE;ISM4;");//enable SRQ and set end of meas mask w3562("STRT;");//run to acquire some dummy data wait_s01(20); } void i3562_charloop(int frange_i,int avg_i) { 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,yscalef; long int m_t; int e_t; int timeout; Display3562t[1000]=-1234.0;//to identify correct record later LocalIbsta = ibrsp (Device3562, &SpollByte); if (LocalIbsta & ERR) { printf ("!!Error:ibrsp failed. No more callbacks.\n"); } wait_s01(10); ibclr(Device3562); // Clear the device sprintf(tbuf,"FRS%iHz;STBL;NAVG%iENT;",frange_i,avg_i); w3562(tbuf); w3562("C1RG-10DBV;AU1U;C2RG-10DBV;AU2U;");//AUTORANGE wait_s01(50); ibclr(Device3562); // Clear the device w3562("SRQE;ISM4;");//enable SRQ and set end of meas mask w3562("STRT;FRQR;"); wait_s01(10); timeout=10+(int)(25.0*1.0/(double)frange_i); //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");} wait_s01(1); ibclr(Device3562); // Clear the device w3562d("DCBN"); //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); //datal=3500; rd3562(datal); ibclr(Device3562); /* Clear the device */ //for (i=0;i<4000;i++) //{ // printf("%c",(unsigned char) Display3562[i]); //} c1=0; for (i=156+168;i=0); //0 to 2047 Startbin=0; Startbinfound=0; do { Startbin++; // printf("%i ",Display3562i[Startbin]); if (Sign!=(Display3562i[Startbin]>=0)) { Startbinfound=Startbin; // printf("Startbinfound %i\n",Startbin); } } while ((Startbin<2047)&&(Startbinfound==0)); Startbin=Startbinfound; //printf("Startbin %i\n",Startbin); if (Startbinfound>0) //1st zero found { Crossingcount=1; Lastbin=Startbin; Sign=(Display3562i[Startbin]>=0); Startbin_d=(double)Startbin; if ((Display3562i[Startbin]-Display3562i[Startbin-1])!=0) { Startbin_d-=(double) Display3562i[Startbin]*1.0/(Display3562i[Startbin]-Display3562i[Startbin-1]); } // FIND POINT THAT IS HALF PEAK VALUE do{ Binn=Lastbin; do { Binn++; } while (!((Binn>2047)||((Sign==1) && (Display3562i[Binn]>Maxx))||((Sign==0) && (Display3562i[Binn]=0))); if (Binn<2047) { Sign=(Display3562i[Binn]>=0); Crossingcount++; if (((Crossingcount-1)%2)==0) {Endbinn=Binn;} Lastbin=Binn; } } } while (Binn<2047); if (Crossingcount>=3) { Endbin_d=(double)Endbinn; if ((Display3562i[Endbinn]-Display3562i[Endbinn-1])!=0) { Endbin_d-=(double)Display3562i[Endbinn]*1.0/(Display3562i[Endbinn]-Display3562i[Endbinn-1]); } Numcycles=(Crossingcount-1) /2; // printf("Crossings %i ",Crossingcount); // printf("Start: %0.1f ",Startbin_d); // printf("End: %0.1f: ",Endbin_d); Newfreq_t=1.0/( ((Endbin_d-Startbin_d))/((double)Numcycles)*T_t/2048.0); // printf("Frequency found %0.6f\n",Newfreq_t); Newfreq=Newfreq_t; } else { printf("!! Error: Could not find sufficient zero crossings (%i found)!\n",Crossingcount); } } else { printf("!! Error: Could not find any zero crossing!\n"); //this error should not occur because of normalization/offset } } 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... %0.1f Hz approx. ", Approxfreq); 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; // 3562a ranges for <=100 Hz if (Rangenum==3) { if (!i3562_init_done) {i3562_timeb_init();i3562_init_done=1;} if (Newfreq<=0) { i3562_timeb(0.4); i3562_frqcalc(0.4); } if (Newfreq<=0) { i3562_timeb(1.6); i3562_frqcalc(1.6); } if (Newfreq<=0) { i3562_timeb(16.0); i3562_frqcalc(16.0); } if (Newfreq<=0) { i3562_timeb(80.0); i3562_frqcalc(80.0); } if (Newfreq<=0) { i3562_timeb(320.0); i3562_frqcalc(320.0); } } frange++; } while ((frange<=3) && (Newfreq<0.01)); if (Newfreq>4.01E+7) {Newfreq=0;} if (Newfreq<.015) {Newfreq=0;} if (Newfreq>0) { printf("beat frequency found [Hz]: %8.1f\n",Newfreq); } else { printf("!!Error: Could not find beat frequency!\n"); } } 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; i3562_init_done=0; 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");} } 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; int SpanF; //max frequency of 3562 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: %0.2f\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 */ // } } } else //use lf analyzer 3562a { SpanF=25000; if (Fmax<10000) {SpanF=10000;} if (Fmax<4000) {SpanF=4000;} if (Fmax<2000) {SpanF=2000;} if (Fmax<1000) {SpanF=1000;} if (Fmax<400) {SpanF=400;} if (Fmax<200) {SpanF=200;} if (Fmax<100) {SpanF=100;} if (Fmax<40) {SpanF=40;} if (Fmax<20) {SpanF=20;} if (Fmax<10) {SpanF=10;} if (Fmax<4) {SpanF=4;} if (Fmax<2) {SpanF=2;} if (Fmax<1) {SpanF=1;} Hzpbin=SpanF/800.0; i3562_pwrspec_init(); rangelevel3562[0]=100;//autorange 3562 P[0][2]=SpanF; i3562_pwrspec(0,0,1); /* Sens=5-Rangedbv/10; 12193 Setupsens: ! 12196 Sens=FNMax(2,Sens-1) 12199 OUTPUT I3582;"HLT PRS AA0 AB0 MD2 IM3 BC2 RP0 AB1" 12202 OUTPUT I3582 USING "K,DD,K";"BS",Sens,"RUN" 12205 OUTPUT I3582 USING "K,DD,K";"SP",Span,"RE LST0" 12208 ENTER I3582 USING "#,B";Stat 12211 OUTPUT I3582;"AR" 12214 ! Load binary routine into 3582 12217 OUTPUT I3582 USING "12A,/,10(W)";"WTM,77200,10",46,12297,5,-3068,921,24617,13209,39,12297,-5680 12220 ! 12223 Waitloop: ! 12226 OUTPUT I3582;"HLT,EXE,77200,RUN,LST1" ! execute binary routine 12229 ENTER I3582 USING "#,B";Stat 12232 IF BIT(Stat,3) THEN Setupsens !IF OVERLOAD, BACK OFF SENSITIVITY 12235 IF NOT BIT(Stat,5) THEN Waitloop 12238 ! 12241 ! Load display from 3582 12244 OUTPUT I3582;"HLTLFM,74400,256" 12247 ENTER I3582 USING "#,W";Display(*) 12250 OUTPUT I3582;"RUN" */ Maxx=-2000; for (Binn=0;Binn<=(800-(int)(Freq/5.0/Hzpbin));Binn++) { // printf("%i ",P82[0][Binn]); if (P82[0][Binn]>Maxx) {Maxbin=Binn;} Maxx=FNMax(P82[0][Binn],Maxx); } // printf("found maxx: %i at %i",Maxx,Maxbin); Freq=Maxbin*Hzpbin; printf("Beat note found at %0.2f\n",Freq); Sign=1; Phaseslope=0; Numharmonics=9; if ((Measuretype==2) | (Measuretype==1) & (Caltype!=2)) {Numharmonics=1;} //IF Measuretype#0, NOT A BEATNOTE for (Harmonic=1;Harmonic<=Numharmonics;Harmonic=Harmonic+2) { Binn=(int)(Freq*(double)Harmonic/Hzpbin); Maxx=-5000; // ! Find max display value of specific harmonic, searching +-5 bins // use +-15 bins because of 800 points for 3562a for (Binc=FNMax(2,Binn-15);Binc<=FNMin(799,Binn+15); Binc++) { Maxx=FNMax(Maxx,P82[0][Binc]); // printf("%i,%i\n",Binc,P82[0][Binc]); } Famp=FNPround((double)Maxx/10.0,-1); //in dBV printf("found harmonic no. %d: amplitude: %0.2f\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/100;} // 40 db amp has x100 amplification into hi z if ((Measuretype==2) & (Amplifier==1) & ((Caltype==2) | (Caltype==3))) {Famp1=Famp1-40;} //with amp present, 40 db amp has 40 db gain into hi z /* FOR Harmonic=1 TO Numharmonics STEP 2 12292 Binn=255-Freq*Harmonic/Hzpbin 12295 Maxx=-1 12298 ! Find max display value of specific harmonic, searching +-5 bins 12301 FOR Binc=FNMax(2,Binn-5) TO FNMin(254,Binn+5) 12304 Maxx=FNMax((Maxx),(Display(Binc))) 12307 NEXT Binc 12310 Famp=FNPround(Fullscale-(1023-Maxx)/(1023/80),-1) 12313 Famp=Famp+FNCalpoint(Amplifier,0,Mixerfreq,Caldata(*),0,0,0,0,0,0,Freq*Harmonic) 12316 IF Harmonic=1 THEN Famp1=Famp 12319 IF Famp-Famp1Maxx THEN Maxbin=Binn 12265 Maxx=FNMax((Display(Binn)),(Maxx)) 12268 NEXT Binn 12271 Freq=(255-Maxbin)*Hzpbin 12274 Fullscale=50-Sens*10 12277 Sign=1 12280 Phaseslope=0 12283 Numharmonics=9 12286 IF (Measuretype=2) OR (Measuretype=1) AND (Caltype<>2) THEN Numharmonics=1!IF Measuretype#0, NOT A BEATNOTE 12289 12331 Gotphase82: ! 12334 IF Amplifier=1 THEN Phaseslope=Phaseslope/100 12337 IF (Measuretype=2) AND (Amplifier=1) AND ((Caltype=2) OR (Caltype=3)) THEN Famp1=Famp1-40 12340 IF (Measuretype=2) OR (Measuretype=1) AND (Caltype<>2) THEN Phseslopecalc 12343 Display(255)=BINAND(Display(255),1023) 12346 Famp=FNPround(Fullscale-(1023-Display(255))/(1023/80),-1) 12349 OUTPUT I3582;"LFM,76000,1" 12352 ENTER I3582 USING "#,W";Sign 12355 Mixerdc1=10^(Famp/20)/2^.5 12358 Mixerdc1=Mixerdc1*SGN(Sign) 12361 Setupinterface(" K2,-K12") 12364 OUTPUT I3582;"HLT SC1 MN1 MP0 SP10 RUN" 12367 OUTPUT I3582;"AR" 12370 WAIT 1.3 12373 OUTPUT I3582;"LMK" 12376 ENTER I3582;Mixerdc2 12379 OUTPUT I3582;"LFM,76000,1" 12382 ENTER I3582 USING "#,W";Sign 12385 Setupinterface("-K2,K12") 12388 Mixerdc=FNPround(Mixerdc1-Mixerdc2*SGN(Sign)/2^.5,-6) 12391 DEALLOCATE Display(*) 12394 GOTO Phseslopecalc */ } //calculate phase slope from data 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");} } } 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; } int Count; // !Index counter int Maxindex; // !Index where max response occured double Maxx; // !Value of max response void i3562_get8db(void) //this is part of charloop, returns count, X, Y; maxindex { int i,j; int i_8db; double hzpbin,farout; double Rc2pi; if (Display3562t[1000]!=1234.0) { printf("!!Error: 3562A LOOP CHARACTERIZATION TRACE IS NOT VALID!\n"); } farout=(Display3562t[800]+Display3562t[799]+Display3562t[798]+Display3562t[797]+Display3562t[796]+Display3562t[795])/6.0; // printf("%0.3f db far out\n",farout); hzpbin=Display3562t[1001]; for (i=0;i<=800;i++) // offset correction, and 80db=800 scaling { Display3562t[i]=(Display3562t[i]-farout)*10.0; } Rc2pi=1.0e+5*1.0e-5*2.0*M_PI; for (i=0;i<=800;i++) // !CORRECTION FOR (1/(1+1/RCs)) AC COUPLER { Display3562t[i]=Display3562t[i]+10.0*10.0*log10(1+1/((Rc2pi*i*hzpbin)*(Rc2pi*i*hzpbin))); } Maxx=-20000; Maxindex=0; // ! FIND FIRST POINT < -8 dB i_8db=0; for (i=700;i>=2;i--) { if ((Display3562t[i]<-80.0)&(Display3562t[i-1]<-80.0)&(i_8db==0)) { i_8db=i; } if (i_8db==0) { Maxx=FNMax(Display3562t[i],Maxx); if (Maxx==Display3562t[i]) {Maxindex=i;} } } Count=0; if (i_8db<10) { printf("!! Error: UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT! <-8 dB not found!\n"); } else { printf("Maxindex: %i (%0.2f Hz); 8db: %i (%0.2f Hz)\n",Maxindex,Maxindex*hzpbin,i_8db,i_8db*hzpbin); for (j=i_8db;j<=FNMin(Maxindex+5,625);j++) { X[Count]=j*hzpbin; Y[Count]=Display3562t[j]/10.0; Count++; } Maxindex=Maxindex-i_8db+1; printf("Maxindex (offset to 8 dB): %i Count: %i\n",Maxindex,Count); } } 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 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; // ! //double Maxpointerror; // !Max error determined by Difcorrection 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]; int I_8db; int SpanF;//3562a frequency span // ! 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"); setup_i("L0,-L9"); //noise to 3562A a input SpanF=25000; if (Loopbw3<3000) {SpanF=10000;} if (Loopbw3<1500) {SpanF=5000;} if (Loopbw3<750) {SpanF=2500;} if (Loopbw3<300) {SpanF=1000;} if (Loopbw3<150) {SpanF=500;} if (Loopbw3<75) {SpanF=250;} if (Loopbw3<30) {SpanF=100;} if (Loopbw3<15) {SpanF=50;} if (Loopbw3<7.5) {SpanF=25;} if (Loopbw3<3) {SpanF=10;} if (Loopbw3<0.5) {SpanF=1;} Hzpbin=(double)SpanF/800.0; Numsamples=15*Hzpbin; Numsamples=FNMin((Numsamples),30); Numsamples=FNMax((Numsamples),4); toggle_i(TOGGLEACDC); i3562_charloop_init(SpanF,Numsamples); toggle_i(OUTOFLOCK); printf("OBSERVE 3582 DISPLAY OF LOOP SUPRESSION CHARACTERISTIC.\n"); printf("EXCESSIVE NOISE MAY CAUSE ACCURACY SPEC DEGRADATION\n"); printf("CHECK LOOP SUPPRESSION ON 3582A, THEN PRESS ANY KEY\n"); getchar(); printf("WAITING FOR AVERAGING ON 3562A OF CLOSED LOOP RESPONSE... "); i3562_charloop(SpanF,Numsamples); printf("done.\n"); setup_i("-S1,-L0,L9"); //noise to 3562A a input toggle_i(OUTOFLOCK); i3562_get8db(); if(Count>0) //valid xfer function found? { 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(); retrychar++; } } } else //for Loopbw3>20 { //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++; } } if (I>500) { printf("!! Error REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT! <-8 dB too far out!\n"); } Count=0; Maxx=-20000; I_8db=I; for (I=I_8db;I<=I_8db+495;I=I+5) { Count=Count+1; Y[Count]=(Display[I]+Display[I+1]+Display[I+2]+Display[I+3]+Display[I+4])/50; X[Count]=(I+2)*Hzpbin; // IF (Pdv=9836 AND (NOT (No_look))) THEN PLOT LGT(X(Count)),Y(Count) Maxx=FNMax(Y[Count]*10,Maxx); if (Maxx==Y[Count]*10) {Maxindex=Count;} // printf("%0.2f %0.2f\n",X[Count],Y[Count]); } Count=FNMin((Count),(Maxindex+10)); } //end of the 3585a function //16393 ! DEALLOCATE Display(*) //16396 IF Pdv<>9836 OR (No_look) THEN Curvesmoothing //16399 FOR I=I TO 1000 STEP 4 //16402 PLOT LGT(I*Hzpbin),Display(I)/10,1 //16405 NEXT I //end of the 3585a function } while (retrychar==1); //This function is common tp 3585a and 3562a data!! if (Maxx>(10*10)) { printf("!! Error: Peak > 10 dB!!\n");} //ABORT IF PEAK > 10 dB if (Maxindex==0) { printf("!! Error: Charloop: No data to fit!!\n");}//ABORT IF NO DATA printf("CALCULATING PRELIMINARY CURVE FIT FOR CLOSED LOOP RESPONSE\n"); // ! Fit curve from -8 dB point to just past peak of xfer fn curvefit(X,Y,Count,5,&C1,&C2,&C3,&C4,&C5); //16432 IF Pdv<>9836 OR (No_look) THEN Skipfittedplot //16435 PENUP //16438 FOR I=1 TO Count STEP 2 //16441 PLOT LGT(X(I)),C5/X(I)+C1+X(I)*(C2+X(I)*(C3+X(I)*C4)),1 //16444 NEXT I //16447 Skipfittedplot:! // ! Pick N fitted points to do differential correction with N=4; Y[1]=C5/X[1]+C1+X[1]*(C2+X[1]*(C3+X[1]*C4)); for (I=2;I<=N;I++) { X[I]=X[(int)pow(10,(log10(Maxindex)*(double)I/(double)N))]; // !X[10^((I-1)/(N-1))*Maxindex/10]; Y[I]=C5/X[I]+C1+X[I]*(C2+X[I]*(C3+X[I]*C4)); } for (I=1;I<=N;I++) { printf("fitted point: %0.2f %0.2f\n",X[I],Y[I]); } //16474 IF Pdv<>9836 OR No_look THEN Skipstars //16477 PENUP //16480 FOR I=1 TO N //16483 MOVE LGT(X(I))-.3,Y(I) //16486 LABEL USING "K";"*->" //16489 NEXT I //16492 Skipstars: ! Oldloopbw1=Loopbw1; printf("CALCULATING FINAL CURVE FIT FOR CLOSED LOOP RESPONSE\n"); //16504 ! Find values for W1 AND Loopbw1 to match Xfer Fn // Difcorrection(X,Y,N,W1,W2,W3,Loopbw1,Maxpointerror); Difcorrection(N); /*16510 DISP 16513 IF Pdv<>9836 OR (No_look) THEN Getvcoindex 16516 PENUP 16519 ALPHA OFF 16522 GRAPHICS ON 16525 RAD 16528 Hzpbin2=Loopbw3*10/125 16531 FOR Binn=1 TO 127 16534 Wi=2*PI*Hzpbin2*Binn 16537 Fw=FNW(Wi,W1,W2,W3,Loopbw1) 16540 PLOT LGT(Wi/(2*PI)),Fw,1 16543 NEXT Binn 16546 GRAPHICS ON 16549 OUTPUT Printer;10^Beginexp;" Hz TO ";10^(Beginexp+4);" Hz" 16552 OUTPUT Printer;" 1dB PER DIVISION" 16555 GRAPHICS OFF 16558 ALPHA ON */ //16567 ! Determine index where vco port must be used Getfreqparms(Vcofreq,1000000,&Vcoindex,&I); Vcoindex=Vcoindex-1; printf("VCOFREQ = %0.1f\n",Vcofreq); printf("VCOINDEX = %i\n",Vcoindex); Spec=fabs(20.0*log10(Loopbw1/Oldloopbw1)); Spec=FNMax3(0,Spec-1.0,Maxpointerror-1.0); // ! 1 dB in error budget printf("Loop BW1 = %0.1f Hz\n",Loopbw1); printf("Loop BW1 CHANGE = %0.2f dB\n",20.0*log10(Loopbw1/Oldloopbw1)); printf("MAX POINT ERROR = %0.2f dB\n",Maxpointerror); if (Spec!=0) { printf("!!WARNING: ACCURACY SPEC MAY BE DEGRADED BY %0.2f dB\n",FNPround(Spec,-2)); } else { printf("OK: CHARLOOP ACCURACY IN SPEC (1 dB)!\n"); } /* 16594 IF Spec=0 THEN Charlockcheck 16597 Ans$="Y" 16600 BEEP 16603 DISP "THE ACCURACY SPEC MAY BE DEGRADED BY ";FNPround(Spec,-2);"dB, CONTINUE? (Y/N)"; 16606 INPUT Ans$ 16609 IF FNUpc$(Ans$[1,1])<>"Y" THEN Abortcharloop4 16612 PRINT "ACCURACY SPEC MAY BE DEGRADED BY ";FNPround(Spec,-2);"dB" 16615 ! PAUSE 16618 ! GOTO Skipstars 16621 ! Check to be sure loop locked back up 16624 Charlockcheck: ! 16627 Toggle("OUT OF LOCK") 16630 Lockcheck(Lockflag) 16633 IF (Abortflag=1) OR (Lockflag=1) THEN Charloopret 16636 BEEP 16639 LOCAL I3582 16642 CLEAR I3585 16645 LOCAL I3585 16648 GRAPHICS OFF 16651 ALPHA ON 16654 DISP "LOCK HAS BEEN LOST, CHECK YOUR SETUP, THEN PRESS 'CONT' TO ZERO THE ""IF""" 16657 BEEP 16660 PAUSE 16663 CALL Walkdownif(Userfrange,10,"LOCKED") !C start walk X10 up from bottom 16666 Lockcheck(Lockflag) 16669 IF (Abortflag=1) OR (Lockflag=1) THEN Charloopret 16672 GOTO Abortcharloop5 16675 Abrtcharloopkey: ! 16678 DISP "MEASUREMENT ABORTED" 16681 BEEP 16684 WAIT 1.5 16687 GOTO Abortcharloop 16690 Abortcharloop1: ! 16693 DISP "REF 323; UNABLE TO ACHIEVE PHASE LOCK, MEASUREMENT ABORTED ,PRESS 'CONTINUE'." 16696 Errorbeep 16699 PAUSE 16702 GOTO Abortcharloop 16705 Abortcharloop3: ! 16708 DISP "REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT, PRESS 'CONTINUE'." 16711 Errorbeep 16714 PAUSE 16717 GOTO Abortcharloop 16720 Abortcharloop4: ! 16723 DISP "MEASUREMENT ABORTED BY USER" 16726 BEEP 16729 WAIT 1.5 16732 GOTO Abortcharloop 16735 Abortcharloop5: ! 16738 DISP "REF 318; LOCK HAS BEEN LOST, MEASUREMENT ABORTED, PRESS 'CONTINUE'." 16741 Errorbeep 16744 PAUSE 16747 GOTO Abortcharloop 16750 Abortcharloop6: ! 16753 DISP "REF 320; EXTERNAL LAG-LEAD MUST BE USED, SEE MANUAL FOR DETAILS, PRESS 'CONT'" 16756 Errorbeep 16759 PAUSE 16762 GOTO Abortcharloop 16765 Abortcharloop: ! 16768 Abortflag=1 16771 Charloopret: ! 16774 IF Printer=1 THEN Printer=0 16777 SUBEXIT ! **FF** 16780 Lagleadcalc: ! 16783 W2=2*PI*Zerofreq(Laglead) 16786 W3=1/(R25*C8+1/W2) 16789 Loopbw3=Loopbw1*W3/W2 16792 ! 16795 ! Check to see if open loop bw is less than lag-lead pole freq W3 16798 IF Loopbw1= than pole-freq W3 and less than 16807 ! lag-lead zero freq W2 16810 IF (Loopbw1>=W3/(2*PI)) AND (Loopbw10 THEN CALL Setupinterface("S4") 16831 Setupbits("LLG",Laglead) 16834 IF Loopbw3>20 THEN CALL Setupinterface("-L0,L9,-S1,-S5,K7,K6,S2") 16837 IF Loopbw3<=20 THEN CALL Setupinterface("L0,-L9,S1,S5,-K7,-K6,-S2") 16840 IF (Loopbw3>250000) AND (Laglead<>7) THEN Abortflag=1 16843 PRINT "LOOP BANDWIDTH=";FNPround(Loopbw3,-2);"Hz" 16846 Vcofreq=Loopbw3/4 16849 RETURN 16852 SUBEND ! **FF** ** */ } /* 15292 SUBEND ! **FF** 15295 ! * 15298 ! * NAME: Charloop 15301 ! * 15304 ! * FUNCTION: Calculate which lead lag filter to use. 15307 ! * 15310 ! * INPUT: Vnom, Vrange, Atten1, Atten2, Phaseslope, Vpeak, Vcoslope, 15313 ! * Pdv, Caldata(*) 15316 ! * 15319 ! * OUTPUT: Loopbw1, Loopbw3, W1, W2, W3, Laglead, Vcofreq, Vcoindex, 15322 ! * Spec 15325 ! * 15328 Charloop: ! 15331 SUB Charloop(REAL Vnom,Vrange,Atten1,Atten2,Phaseslope,Vpeak,Vcoslope,Loopbw1,Loopbw3,W1,W2,W3,Vcofreq,Caldata(*),Spec,INTEGER Pdv,Vcoindex) 15334 COM /Loc_flags/ INTEGER C9835,I3582,I3585,I35601a,Clock,Plotter,Abortflag,Printer 15337 COM /Settings/ Latch(0:9) 15340 DIM Ans$[3] !Answer to yes/no questions 15343 INTEGER Beginexp !Used to scale graph 15346 INTEGER Binn !Bin # of display 15349 INTEGER Bwincrease !0=ok to increase bandwidth, 1=already increased 15352 REAL C1,C2,C3,C4,C5 !Curve fit coeffecients 15355 REAL C8 !Capacitor in lag-lead 15358 REAL Corner !Freq of pole in lag-lead 15361 INTEGER Count !Index counter 15364 REAL Fw !Value of transfer function at w 15367 REAL Gain !Amount of gain in programmable gains 15370 REAL Gain1 !0->28 dB in 4 dB steps 15373 REAL Gain2 !6->20 dB in 2 dB steps 15376 REAL Hzpbin !Hz per display bin 15379 REAL Hzpbin2 !Hz per bin used for plot of loop 15382 INTEGER I !For-next loop counter 15385 INTEGER J !For-next loop counter 15388 REAL Junk !Dummy variable for non-usable value read from the 3585A 15391 REAL Laglead2 !Effective Lag-lead if external lag-lead used 15394 INTEGER Lockflag !0=loop not locked, 1=loop locked 15397 REAL Loopbw2 ! 15400 INTEGER Maxindex !Index where max response occured 15403 REAL Maxpointerror !Max error determined by Difcorrection 15406 REAL Maxx !Value of max response 15409 INTEGER N !Number of points for differential correction 15412 INTEGER Numsamples !Number of samples on 3582A XFER function 15415 REAL Oldloopbw1 !Initial calculation of Loopbw1 15418 REAL R25 !Resistor in lag-lead 15421 REAL Rc2pi !Product of 2*PI*R*C 15424 INTEGER Sens !Sensitivity setting of the 3582A 15427 INTEGER Span !Span number of the 3582A 15430 INTEGER Stat !Status read from the 3582A or 3585A 15433 REAL Wi !Radian freq 15436 REAL X(1:100) !Freq's to be used for curve fit 15439 REAL X1 !Freq to be put in X(*) 15442 REAL Y(1:100) !Amp's to be used for curve fit 15445 REAL Zero !Desired Leadfreq in lag-lead 15448 REAL Zerofreq(0:11) !Actual Leadfreqs for each lag-lead 15451 ! Plus 4 EXTERNAL lag-leads 15454 No_look=1 !SET No_look=0 TO PLOT LOOP SUPPRESSION, =1 TO NOT PLOT. 15457 ON KEY 19 LABEL "ABORT FUNCTION",3 GOTO Abrtcharloopkey 15460 ENABLE 15463 DISP CHR$(130)&CHR$(127)&CHR$(128)&"CALCULATING PHASE LOCK LOOP PARAMETERS" 15466 ! 15469 ! Zero freqs are calculated from the resistor selected by 15472 ! the following formula: f=1/(2*PI*(R+100)*C8) 15475 ! 100 is the switch resistance 15478 ! 15481 DATA 9.95,40.1,115.9,306,784,1.985E3,5E3,12.58E3,31612,79421,199511,501164 15484 READ Zerofreq(*) 15487 C8=3.3E-8 ! .033 uf 15490 R25=4.823E+5 ! 482K ohm 15493 CLEAR I3585 15496 ! 15499 ! DETERMINE GAIN SETTINGS 15502 Gain=2*(20*LGT(Vrange/Atten1/Vpeak) DIV 2) 15505 IF Gain>54 THEN Gain=54 15508 Loopbw1=ABS(Phaseslope*Vcoslope*10^(Gain/20)) ! OPEN LOOP BW 15511 Loopbw1=Loopbw1/10^(FNCalpoint(0,0,Mixerfreq,Caldata(*),0,0,0,0,0,0,10000)/20) ! ADJUST PHASESLOPE TO MEASUREMENT POINT 15514 Gain=Gain-12+6 !TAKE OUT x4(12dB) AMPLIFIER AND 6dB PAD 15517 Gain=Gain+6*(Atten2=.5) !ADD 6 dB IF ATTEN2=.5 15520 Gain2=20-Gain MOD 4 !CHOOSE 20 OR 18 dB FOR GAIN2 15523 IF Gain<18 THEN Gain2=Gain!USE LESS IF GAIN<18 15526 Gain2=FNMax(6,Gain2) !GAIN2 HAS 6 dB MIN 15529 Gain1=Gain-Gain2 !PUT REMAINING GAIN IN GAIN1 15532 Setupbits("GN1",Gain1) 15535 Setupbits("GN2",Gain2) 15538 Setupbits("DAC",Vnom/Atten1) 15541 Setupinterface("L2,K10,S3") ! CLOSE LOOP 15544 IF Printer=0 THEN Printer=1 15547 IF No_look THEN Skiplook 15550 DISABLE 15553 PRINTER IS Printer 15556 PRINT "GAIN=";Gain 15559 PRINT "VCOSLOPE=";Vcoslope/Atten1;" Hz/V" 15562 PRINT "PHASESLOPE=";Phaseslope 15565 PRINT "VPEAK= ";Vpeak 15568 PRINT "LOOP BW1=",Loopbw1 15571 ENABLE 15574 Skiplook: ! 15577 ! 15580 ! Calculate BW assuming far out zero 15583 Corner=1/(2*PI*R25*C8) 15586 Loopbw2=SQR(Loopbw1*Corner)! Geometric mean, approximate cross-over 15589 ! 15592 ! DETERMINE WHICH ZERO TO USE 15595 Zero=Loopbw2/2^.5 15598 FOR Laglead=11 TO 0 STEP -1 15601 IF Zerofreq(Laglead)"Y" THEN Noexternal 15664 Getlaglead: ! 15667 BEEP 15670 INPUT "ENTER LAG-LEAD FOR 35601A HARDWARE (0-7)",Laglead2 15673 Laglead2=INT(Laglead2) 15676 IF (Laglead2>=0) AND (Laglead2<=7) THEN Geteffective 15679 PRINT CHR$(27)&"A"&CHR$(27)&"J"&"LAG LEAD NUMBER MUST BE 0-7" 15682 Errorbeep 15685 GOTO Getlaglead 15688 Geteffective: ! 15691 Laglead=Laglead2 15694 DISP "ENTER EFFECTIVE LAG-LEAD NUMBER (";Laglead2;"- 11 )"; 15697 BEEP 15700 INPUT Laglead 15703 Laglead=INT(Laglead) 15706 IF (Laglead>=Laglead2) AND (Laglead<=11) THEN Lagleadsok 15709 PRINT CHR$(27)&"A"&CHR$(27)&"J"&"LAG LEAD NUMBER MUST BE";Laglead2;"- 11" 15712 Errorbeep 15715 GOTO Geteffective 15718 Lagleadsok: ! 15721 GOSUB Lagleadcalc 15724 IF Abortflag<>0 THEN Abortcharloop1 15727 Bwincrease=1 ! DON'T ALLOW LAGLEAD TO BE CHANGED 15730 Setupbits("LLG",Laglead2)! FORCE LAGLEAD2 15733 GOTO Checklock 15736 Noexternal: ! 15739 GOSUB Lagleadcalc 15742 IF Abortflag<>0 THEN Abortcharloop1 15745 ! CHECK TO SEE IF LOOP IS LOCKED 15748 Checklock: ! 15751 ENABLE 15754 PRINTER IS 1 15757 Lockcheck(Lockflag) 15760 IF Abortflag=1 THEN Abortcharloop 15763 IF Lockflag=1 THEN Startcharloop 15766 ! IF NOT LOCKED, TRY TO INCREASE LOOP BANDWIDTH 15769 Increaseloopbw: ! 15772 IF (Bwincrease=1) OR (Laglead=0) THEN Abortcharloop1 15775 Laglead=Laglead-1 !INCREASE LOOP BANDWIDTH 15778 Bwincrease=1 15781 DISABLE 15784 GOSUB Lagleadcalc !CALCULATE ACTUAL LOOP BW 15787 IF Abortflag<>0 THEN Abortcharloop1 15790 ENABLE 15793 GOTO Checklock 15796 ! 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 ! 15871 ! USE 3585A FOR LOOP BANDWIDTHS >20 HZ 15874 GRAPHICS OFF 15877 IF Loopbw3>=20 THEN Charloop85 15880 Setupinterface("L0,-L9") 15883 Span=14 15886 Hzpbin=25000/125 15889 IF Loopbw3<3000 THEN Span=13 15892 IF Loopbw3<3000 THEN Hzpbin=10000/125 15895 IF Loopbw3<1500 THEN Span=12 15898 IF Loopbw3<1500 THEN Hzpbin=5000/125 15901 IF Loopbw3<750 THEN Span=11 15904 IF Loopbw3<750 THEN Hzpbin=2500/125 15907 IF Loopbw3<300 THEN Span=10 15910 IF Loopbw3<300 THEN Hzpbin=1000/125 15913 IF Loopbw3<150 THEN Span=9 15916 IF Loopbw3<150 THEN Hzpbin=500/125 15919 IF Loopbw3<75 THEN Span=8 15922 IF Loopbw3<75 THEN Hzpbin=250/125 15925 IF Loopbw3<30 THEN Span=7 15928 IF Loopbw3<30 THEN Hzpbin=100/125 15931 IF Loopbw3<15 THEN Span=6 15934 IF Loopbw3<15 THEN Hzpbin=50/125 15937 IF Loopbw3<7.5 THEN Span=5 15940 IF Loopbw3<7.5 THEN Hzpbin=25/125 15943 IF Loopbw3<3 THEN Span=4 15946 IF Loopbw3<3 THEN Hzpbin=10/125 15949 IF Loopbw3<.5 THEN Span=1 15952 IF Loopbw3<.5 THEN Hzpbin=1/125 15955 Numsamples=15*Hzpbin 15958 Numsamples=FNMin((Numsamples),30) 15961 Numsamples=FNMax((Numsamples),4) 15964 OUTPUT I3582;"PRS,AC2,BC2" 15967 Toggle("AC DC") 15970 Sens=5 15973 Autorange82(Sens) 15976 IF Abortflag=1 THEN Charloopret 15979 Sens=FNMax(2,(Sens-1)) 15982 Format:IMAGE "PRS AA0 RP0 IM2 AC2 BC2 BS",2D,"AM",DD,"AS4 MD2 PS3 AV2 NU4 SP",2D,"AX1REWTM,77465,1",/,W,"LST0" 15985 IF No_look THEN Skiplook3 15988 OUTPUT I3582 USING Format;Sens,FNMin(9,9-(Sens-4)),Span,Numsamples 15991 OUTPUT I3582;"RP1" 15994 PRINT TABXY(1,17);" OBSERVE 3582 DISPLAY OF LOOP SUPRESSION CHARACTERISTIC. " 15997 PRINT TABXY(1,18);" EXCESSIVE NOISE MAY CAUSE ACCURACY SPEC DEGRADATION " 16000 BEEP 16003 INPUT "CHECK LOOP SUPPRESSION ON 3582A, THEN PRESS 'CONT';ENTER 'S' FOR 'SWITCH'",Trble$ 16006 ! 16009 PRINT TABXY(1,17);FNClte$ 16012 PRINT TABXY(1,18);FNClte$ 16015 ! 16018 IF Trble$="S" THEN CALL Switch 16021 Skiplook3: ! 16024 DISP CHR$(130)&CHR$(127)&CHR$(128)&"WAITING FOR AVERAGING ON 3582A OF CLOSED LOOP RESPONSE" 16027 OUTPUT I3582 USING Format;Sens,FNMin(9,9-(Sens-4)),Span,Numsamples 16030 ENTER I3582 USING "#,B";Stat 16033 Toggle("OUT OF LOCK") 16036 OUTPUT I3582;"RP1" 16039 Loop:OUTPUT I3582;"LST1" 16042 ENTER I3582 USING "#,B";Stat 16045 IF BIT(Stat,6)=0 THEN Loop 16048 Setupinterface("-S1,-L0,L9") 16051 DISP CHR$(130)&CHR$(127)&CHR$(128)&"MEASURING CLOSED LOOP RESPONSE" 16054 ALLOCATE Display(0:127) 16057 OUTPUT I3582;"LFM,74600,128" 16060 ENTER I3582 USING "#,W";Display(127) ! Get first value so don't 16063 Display(127)=BINAND(Display(127),1023) ! need hpip address each time 16066 FOR I=126 TO 0 STEP -1 16069 ENTER I3582 USING "#,W";Display(I) 16072 Display(I)=BINAND(Display(I),1023) 16075 NEXT I 16078 Mat1(Display(*),"*",(10*80/1023),0,127) !SCALE FROM 0 TO 800 16081 ! 16084 ! Assume transfer function is 0 far out 16087 Mat1(Display(*),"-",((Display(123)+Display(124)+Display(125))/3),0,127) 16090 Rc2pi=1.E+5*1.0E-5*2*PI 16093 FOR I=1 TO 127 !CORRECTION FOR (1/(1+1/RCs)) AC COUPLER 16096 Display(I)=Display(I)+10*10*LGT(1+1/(Rc2pi*I*Hzpbin)^2) 16099 IF (Pdv=9836 AND (NOT (No_look))) THEN PLOT LGT(I*Hzpbin),Display(I)/10,1 16102 NEXT I 16105 Maxx=-20000 16108 ! FIND FIRST POINT < -8 dB 16111 FOR I=100 TO 2 STEP -1 16114 IF (Display(I)<-80) AND (Display(I-1)<-80) THEN Found8db 16117 Maxx=FNMax((Display(I)),(Maxx)) 16120 IF Maxx=Display(I) THEN Maxindex=I 16123 NEXT I 16126 ! TRY TO INCREASE LOOP BANDWIDTH IF -8 dB POINT NOT FOUND 16129 DEALLOCATE Display(*) 16132 IF (Bwincrease=1) OR (Laglead=0) THEN Abortcharloop3 16135 Bwincrease=1 16138 Laglead=Laglead-1 16141 GOSUB Lagleadcalc 16144 IF Abortflag<>0 THEN Abortcharloop1 16147 GOTO Startcharloop 16150 Found8db: ! 16153 Count=0 16156 FOR J=I TO FNMin(Maxindex+5,100) 16159 Count=Count+1 16162 Y(Count)=Display(J)/10 16165 X(Count)=J*Hzpbin 16168 NEXT J 16171 Maxindex=Maxindex-I+1 16174 GOTO Curvesmoothing 16177 ! 16180 Charloop85: ! 16183 Hzpbin=(Loopbw3*4 DIV 10)*.01 ! Span=BW3*4. Hzpbin in Units of .01 Hz. 16186 CLEAR I3585 ! CLEAR DISPLAY BITS 16189 OUTPUT I3585 USING "K,8D.D,K";"FB",1000*Hzpbin,"HZ,R10,I1,SV4,S2" 16192 IF No_look THEN Skiplook4 16195 OUTPUT I3585;"SV1 S1" 16198 LOCAL I3585 16201 BEEP 16204 ! 16207 PRINT TABXY(1,17);" OBSERVE 3585 DISPLAY OF LOOP SUPRESSION CHARACTERISTIC. " 16210 PRINT TABXY(1,18);" EXCESSIVE NOISE MAY CAUSE ACCURACY SPEC DEGRADATION " 16213 ! 16216 BEEP 16219 INPUT "CHECK LOOP SUPPRESSION ON 3585A, THEN PRESS 'CONT';ENTER 'S' FOR 'SWITCH'",Trble$ 16222 ! 16225 PRINT TABXY(1,17);FNClte$ 16228 PRINT TABXY(1,18);FNClte$ 16231 ! 16234 IF Trble$="S" THEN CALL Switch 16237 CLEAR I3585 16240 OUTPUT I3585;"RC1" 16243 Skiplook4: ! 16246 Toggle("OUT OF LOCK") 16249 DISP CHR$(130)&CHR$(127)&CHR$(128)&"MEASURING CLOSED LOOP RESPONSE" 16252 WAIT 1 16255 OUTPUT I3585;"S2" !Start the sweep 16258 ! 16261 Waitforsweep:OUTPUT I3585;"D6T4" 16264 ENTER I3585 USING "#,B";Stat 16267 IF BIT(Stat,7) THEN Waitforsweep 16270 ! 16273 OUTPUT I3585;"SAAB1" 16276 Setupinterface("-S3,-S4") ! Open loop for reference sweep 16279 OUTPUT I3585;"S2" !Start the sweep 16282 ! 16285 Waitforsweep2:OUTPUT I3585;"D6T4" 16288 ENTER I3585 USING "#,B";Stat 16291 IF BIT(Stat,7) THEN Waitforsweep2 16294 ! 16297 Setupinterface("-K7,-K6,-S2,S3,S4")!Close loop again 16300 ALLOCATE Display(0:1000) 16303 OUTPUT I3585;"C5CLSABO" 16306 ENTER I3585 USING "#,W";Junk !First two bytes are junk 16309 ENTER I3585 USING "#,W";Display(*) 16312 Display(1000)=BINAND(Display(1000),1023) 16315 Display(0)=BINAND(Display(0),1023) 16318 FOR I=0 TO 1000 16321 Display(I)=500-Display(I)!SCALE FROM -500 TO 500 16324 NEXT I 16327 IF Display(1000)<-10 THEN Abortcharloop3!Check for < -1 dB far out 16330 FOR I=1000 TO 2 STEP -1 !Search for first point <-8 dB 16333 IF (Display(I)<-80) AND (Display(I-1)<-80) THEN Found08db 16336 NEXT I 16339 GOTO Abortcharloop3 16342 Found08db: ! -8 dB point found, increase loop bandwidth if invalid 16345 IF (I>500) AND (Bwincrease=0) THEN 16348 DEALLOCATE Display(*) 16351 GOTO Increaseloopbw 16354 END IF 16357 IF I>500 THEN Abortcharloop3 16360 Count=0 16363 Maxx=-20000 16366 FOR I=I TO I+495 STEP 5 16369 Count=Count+1 16372 Y(Count)=(Display(I)+Display(I+1)+Display(I+2)+Display(I+3)+Display(I+4))/50 16375 X(Count)=(I+2)*Hzpbin 16378 IF (Pdv=9836 AND (NOT (No_look))) THEN PLOT LGT(X(Count)),Y(Count) 16381 Maxx=FNMax(Y(Count)*10,Maxx) 16384 IF Maxx=Y(Count)*10 THEN Maxindex=Count 16387 NEXT I 16390 Count=FNMin((Count),(Maxindex+10)) 16393 ! DEALLOCATE Display(*) 16396 IF Pdv<>9836 OR (No_look) THEN Curvesmoothing 16399 FOR I=I TO 1000 STEP 4 16402 PLOT LGT(I*Hzpbin),Display(I)/10,1 16405 NEXT I 16408 ! 16411 Curvesmoothing: ! 16414 IF Maxx>10*10 THEN Abortcharloop3 !ABORT IF PEAK > 10 dB 16417 IF Maxindex=0 THEN Abortcharloop3 !ABORT IF NO DATA 16420 DISP CHR$(130)&CHR$(127)&CHR$(128)&"CALCULATING PRELIMINARY CURVE FIT FOR CLOSED LOOP RESPONSE" 16423 ! 16426 ! Fit curve from -8 dB point to just past peak of xfer fn 16429 Curvefit(X(*),Y(*),Count,5,C1,C2,C3,C4,C5) 16432 IF Pdv<>9836 OR (No_look) THEN Skipfittedplot 16435 PENUP 16438 FOR I=1 TO Count STEP 2 16441 PLOT LGT(X(I)),C5/X(I)+C1+X(I)*(C2+X(I)*(C3+X(I)*C4)),1 16444 NEXT I 16447 Skipfittedplot:! 16450 ! 16453 ! Pick N fitted points to do differential correction with 16456 N=4 16459 Y(1)=C5/X(1)+C1+X(1)*(C2+X(1)*(C3+X(1)*C4)) 16462 FOR I=2 TO N 16465 X(I)=X(10^(LGT(Maxindex)*I/N))!X(10^((I-1)/(N-1))*Maxindex/10) 16468 Y(I)=C5/X(I)+C1+X(I)*(C2+X(I)*(C3+X(I)*C4)) 16471 NEXT I 16474 IF Pdv<>9836 OR No_look THEN Skipstars 16477 PENUP 16480 FOR I=1 TO N 16483 MOVE LGT(X(I))-.3,Y(I) 16486 LABEL USING "K";"*->" 16489 NEXT I 16492 Skipstars: ! 16495 Oldloopbw1=Loopbw1 16498 DISP CHR$(130)&CHR$(127)&CHR$(128)&"CALCULATING FINAL CURVE FIT FOR CLOSED LOOP RESPONSE" 16501 ! 16504 ! Find values for W1 AND Loopbw1 to match Xfer Fn 16507 Difcorrection(X(*),Y(*),N,W1,W2,W3,Loopbw1,Maxpointerror) 16510 DISP 16513 IF Pdv<>9836 OR (No_look) THEN Getvcoindex 16516 PENUP 16519 ALPHA OFF 16522 GRAPHICS ON 16525 RAD 16528 Hzpbin2=Loopbw3*10/125 16531 FOR Binn=1 TO 127 16534 Wi=2*PI*Hzpbin2*Binn 16537 Fw=FNW(Wi,W1,W2,W3,Loopbw1) 16540 PLOT LGT(Wi/(2*PI)),Fw,1 16543 NEXT Binn 16546 GRAPHICS ON 16549 OUTPUT Printer;10^Beginexp;" Hz TO ";10^(Beginexp+4);" Hz" 16552 OUTPUT Printer;" 1dB PER DIVISION" 16555 GRAPHICS OFF 16558 ALPHA ON 16561 Getvcoindex: ! 16564 ! 16567 ! Determine index where vco port must be used 16570 Getfreqparms(Vcofreq,1000000,Vcoindex,I) 16573 Vcoindex=Vcoindex-1 16576 Spec=ABS(20*LGT(Loopbw1/Oldloopbw1)) 16579 Spec=FNMax(0,Spec-1.,Maxpointerror-1.) ! 1 dB in error budget 16582 IF No_look THEN Skiplook6 16585 OUTPUT Printer;"BW1 CHANGE=";20*LGT(Loopbw1/Oldloopbw1) 16588 OUTPUT Printer;"MAX POINT ERROR=";Maxpointerror 16591 Skiplook6: ! 16594 IF Spec=0 THEN Charlockcheck 16597 Ans$="Y" 16600 BEEP 16603 DISP "THE ACCURACY SPEC MAY BE DEGRADED BY ";FNPround(Spec,-2);"dB, CONTINUE? (Y/N)"; 16606 INPUT Ans$ 16609 IF FNUpc$(Ans$[1,1])<>"Y" THEN Abortcharloop4 16612 PRINT "ACCURACY SPEC MAY BE DEGRADED BY ";FNPround(Spec,-2);"dB" 16615 ! PAUSE 16618 ! GOTO Skipstars 16621 ! Check to be sure loop locked back up 16624 Charlockcheck: ! 16627 Toggle("OUT OF LOCK") 16630 Lockcheck(Lockflag) 16633 IF (Abortflag=1) OR (Lockflag=1) THEN Charloopret 16636 BEEP 16639 LOCAL I3582 16642 CLEAR I3585 16645 LOCAL I3585 16648 GRAPHICS OFF 16651 ALPHA ON 16654 DISP "LOCK HAS BEEN LOST, CHECK YOUR SETUP, THEN PRESS 'CONT' TO ZERO THE ""IF""" 16657 BEEP 16660 PAUSE 16663 CALL Walkdownif(Userfrange,10,"LOCKED") !C start walk X10 up from bottom 16666 Lockcheck(Lockflag) 16669 IF (Abortflag=1) OR (Lockflag=1) THEN Charloopret 16672 GOTO Abortcharloop5 16675 Abrtcharloopkey: ! 16678 DISP "MEASUREMENT ABORTED" 16681 BEEP 16684 WAIT 1.5 16687 GOTO Abortcharloop 16690 Abortcharloop1: ! 16693 DISP "REF 323; UNABLE TO ACHIEVE PHASE LOCK, MEASUREMENT ABORTED ,PRESS 'CONTINUE'." 16696 Errorbeep 16699 PAUSE 16702 GOTO Abortcharloop 16705 Abortcharloop3: ! 16708 DISP "REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT, PRESS 'CONTINUE'." 16711 Errorbeep 16714 PAUSE 16717 GOTO Abortcharloop 16720 Abortcharloop4: ! 16723 DISP "MEASUREMENT ABORTED BY USER" 16726 BEEP 16729 WAIT 1.5 16732 GOTO Abortcharloop 16735 Abortcharloop5: ! 16738 DISP "REF 318; LOCK HAS BEEN LOST, MEASUREMENT ABORTED, PRESS 'CONTINUE'." 16741 Errorbeep 16744 PAUSE 16747 GOTO Abortcharloop 16750 Abortcharloop6: ! 16753 DISP "REF 320; EXTERNAL LAG-LEAD MUST BE USED, SEE MANUAL FOR DETAILS, PRESS 'CONT'" 16756 Errorbeep 16759 PAUSE 16762 GOTO Abortcharloop 16765 Abortcharloop: ! 16768 Abortflag=1 16771 Charloopret: ! 16774 IF Printer=1 THEN Printer=0 16777 SUBEXIT ! **FF** 16780 Lagleadcalc: ! 16783 W2=2*PI*Zerofreq(Laglead) 16786 W3=1/(R25*C8+1/W2) 16789 Loopbw3=Loopbw1*W3/W2 16792 ! 16795 ! Check to see if open loop bw is less than lag-lead pole freq W3 16798 IF Loopbw1= than pole-freq W3 and less than 16807 ! lag-lead zero freq W2 16810 IF (Loopbw1>=W3/(2*PI)) AND (Loopbw10 THEN CALL Setupinterface("S4") 16831 Setupbits("LLG",Laglead) 16834 IF Loopbw3>20 THEN CALL Setupinterface("-L0,L9,-S1,-S5,K7,K6,S2") 16837 IF Loopbw3<=20 THEN CALL Setupinterface("L0,-L9,S1,S5,-K7,-K6,-S2") 16840 IF (Loopbw3>250000) AND (Laglead<>7) THEN Abortflag=1 16843 PRINT "LOOP BANDWIDTH=";FNPround(Loopbw3,-2);"Hz" 16846 Vcofreq=Loopbw3/4 16849 RETURN 16852 SUBEND ! **FF** ** */ 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.0*20.0*log10(F)+10.0*10.0*log10((1.0+1.0/Ww)*(1.0+Ww/Ww5)*(1.0+Ww/Ww2)/(1.0+Ww/Ww3))); } printf("Phioff: Plotindex<=VCOindex Correction done, Segment %i!\n",Plotindex); 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));} if (Plotindex<=3) {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; old seg 2 is up to 5 hz //if (Plotindex<=2) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+(int)(100.0*log10(1.0+1.0/(Rc2pi*F*F)));} if (Plotindex<=3) {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 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"); } // i3562_timeb_init(); /* 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 /* //follows: test for small bw loop char setup_i("K8,K9"); //low pass setup_i("K12,K10,S3,S8,L1,L3,L5,L8,L9,S4"); //close loop setup_i("-K6,-K7,K12,K10,-S1,-S2,S3,S4");//loop closed setup_i("L2,K10,S3"); // IF Loopbw3<=20 THEN CALL Setupinterface("L0,-L9,S1,S5,-K7,-K6,-S2") setup_i("L0,-L9,S1,S5,-K7,-K6,-S2"); toggle_i(NOCOMMAND); //make sure the GPIB is working with 35601a interface toggle_i(OVERLOAD); toggle_i(OUTOFLOCK); //setup_i("L0,-L9"); //noise to 3562A a input //setup_i("S1,S5"); //noise to 3562A summing jnctn toggle_i(TOGGLEACDC); i3562_charloop_init(200,4); i3562_charloop(200,4); i3562_get8db(); getchar(); setup_i("-S1,-L0,L9"); //noise to 3562A a input printf("...\n\n"); getchar(); exit(1); */ 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; Vcoport=0; 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("PN measurement started:\n"); printf("Running getdata...\n"); //** need to add autorange after each filter change range_3562=7; i3562_pwrspec_init(); getdata(); setup_i("F0"); //seg 3: F2; seg 4-6 F1, seg 7- F0; toggle_i(TOGGLEACDC); i3562_pwrspec(10,range_3562,30); i3562_pwrspec(10,range_3562,30); i3562_pwrspec(9,range_3562,30); setup_i("S5"); Vcoport=1; 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,3); //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\\testvco10.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); }