实验室买了个函数发生器,要集成到自己的设备上,又想从自己编写的PC Windows软件上直接控制,不用手动操作。像这种标准测试控制仪器都是提供PC接口的,在查阅了相关资料以后,完美解决问题,记下相关知识以供有需要的参考。

我用的Agilent函数发生器型号是Agilent 33521B。
要完成PC控制仪器需要了解两方面知识:SCPI和VISA。

SCPI

SCPI(可编程仪器的标准命令)是一种基于 ASCII 的仪器命令语言,供测试和测量仪器使用,简单来说就是你发送给一个设备一串SCPI格式的字符串,它就能完成相应操作,这就是它们的通用语言。SCPI分为标准SCPI和扩展的SCPI,前者是各种设备通用的,如重置命令RST,后者是各个厂家各种设备自己扩展的命令。如果相应设备支持SCPI,在其操作手册中会对SCPI详细说明,一个简单的参考在这里,最好是查看需要控制的设备说明文档。

VISA

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的安装和使用

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

一般你可以在这个工具中,测试各个指令串,在编程的时候再把需要参数化的参数设置成变量即可。

使用Visa编程控制函数发生器

接下来就是使用Visa和设备编程通信了。
和其他硬件设备编程一样,以我默认目录安装为例,VC include目录加入C:\Program Files\IVI Foundation\VISA\WinNT\include,VC lib目录加入C:\Program Files\IVI Foundation\VISA\WinNT\lib\msc,接下来就是按照之前在Interactive IO中测试完成的功能,翻译成使用VISA通信库发送的程序即可,一个完整的方波设置程序如下:

#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;
}

这里只是最简单的走通流程,在实际使用时,需要将输入的控制量如电压、占空比等做成函数参数,这样就可以通用了。

高大上的工具-CommandExpert

实际上Agilent IO Suite提供了一个非常强大的工具,使用它可以为你自动生成代码:
在Tools中打开CommandExpert,如下:
在这里插入图片描述
在这个工具中,选择要操作的设备,连接后,可以为其编辑一系列SCPI控制命令(最下方显示),最后导出为指定语言和通信库的程序。
由于我本机没有连接设备,所以演示不了,但是这个程序非常容易使用,可以自己摸索一下,对于大型程序使用它非常方便。

原创,转载请注明来自http://blog.csdn.net/wenzhou1219

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐