要完成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
#include
#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;
}