通用计算机平台上IEEE-488兼容仪器的设计
2008-04-01
作者:吕 锋, 陈 园
摘 要: 提出了一个通用计算机平台上IEEE-488兼容仪器的设计方案,给出了系统的软硬件组成,并且对仪器端程序以及状态报告模型的设计进行了说明。该方案主要通过C++" title="C++">C++语言编程实现,具有成本低和可移植性强的特点,目前已经在某基于计算机的测试仪器上得到初步应用并取得了较好的效果。
关键词: IEEE-488(GPIB)接口 SCPI 自动测试系统
通用计算机系统具有强大的处理能力以及丰富的软件资源,正在被越来越多的现代仪器所采用。在仪器的设计过程中,往往需要提供GPIB接口以及相应的指令集" title="指令集">指令集以方便用户组成自动测试系统。针对这一需求,本文提出了一个通用计算机平台上IEEE-488兼容仪器的设计方案:通过使用GPIB接口卡和编写相应的仪器端程序,使得基于计算机的仪器能够模拟一个或者多个GPIB仪器。
1 IEEE-488仪器简介
IEEE-488仪器模型如图1所示。仪器提供GPIB接口以及相应的指令集,指令集由以下几部分组成[1~2]:
(1) IEEE-488.2公用命令集,如:*IDN?,*STB?,*CLS等。
(2) SCPI标准规定的STATus和SYSTem子系统,主要用来报告仪器状态和进行系统设置。
(3) 仪器特定测量功能指令。
其中,(1)和(2)是仪器必备指令,(3)的选取与仪器的实际功能有关。用户只需要将PC机与带有GPIB接口的仪器连接,通过调用仪器控制软件如NI-488.2和VISA等提供的I/O" title="I/O">I/O库向仪器写入指令,就能实现对仪器的控制。
2 系统设计
2.1 系统组成
根据图1所示的模型,在通用计算机平台上设计的IEEE-488兼容仪器软硬件组成如图2所示。
仪器运行在Windows操作系统下,其各部分的功能如下:
(1)PCI-GPIB是NI公司提供的GPIB接口卡。通过安装设备端软件NI-Device" title="NI-Device">NI-Device,使GPIB接口卡完成Talker/Listener功能。
(2)模块函数和必备函数与IEEE-488仪器模型中的仪器函数相对应:模块函数是模块制造商提供的API,大部分用来处理仪器特定测量功能指令;必备函数通过访问状态报告模型和调用某些模块函数处理IEEE-488.2与SCPI标准规定的必备指令。
(3)状态报告模型由若干状态寄存器组" title="寄存器组">寄存器组构成,用来描述仪器的状态。大部分仪器函数都会访问此模型。
(4)仪器端程序采用C++编写,主要负责接收主控计算机发送的指令,然后找到对应的仪器函数进行处理。如果接收的是查询指令,还负责将仪器函数的响应结果返回给主控计算机。
系统的核心是仪器端程序和状态报告模型的设计,以下将对这两部分进行详细说明。
2.2 仪器端程序设计
仪器端的程序完成图1中除仪器函数以外的所有功能。其中,总线的消息处理即图1中GPIB总线、I/O组件、输出队列、消息交换组件、输入队列部分的功能通过调用NI-Device提供的API完成,其余部分由设计者自行完成。
2.2.1 总线消息处理
总线上的消息处理主要通过调用NI-Device提供的API完成。NI-Device是NI公司推出的一款面向仪器制造商的设备端软件,可以为仪器开发人员处理绝大部分的IEEE-488协议要求,并且支持面向对象的C++语言接口[3]。 IEEE-488兼容仪器主要使用以下几个类:
(1)C4882Device:是一个抽象类,是所有设备类的基类,它定义了设备类与总线接口方式。当总线上发生某个事件时,就调用相应的事件处理函数。此外,C4882Device类还负责输入输出队列管理和状态字节报告等。
(2)CGpibDevice:使用GPIB总线的设备类都必须是CGpibDevice类的派生类,它负责处理GPIB总线协议。
(3)C4882MsgBuffer:输入和输出队列使用这个类来存储指令。
NI-Device采用事件驱动的方式处理总线上的消息。仪器端程序只需要从CGpibDevice类派生出自定义的仪器类,然后重载基类C4882Device的InputQueueEvent Handler、OutputQueueEventHandler、 DeviceClearEventHandler事件响应函数,最后编写事件响应代码就能完成与总线间的消息交换。
基于NI-Device的仪器端程序流程如图3所示。其中,从输出队列取出的指令存放在InputQueueEvent Handler函数的pMsgBuf参数中。通过调用AcknowledgeEndOfMessage()即可通知消息交换组件指令已解释完毕;此外,通过调用QueryDetected()可通知消息交换组件检测到一个查询操作。而将结果放入输出队列则通过调用QueueResponseMsg()完成。
需要说明的是,在主控计算机读取响应结果时,NI-Device会自动将输出队列的队首内容取出并返回给主控计算机,并且以一个MSG_SENT事件通知仪器响应结果已被取走,该事件将在OutputQueueEventHandler响应函数中进行处理。DeviceClearEventHandler函数在主控计算机发送Device Clear消息的时候被调用,在该事件处理函数中,仪器端程序完成一些必要的清除工作。
在图3中,SCPI解释器是最关键的部分,它的效率高低直接影响到仪器的性能。以下将说明SCPI解释器的设计。
2.2.2 SCPI解释器
SCPI 是IEEE-488.2上的可程控仪器标准指令集。其命令格式为树状层次结构,可分为多个子系统,每个子系统由一个根命令和一个或数个层次命令构成[4]。例如,MEASure子系统中测量电压周期的命令为:“MEASure:VOLTage:PERiod?”。
解释器的功能是对输入指令进行语法检查并找到对应的仪器函数,其工作流程如下:
(1)首先对输入指令进行扫描,根据分割符(:,空格等)位置将输入的命令拆分为子系统根命令、层次命令、参数以及单位部分。
(2)根据(1)识别的子系统根命令动态加载相应的命令树。图4是一个子系统命令树的例子,每个叶节点除节点内容以外还存放对应仪器函数的编号。
(3)根据(1)识别的层次命令自顶向下遍历命令树,如果遍历成功则返回叶节点仪器函数的编号。如果失败则说明发生语法错误,返回错误编码。最后从内存中释放树结构。
执行组件维护着一个编号与仪器函数的对应表。根据解释器的返回值,执行组件首先判断是否有语法错误。如果没有则通过查表找到该函数,然后验证参数并执行,如果是查询命令,还要将执行结果放入输出队列。如果发生语法错误则通过修改状态报告模型中的相应位表明产生了语法错误。
2.3 状态报告模型
一个符合IEEE-488标准的仪器必须具备如图5所示的状态报告模型。绝大部分仪器函数都会影响到这个模型。其中,每一个寄存器组都是由条件寄存器、边沿过滤器、事件寄存器和事件使能寄存器组成,具体的定义在参考文献[1]和[2]中有明确的规定,在此不再赘述。
一般在两种情况下需要向主控计算机报告仪器的状态:
(1)执行STATus和SYSTem子系统对应的仪器函数时。例如,仪器端接收到指令'STATus:OPERation?”后,对应的仪器函数返回操作状态寄存器组中的事件寄存器的内容,然后由响应格式化组件将返回内容放入输出队列,等待主控计算机的读取。
(2)执行某些IEEE-488.2公用命令对应的仪器函数时。
例如,接收到公用命令“*STB?”后,对应的仪器函数返回状态字节的内容,随后处理流程同(1)。
另外,在执行一些测量功能和公用命令时需要更新仪器状态。例如用户设置了一个可能引起不稳定因素的电压,对应的仪器函数将可疑状态寄存器组中事件寄存器的VOLTage位置为1。状态报告模型的设计需要根据仪器的特定功能对某些寄存器进行扩展或者只实现其中的某些位。
3 实验结果
目前该方案已经在某基于计算机的手机终端测试仪上得到初步应用并取得较好的效果。在主控计算机上用NI-MAX软件向该仪器发送指令询问激活小区是否激活,仪器的返回结果如图6所示。实验结果表明仪器端的程序能够正常工作,且没有出现明显的延时。
以上提出了一个通用计算机平台上IEEE-488仪器的设计方案并在实际应用中取得了较好的效果。由于该方案采用高级语言编程实现,且用户不需要对原有系统做大的修改就能使基于计算机的仪器支持IEEE-488标准,因此具有成本低和可移植性强的特点。
参考文献
1 IEEE std 488.2-1992,IEEE standard codes, formats, protocols, and common commands for use with IEEE std 488.1-1987. IEEE standards digital interface for programmable instrumentation. (ANSI)
2 Standard commands for programmable instruments (SCPI), Version 1999.0.SCPI Consortium, May 1999
3 NI-deviceTM help. National Instruments, April 2004
4 王,侯国屏,赵 伟.可编程仪器控制规范和关键技术(一)[J]. 电测与仪表,2004;(2):22~24