#include "stdafx.h"
 #include "C:\Program Files\IVI Foundation\VISA\WinNT\agvisa\include\visa.h"
 #pragma comment(lib,"C:\\Program Files\\IVI Foundation\\VISA\\WinNT\\agvisa\\lib\\msc\\agvisa32.lib")
 #include <stdio.h>
 void main () {
 ViSession defaultRM, vi;
 char buf [256] = {0};
 /* Open session to GPIB device at address 22 */
 viOpenDefaultRM (&defaultRM);
 viOpen (defaultRM, "GPIB0::22::INSTR", VI_NULL,VI_NULL, &vi);
 /* Initialize device(Reset) */
 viPrintf (vi, "*RST\n");
 /* Send an *IDN? string to the device */
 viPrintf (vi, "*IDN?\n");
 /* Read results */
 viScanf (vi, "%t", &buf);
 //viQueryf(vi, "*IDN?\n","%t",%buf);//上两条语句可用此条代替
 /* Print results */
 printf ("Instrument identification string: %s\n", buf);
 //信号源---特定的信号源可能命令不一样,需要参考编程文档
 int freq=999;
 viPrintf(vi, "FREQ %dMHz\n",freq);
 viPrintf(vi, "POW  0dBm\n");
 viPrintf(vi, "OUTP ON\n"); //RF ON
 viPrintf(vi, "MOD ON\n");  //调制开
 //频谱仪
 viPrintf(vi, "SYST:DISP:UPDate ON\n");//屏幕显示,不显示速度较快
 viPrintf(vi, "FREQ:CENT 999MHz\n");
 viPrintf(vi, "FREQ:SPAN 10MHz\n");
 viPrintf(vi, "CALC:MARK:AOFF\n");
 viPrintf(vi, "SWE:TIME 2s\n");//扫描时间
 viPrintf(vi, "SYST:PSAVE ON\n");//省电模式
 viPrintf(vi, "DISP:TRAC:Y:RLEV 10dBm\n");
 viPrintf(vi, "DISP:WIND:TRAC:Y:RLEV:OFFS 10dB\n");
 viPrintf(vi, "CALC:MARK:X 999MHz\n");//MARK ON
 viPrintf(vi, "BAND:RES 100kHz\n");//RBW
 viPrintf(vi, "BAND:VID 300kHz\n");//VBW   
 //自动校准需要单次扫描,连续扫描不准确   
 viPrintf(vi, "INIT:CONT OFF\n");
 //WAI用于同步,还有OPC等也可用于同步,仅用于overlapping command,sequential command
 //无用,不过用
 viPrintf(vi, "INIT:IMM;*WAI\n");
 viPrintf(vi, "CALC:MARK:MAX\n");
 //读取mark的值
 viQueryf(vi, "CALC:MARK:Y?\n","%t",buf);  
 printf("The mark value is:%s.\n",buf);
 //功率计
 viPrintf(vi, "SENS:CORR:OFFS 31\n");//外部补偿电平 db!!!!ok
 viPrintf(vi, "DISP:TRAC:VCENT 55dBm\n");//参考电平 
 viPrintf(vi, "TRIG:LEV 40dBm\n");//触发电平 dBm
 viPrintf(vi, "TRIG:DEL 0\n");//触发事件位置us   ns/div us/div ms/div
 viPrintf(vi, "DISP:PULS:TIMEBASE 10us\n");//时间单位 (moren s) 100us
 viPrintf(vi, "DISP:TRAC:VSCALe 5dB\n");//db/格  db dBm,dBV,dBmV,dbuV dBuV
 //网分仪
 viPrintf(vi, "SYST:DISP:UPDate ON\n");
 viPrintf(vi, "SWE:COUnt 12\n");
 viPrintf(vi, "CALC:PAR:SEL 'CH1_S11_1'\n");
 viPrintf(vi, "CALC:PAR:DEF 'My_S11',s11\n");
 //
 viPrintf(vi, "CALCulate1:PARameter:SELect 'Ch1Trc2' 'S21'\n");
 viPrintf(vi, "SYST:DISP:UPDate ON\n");
 viPrintf(vi, "CALC:FORM PHAS\n");
 viPrintf(vi, "FORMat ASCII\n");
 viQueryf(vi, "INITiate1:CONTinuous OFF;*OPC?\n","%s", buf);
 viPrintf(vi, "SENS1:FREQ:STAR 1000MHz\n");
 viPrintf(vi, "SENS1:FREQ:STOP 1125MHz\n");
 viPrintf(vi, "SENS1:SWE:POIN 126\n");
 viPrintf(vi, "OUTP1  OFF\n");
 viPrintf(vi, "SOUR:POW -7\n");
 viPrintf(vi, "CALC1:MARK1 ON\n");
 //
 /* Close session */
 viClose(vi);
 viClose(defaultRM);
 while(1);//pause for see the result.
 }
 /*
 一段VC写的VISA GPIB控制代码。
 注意事项:
 1.必须先安装Agilent IO Library驱动,本人添加的是默认位置的库;
 装了驱动后有很多很好的文档C:\Program Files\Agilent\IO Libraries Suite\Manuals\visa.pdf
 2.安捷伦提供SICL 和 VISA两种库,不推荐用SICL,因为VISA更通用,
   NI也用VISA,函数名一致,都是viOpenDefaultRM,viOpen,viPrintf,viQueryf,viClose。
 3.GPIB是用来控制电子仪器的,主要用在自动化控制,测试上。标准是SCPI,可以google下。
 4.其实不难,但要多实践,只是调用API(头文件visa.h,库agvisa32.lib),API常用的就是几个,
 viOpenDefaultRM,viOpen,viPrintf,viQueryf,viClose...
 还有viSetAttribute,viScanf等;
 viSetAttribute(vi,VI_ATTR_TMO_VALUE,20000);//超时时间20s 
 其他的主要是SCPI命令,大多是标准化的,查查编程文档即可。
 5.较新的技术是: LXI(LAN Extention Interface),网口控制,
 因为一个方面是GPIB接口较贵(3k-5k),设备也只能接十几个(通常足够了);
 6.扫描时需要单次同步,这样才准确;
 7,应该多在Agilent和NI官网看看。
 8.好书:《NI-VISAProgrammersMan》,《Agilent VISA User's Guide》
 9.自动搜索仪器,根据*IDN知道什么仪器
 ViChar buffer[255];
 ViRsrc mathes=buffer;
 ViUInt32 nmatched;
 ViFindList list;
 viFindRsrc(defaultRM,"GPIB?*INSTR",&list,&nmatched,
  matched);
 viFindNext(list,matches);
 viFindNext(list,matches);
 ...
 viClose(list);
 10. 测量多个数据可能用到strtok函数,或直接保存到一个数组里;
 11.至于GPIB规范,总线电缆 包括16根信号线和9根地线。16根信号线中,8根为数据线,5根
 为接口管理线,3根为握手线。IFC,ATN,了解即可。
 12.FORMAT ASCii | In
 自动校准用,写多了也没什么意思了。
 //*/
 信号源
 //信号源设置较少,主要设置频率和功率。
 viPrintf(vi_sig, "FREQ 999MHz\n");
 viPrintf(vi_sig, "POW  0dBm\n");
 viPrintf(vi_sig, "OUTP ON\n"); //射频开
 viPrintf(vi_sig, "MOD  ON\n"); //调制开
 其他滤波器什么的,很少用。
 最新的仪器有有个很强大的功能,按下某个键即可显示其相应的SCPI命令,
 于此我们不用查编程文档了,真是爽歪歪。
 viPrintf(vi_sig,"DM:IQ:STATE ON\n");
 // viPrintf(vi_4438c, "OUTP:MOD:STAT OFF\n");//
 // viPrintf(vi_4438c,"DM:STATE ON\n");
 //频谱仪
 viPrintf(vi_spec, "SYST:DISP:UPDate ON\n");
 viPrintf(vi_spec, "FREQ:CENT %dMHz\n",m_cent_freq);
 viPrintf(vi_spec, "FREQ:SPAN %dMHz\n",m_span);
 viPrintf(vi_spec, "DISP:WIND:TRAC:Y:RLEV %ddBm\n",m_rlevel);
 viPrintf(vi_spec, "BAND:VID %dkHz\n",m_rbw);
 viPrintf(vi_spec, "BAND:RES %dkHz\n",m_vbw);
 viPrintf(vi_spec, "CALC:MARK:AOFF\n");
 //
 char buf[255];
 viPrintf(vi_spec,"INIT:CONT OFF\n");
 viPrintf(vi_spec,"INIT:IMM;*WAI\n");
 viPrintf(vi_spec,"CALC:MARK:MAX\n");
 viPrintf(vi_spec,"*WAI\n");
 viQueryf(vi_spec,"CALC:MARK:Y?\n","%t",buf);
 viPrintf(vi_spec,"*WAI\n");
 viPrintf(vi_spec,"INIT:CONT ON\n");
 viPrintf(vi_spec, "SWE:TIME 2s\n");
 //功率计
 /*
 viPrintf(vi_boonton,"SENS:CORR:OFFS 31dBm\n");//外部补偿电平
 viPrintf(vi_boonton,"DISP:TRAC:VCENT 55dBm\n");//参考电平
 viPrintf(vi_boonton,"TRIG:LEV 40dBm\n");//触发电平
 viPrintf(vi_boonton,"DISP:PULS:TIMEBASE 10us\n");//时间单位
 viPrintf(vi_boonton,"DISP:TRAC:VSCALe 5dB\n");//db/格
 viPrintf(vi_boonton,"*CLS\n");
 viPrintf(vi_boonton,"CALC:MODE PULSE\n");
 viPrintf(vi_boonton,"DISP:PARA:MODE MEAS\n");
 viPrintf(vi_boonton,"SENS:CORR:OFFS 0\n");//0dB//外部补偿电平
 viPrintf(vi_boonton,"TRIG:LEV 0\n");//触发电平0
 viPrintf(vi_boonton,"DISP:TRAC:VCENT 0\n");//参考电平
 viPrintf(vi_boonton,"DISP:TRAC:VSCALe 5\n");//db/格 10
 viPrintf(vi_boonton,"TRIG:DEL 0\n");//触发事件位置s 0 
 viPrintf(vi_boonton,"DISP:PULS:TIMEBASE 5us\n");//pow
 viPrintf(vi_boonton,"DISP:PULS:TIMEBASE 5us\n");
 viPrintf(vi_boonton,"*WAI\n");
 // viQueryf(vi_boonton,"FETCH:INTER:MAX ?\n","%t",buf);
 viQueryf(vi_boonton,"FETCH:ARRAY:AMEA:POW  ?\n","%t",buf);
 viPrintf(vi_boonton,"TRIG:SLOP POS\n");
 viPrintf(vi_boonton,"DISP:PULS:TIMEBASE 100ns\n");
 viPrintf(vi_boonton,"*WAI\n");
 viQueryf(vi_boonton,"FETCH:ARRAY:AMEA:TIM ?\n","%t",buf_time);
 viQueryf(vi_boonton,"FETCH:INTER:MAX ?\n","%t",buf_p);//0410
 viQueryf(vi_boonton,"FETCH:ARRAY:AMEA:POW  ?\n","%t",buf_p);
 viPrintf(vi_boonton,"*WAI\n");
 str_time=buf_time;count=0;
 /测试下降沿
 viPrintf(vi_boonton,"TRIG:SLOP NEG\n");
 viPrintf(vi_boonton,"*WAI\n");
 viQueryf(vi_boonton,"FETCH:ARRAY:AMEA:TIM ?\n","%t",buf_time);
 viQueryf(vi_boonton,"FETCH:ARRAY:AMEA:POW  ?\n","%t",buf_p2);
 // viQueryf(vi_boonton,"FETCH:INTER:MAX ?\n","%t",buf_p2);//均值
 viPrintf(vi_boonton,"*WAI\n");
 //
 viQueryf(vi,"FETCH:INTER:AVER?\n","%t",buf);READ:INTER:AVER
 viQueryf(vi,"FETCH:INTER:MAX?\n","%t",buf); READ:INTER:MAX
 //
 viPrintf(vi_zvb, "SYST:DISP:UPDate ON\n");
 viPrintf(vi_zvb, "SWE:COUnt %d\n",m_point);
 viPrintf(vi_zvb, "CALC:PAR:SEL 'CH1_S11_1'\n");
 viPrintf(vi_zvb, "CALC:PAR:DEF 'My_S11',s11\n");
 //
 viPrintf(vi_zvb, "CALCulate1:PARameter:SELect 'Ch1Trc2' 'S21'\n");
 viPrintf(vi_zvb, "SYST:DISP:UPDate ON\n");
 viPrintf(vi_zvb, "CALC:FORM PHAS\n");
 viPrintf(vi_zvb, "FORMat ASCII\n");
 viQueryf(vi_zvb, "INITiate1:CONTinuous OFF;*OPC?\n","%s", ValueStr);
 viPrintf(vi_zvb, "SENS1:FREQ:STAR 1000MHz\n");
 viPrintf(vi_zvb, "SENS1:FREQ:STOP 1125MHz\n");
 viPrintf(vi_zvb, "SENS1:SWE:POIN 126\n");
 viPrintf(vi_zvb, "OUTP1  OFF\n");
 viPrintf(vi_zvb, "SOUR:POW -7\n");
 viPrintf(vi_zvb,"CALC1:MARK1 ON\n");
  










