一、概述
虚拟仪器的关键是软件,软件即仪器,软件开发至关重要。NI公司、HP公司、Techtronix公司都开发了虚拟仪器设计软件平台,供用户开发不同应用软件,即多功能虚拟仪器。
NI公司开发的面向仪器和测控过程的图形化开发平台LabVIEW和交互式C/C++开发平台LabWindows/CVI是两种较普及的商品化开发环境,其特点是编程非常方便、人机交互界面好,具有强大的数据可视化分析和仪器控制能力,并提供与其他语言的接口以便实现低层操作和大量数据处理。以下重点介绍这两个软件产品。
二、LabVIEW
LabVIEW英文全称为Laboratory virtual instrument engineering workbench,中文意思是实验室虚拟仪器工程平台。它采用了直观的前面板与流程图式的编程技术,使用图形语言(图形、图形符号、连线等)编程,界面直观形象,对无编程经验的工程师来说是极好的选择。
LabVIEW集成了很多仪器硬件库,如GPIB/VXI/PXI/基于计算机仪器、RS-232/485协议、插入式数据采集、模拟I/O、数字I/O、时间I/O、信号调理、分布式数据采集、图像获取和机器视觉、运动控制、PLC/数据记录等。
LabVIEW的主要特点有:
(1)图形化的编程环境,采用“所见即所得”的可视化技术;
(2)内置程序编程器,采用编译方式运行32位应用程序,速度快;
(3)具有灵活的调试手段,编程者可在源代码上设置断点,单步执行程序;
(4)集成了大量的函数库;
(5)支持多种系统工作平台;
(6)开放式开发平台,提供DDL、OLE等支持;
(7)支持网络功能。
用LabVIEW设计虚拟仪器的方法和步骤有:
(1)建立方案;
(2)建立前面板;
(3)构建图形化的流程图;
(4)数据流程设计;
(5)构造模块和分清层次;
(6)启用图形编辑器编程。
三、LabWindows/CVI
LabWindows/CVI(C for Virtual Instruments)是一个用C语言构建虚拟仪器系统的交互式软件开发环境,能以模块化方式对C语言进行编辑、编译、连接和调试。
LabWindows/CVI集成了GPIB、RS-232、VXI总线通信库、数据采集库和数据分析库及多种驱动程序,供编程者开发数据采集、测控系统等应用程序。
LabWindows/CVI的主要特点有:
(1)集成开发平台。
(2)交互式编程方法。LabWindows/CVI采用事件驱动方式和回调数据方式,对每一函数都提供一个函数面板以便用户选择参数,对变量提供变量声明窗口,这种交互式编程提高了程序的可视化和编程的效率及程序运行的可靠性。
(3)提供简单、直观的图形设计,并支持“所见即所得”可视化编程方法,让编程者快速编写用户界面、可视化数据显示。
(4)较好的兼容性及灵活的程序调试手段。
(5)具有功能强大的函数库,从底层的VXI、GPIB、并口、数据集售卡、硬件控制到各种仪器驱动程序,从基本的数字函数、文件I/O到数据分析函数,应有尽有。
(6)强大的网络支持功能。
(7)提供各种测试、测量和控制模板供用户选用。
用LabWindows/CVI设计虚拟仪器的一般步骤是:
(1)设计一个图形化用户界面接口,系统自动生成头文件(*.h),并生成功能框架源程序文件(*.c)。
(2)创建工程文件,并添加相应的功能函数。
(3)生成可执行文件。
四、用LabWindows/CVI开发虚拟仪器软件功能实例
以开发一个信号发生器及分析仪为例,说明用LabWindows/CVI开发虚拟仪器的方法和步骤。
1.仪器实现功能
本仪器将实现产生正弦信号、进行自相关分析、进行功率谱分析等主要功能。
2.面板设计
根据仪器实现功能分析和传统仪器设计风格,将本信号发生器及分析仪设计成图8-3所示的用户界面(其中,A、B、C⋯L等皆为控件标号),软件编程步骤为:
图8-3 面板设计
·启动LabWindows/CVI系统。
·从菜单中选择【File】/【New】/【User Interface(*.uir)⋯】系统生成一个含有面板A的空白用户图形界面,并设定此文件为example.uir。
·从菜单中选择【Create】/【Text Box】或点右键在弹出的快捷菜单中选择【Text Box】添加一个文本输出框B,用于图形输出提示。
·从菜单中选择【Create】/【Graph】或点右键在弹出的快捷菜单中选择【Graph】添加一个图形输出显示框C,横轴为采样点数,纵轴为幅值,用于图形输出。
·从菜单中选择【Create】/【Numeric】或点右键在弹出的快捷菜单中选择【Numeric】依次添加五个输入型数字控件D、E、F、G、H,名称分别为幅值、采样点数、相位、信号频率和采样频率,这五个控件用于设定生成正弦信号和分析信号的参数。
·从菜单中选择【Create】/【CommandButton】或点右键在弹出的快捷菜单中选择【Command Button】依次添加四个按钮:正弦信号产生按钮I、自相关分析按钮J、自功率谱分析按钮K和退出按钮L,分别用于产生正弦信号、进行自相关分析、进行自功率谱分析和退出程序,并设置各控件的属性(表8-2)。
·文件example.uir存盘后系统会自动生成头文件example.h。
·创建缺省控件事件。从菜单中选择【Code】/【Preferences】/【Default Control Events】在弹出的对话框中选择所需事件,本例中选择EVENT COMMIT为点击事件按钮命令标号和EVENT_RIGHT_CLICK为点右键事件按钮命令标号。
表8-2 控件属性表
·生成源程序文件。从菜单中选择【Code】/【Generate】/【All Code⋯】进入源代码编辑窗口,在生成的源代码框架中选定程序开始时的面板(在本例中应选择PANEL)以及终止程序的功能函数(本例中应选择Quit),点击OK按钮之后,代码编辑器会自动创建程序的部分源代码程序(框架程序)文件example.c。
3.创建工程文件
创建工程文件example.prj,并将example.uir、example.h和example.c添加到工程文件中保存,这是Windows应用程序的要求。
4.仪器功能设计
在框架源程序中需添加功能函数,才能实现仪器功能,函数选择应根据仪器的功能设计要求。以下分三步介绍仪器功能设计,首先介绍本仪器需采用的库函数,然后说明在源程序框架中添加调用库函数的方法,最后列出完整的程序清单。
1)本仪器需用的函数介绍
(1)SineWave函数,功能是产生正弦信号。
函数定义:int status=SineWave(int n,double amp,double f,double*phase,double x[])
输入参数说明:
·参数n,int类型,表示信号的采样点数;
·参数amp,double类型,表示信号幅值;
·参数f,double类型,表示信号频率;
·参数phase,double指针类型,表示信号初相位。
输出参数说明:
·参数phase,double类型,表示信号下一部分的相位;
·参数x[],一维double类型数组,表示信号离散序列值,由以下公式确定:
(2)Correlate函数,功能是进行自相关分析。
函数定义:
int status=Correlate(double x[],int n,double y[],int m,double rxy[])
输入参数说明:
·参数x[],double类型,表示信号1离散序列值;
·参数n,int类型,表示数组x[]的长度;
·参数y[],double类型,表示信号2离散序列值;
·参数m,int类型,表示数组y[]的长度。
输出参数说明:
·参数rxy[],double数组类型,表示数组x[]和y[]的离散互相关运算值,rxy[]的值由以下公式确定:
其中,yj=0(当j<0或j≥m);xi=0(当j<0或j≥n)。
(3)函数AutoPowerSpectrum,功能是进行自功率谱分析。
函数定义:
int status=AutoPowerSpectrum (double x[ ],int n,double dt,double AutoSpectrum[],double*df)
输入参数说明:
·参数x[],double数组类型,表示信号离散序列值;
·参数n,int类型,表示采样点数,n必须是2的幂次方;
输出参数说明
·参数dt,double类型,表示时域信号的采样周期,dt=1/fs,fs是采样频率。
·参数AutoSpectrum[],double数组类型,表示自功率谱运算值,长度至少为n/2,其值由以下公式确定:
·参数df,double指针类型,表示频率间隔。
2)在源程序文件中添加函数的方法
在源程序文件中添加函数的方法是:首先将编辑光标定在需添加函数处,然后在菜单中选择调用该函数的函数面板命令,在函数面板中选择所需的参数,确认后系统自动将函数及参数填写在该光标处。如需调用GetCtrlVal()函数,直接在菜单中选择【Labaray】/【UserInterface】/【Controls/Graphs/Strip Charts⋯】/【General Functions⋯】/【Get Control Value】命令,在弹出的功能函数窗口中添加相应的代码,然后在该窗口中选择【Code】/【Insert FunctionCall】命令将此函数添加进源程序。
将本仪器中所用函数及选择函数面板命令列入表8-3。
表8-3 函数及选择函数面板命令列表
3)在源程序中设计仪器功能
现在可以设计仪器功能,打开example.c,可见自动生成的源程序,这是仪器功能框架。在源程序中添加相应的函数来实现仪器功能,添加函数的方法如上所述。以下程序是完整的程序清单,其中黑体语句为添加代码,其余为系统自动生成的源程序代码:
#include<analysis.h>
#include<ansi_c.h>
#include<cvirte.h>
#include<userint.h>
#include″example.h″
static int panelHandle;
double wave[32767]; /*全局变量*/
int main(int argc,char argv[]) / 主函数体*/
{
if(InitCVIRTE(0,argv,0)==0)
return—1; /* out of memory */
if((panelHandle=LoadPanel(0,″example.uir″,PANEL))<0)
return—1;
DisplayPanel(panelHandle);
RunUserInterface();
DiscardPanel(panelHandle);
return 0;(www.xing528.com)
}
int CVICALLBACK Sine(int panel,int control,int event,
void *callbackData,inteventData1,inteventData2)
/* 产生正弦信号的按钮功能函数体*/
{
double samfre,sigfre,phase,amp;
intnum;
GetCtrlVaI(panelHandle,PANEL_AMP,&); /*获取控件AMP设定的幅值参数amp */
GetCtrlVal(panelHandle,PANEL_NUM ,&num);/*获取控件NUM 设定的采样点数参数num */
GetCtrlVal(panelHandle,PANEL_PHASE,&phase);
/*获取控件PHASE设定的相位参数phase */
GetCtrlVal(panelHandle,PANEL_SIGNALFRE,&sigfre);
/*获取控件SIGNALFRE设定的信号点数参数sigfre */
GetCtrlVal(panelHandle,PANEL_SAMPLEFRE,&samfre);
/*获取控件SAMPLEFRE设定的采样点数参数samfre */
switch(event)
{
case EVENT _COMMIT: /*点击正弦信号按钮事件*/
ResetTextBox(panelHandle,PANEL_TEXTBOX,″正弦信号″); /*波形显示提示*/
SineWave(num,amp,sigfre/samfre,&phase,wave); /*生成正弦信号*/
DeleteGraphPlot(panelHandle,PANEL_GRAPH,﹣1,VAL_IMMEDIATE_DRAW);
/*刷新图形*/
PlotY(panelHandle,PANEL_GRAPH,wave,num,VAL_DOUBLE,VAL_THIN_LINE,VAL
_EMPTY_SQUARE,VAL_SOLID,1,VAL_RED); 正弦信号图形显示*/
break;
case EVENT_RIGHT_CLICK: /*点击正弦信号按钮右键事件*/
MessagePopup(″请选择″,″幅值、采样点数、相位、采样频率和信号频率″); /*显示提示框*/
break;
}
return 0;
}
int CVICALLBACK AutoCorrelate(int panel,int control,int event,
void *callbackData,inteventData1,int eventData2)
/*正弦信号的自相关按钮功能函数体*/
{
int num,i;
double*Cor;
switch(event)
{
case EVENT_COMMIT:
ResetTextBox(panelHandle,PANEL_TEXTBOX,″自相关分析″);
GetCtrlVal(panelHandle,PANEL_NUM,&num);
Cor=malloc(2*num*(sizeof(double))); /*动态分配数组内存*/
Correlate(wave,num,wave,num,Cor); /*进行自相关分析*/
for(i=0;i<2*num;i++){Cor[i]=Cor[i]/num;}
DeleteGraphPlot(panelHandle,PANEL_GRAPH,﹣1,VAL_IMMEDIATE_DRAW);
PlotY(panelHandle,PANEL_GRAPH,Cor,2*num,VAL_DOUBLE,VAL_THIN_LINE,
VAL_EMPTY_SQUARE,VAL_SOLID,1,VAL_RED); 显示自相关分析图形*/
free(Cor); /*释放数组内存*/
break;
case EVENT_RIGHT_CLICK:
break;
}
return 0;
}
int CVICALLBACK PowerSpectrum(intpanel,int control,int event,
void *callback Data,intevent Data1,intevent Data2)
/* 正弦信号的自功率谱按钮功能函数体*/
{
double samfre,df,*AutoSpe;
int num;
GetCtrlVal(panelHandle,PANEL_NUM,&num); /*获取采样点数值*/
GetCtrlVal(panelHandle,PANEL_SAMPLEFRE,&samfre); /最获取采样频率*/
switch(event)
{
case EVENT_COMMIT:
if(num%2) /*判断是否为2的幂*/
{
DeleteGraphPlot(panelHandle,PANEL_GRAPH,﹣1,VAL_IMMEDIATE_DRAW);
/*刷新图形*/
MessagePopup(″注意″,″采样点数必须为2的幂″); /*显示提示框*/
}
else
{
ResetTextBox(panelHandle,PANEL_TEXTBOX,″自功率谱分析″); /*波形显示提示*/
AutoSpe=malloc(num*sizeof(double)); /*动态分配数组*/
AutoPowerSpectrum(wave,num,1/samfre,AutoSpe,&df); /*进行自功率谱分析*/
DeleteGraphPlot(panelHandle,PANEL_GRAPH,﹣1,VAL_IMMEDIATE_DRAW);
/*刷新图形*/
PlotY(panelHandle,PANEL_GRAPH,AutoSpe,num/2,VAL_DOUBLE,VAL_THIN_LINE,VAL_CEMPTY_SQUARE,VAL_SOLID,1,VAL_RED);
/*显示自功率谱分析*/
free(AutoSpe); /*释放数组内存*/
}
break;
case EVENT_RIGHT_CLICK:
break;
}
return 0;
}
int CVICALLBACK Quit(intpanel,intcontrol,int event,voidcallbackData,int event Data1,int
eventData2) /*终止功能函数体*/
{
switch(event)
{
case EVENT_COMMIT:
QuitUserInterface(0); /*终止程序*/
break;
case EVENT_RIGHT_CLICK:
break;
}
return 0;
}
5.编译运行
在example.uir、example.h和example.c任一窗口菜单中选择【Run】/【Debug example. exe】对程序进行调试运行,系统将生成如图8-3所示用户界面的虚拟仪器,部分运行结果见图8-4、图8-5、图8-6。
图8-4是产生正弦信号图,先选择幅值、采样点数、相位、信号频率和采样频率这五个控件参数,点击正弦按钮,即产生设定参数的正弦信号,并显示在图形输出窗口中。若在正弦按钮上点击右键,屏幕弹出一个提示框,提示所需选择的参数。
图8-5是正弦信号的自相关分析图,点击自相关按钮即显示正弦信号的自相关分析图形。
图8-6是正弦信号的自功率谱图,点击自功率谱按钮,如果采样点数为2的幂,则直接显示功率谱图,否则弹出提示框,提示所需的采样点数,确定后再显示功率谱图。
图8-4 产生的正弦信号
图8-5 正弦信号的自相关分析
图8-6 正弦信号的自功率谱分析
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。