要完成PC控制仪器需要了解两方面知识:SCPI和VISA。
SCPI(可编程仪器的标准命令)是一种基于 ASCII 的仪器命令语言,供测试和测量仪器使用,简单来说就是你发送给一个设备一串SCPI格式的字符串,它就能完成相应操作,这就是它们的通用语言。SCPI分为标准SCPI和扩展的SCPI,前者是各种设备通用的,如重置命令RST,后者是各个厂家各种设备自己扩展的命令。如果相应设备支持SCPI,在其操作手册中会对SCPI详细说明,一个简单的参考在这里,最好是查看需要控制的设备说明文档。
VISA(Virtual Instrument Software Architecture,简称为"Visa"),即虚拟仪器软件结构,是VXI plug&play联盟制定的I/O接口软件标准及其规范的总称。VISA提供用于仪器编程的标准I/O函数库,称为VISA库。计算机通过它来控制仪器。
VISA的适用和各种仪器接口通信,无论仪器使用的串口还是其他任何一种总线,诸如USB、GPIB、VXI、PXI和LXI等,都具有相同的操作函数,从而实现了控制操作上的统一。
我们在这里使用的是Agilent IO Suite提供的VISA库。
Agilent的Visa库使用手册链接。不同厂商提供的visa库可能稍微有些差别,一般推荐使用Agilent IO Suite来完成与各种标准测试仪器的通信。
Agilent IO Suite是很多设备通信库和调试工具的集合,详细的下载和说明链接。
这里我是使用光盘安装的,打开光盘内容显示如下:
进入文件夹Autorun中运行auto.exe安装,安装完成后,在工具栏显示如下IO图标:
CommandExpert不会自动安装,为了后面讲解内容,进入文件夹CommandExpert,点击安装。
将要控制的设备和PC连接起来,这里我的函数发生器和PC使用USB连接起来,双击IO图标,打开Agilent Connection Expert软件界面如下:
可以看到,已经连接的设备会显示在列表中(包括接口类型和VISA标志串),这里截图时我的设备没有连到PC上,所以显示为红叉叉,连接成功应该是绿钩钩。
选择对应的设备,在Tools中打开Interactive IO如下:
使用该工具就可以在PC上面给函数发生器发送SCPI指令了,你可以发送一个IDN?查询一下设备信息。其他的控制指令是一样的,如函数发生器设置方波及其参数,可以分别发送如下指令:
FUNC SQU FUNC:SQU:DCYC +20.0 FREQ +1.0E+04 VOLT:HIGH +4.0 VOLT:LOW +0.0 OUTP 1一般你可以在这个工具中,测试各个指令串,在编程的时候再把需要参数化的参数设置成变量即可。
#include <stdio.h> #include <string.h> #include "visa.h" #pragma comment(lib, "visa32.lib") void SetSquare() { ViSession rm; ViSession Function_Generator_33500B; ViUInt16 io_prot; ViUInt16 intfType; ViString intfName[512]; //打开总的资源管理器,初始化资源管理器 viOpenDefaultRM(&rm); //打开指定的USB接口控制的函数发生器 viOpen(rm, "USB0::2391::11015::MY52700871::0::INSTR", VI_NULL, VI_NULL, &Function_Generator_33500B); //确认默认的函数发生器命令否以\n结束,这里定义的SCPI语言是必须以\n结尾的 ViBoolean termDefaultFunction_Generator_33500B = VI_FALSE; if((VI_SUCCESS == viGetAttribute(Function_Generator_33500B, VI_ATTR_RSRC_CLASS, intfName)) && (0 == strcmp("SOCKET", (ViString)intfName))) { termDefaultFunction_Generator_33500B = VI_TRUE; } else if((VI_SUCCESS == viGetAttribute(Function_Generator_33500B, VI_ATTR_INTF_TYPE, &intfType)) && (intfType == VI_INTF_ASRL)) { termDefaultFunction_Generator_33500B = VI_TRUE; } viSetAttribute(Function_Generator_33500B, VI_ATTR_TERMCHAR_EN, termDefaultFunction_Generator_33500B); //具体的命令操作语句,注意SCPI的写法和\n结尾 viPrintf(Function_Generator_33500B, ":SOURce:FUNCtion %s\n", "SQUare"); //方波 viPrintf(Function_Generator_33500B, ":SOURce:VOLTage:LIMit:HIGH %@3lf\n", 5.0); //最大输出电压 viPrintf(Function_Generator_33500B, ":SOURce:VOLTage:LIMit:LOW %@3lf\n", -5.0); //最小输出电压 viPrintf(Function_Generator_33500B, ":SOURce:VOLTage:LIMit:STATe %@1d\n", 1); viPrintf(Function_Generator_33500B, ":SOURce:FREQuency %@3lf\n", 100.0); //频率(kHz) viPrintf(Function_Generator_33500B, ":SOURce:VOLTage %@3lf\n", 4.0); //幅值(V) viPrintf(Function_Generator_33500B, ":SOURce:VOLTage:OFFSet %@3lf\n", 1.0); //偏移值(V) viPrintf(Function_Generator_33500B, ":SOURce:FUNCtion:SQUare:DCYCle %@3lf\n", 20.0); //占空比(%) viPrintf(Function_Generator_33500B, ":OUTPut %@1d\n", 1); //开启输出 //关闭到指定的USB接口控制的函数发生器的连接 viClose(Function_Generator_33500B); //关闭总的资源管理器 viClose(rm); } int main(int argc, char *argv[]) { printf("请输入任意字符:\n"); getchar(); //控制函数发生器产生矩形波 SetSquare(); return 0; }