【VC++技术杂谈005】如何与程控仪器通过GPIB接口进行通信

在工控测试系统中,经常需要使用到各类程控仪器,这些程控仪器通常具有GPIB、LAN、USB等硬件接口,计算机通过这些接口能够与其通信,从而实现自动测量、数据采集、数据分析和数据处理等操作。本文主要介绍如何与程控仪器通过GPIB接口进行通信。

 

1.GPIB简介

  GPIB是通用总线(General Purpose Interface Bus)的简称。

  GPIB一共由24根线组成,其中8根数据线DB0-DB7,3根握手线(NRFD、DAV、NDAC),5根总线控制线(ATN、SRQ、IFC、REN、EOI),8根地线。

  GPIB是异步数据传输方式的双向总线,总线上的信息按位(bit)并行、字节(byte)串行的方式进行传送。

  详细的GPIB硬件接口介绍请查阅相关资料,这里就不详述了。

 

2.SCPI简介

  SCPI是可编程仪器标准命令(Standard Commands for Programmable Instruments)的简称。

  SCPI规定了在控制器到仪器和仪器到控制器之间的信息交换层消息的构造和内容,因而使得在垂直层面上,同一类型的仪器命令集相似;在水平层面上,不同类型仪器之间,同种功能的SCPI命令也一致。

  SCPI命令分为仪器公用命令和仪器特定控制命令两部分。公用命令用于控制仪器的某些基本功能操作,其句法和语义遵循IEEE488.2规定。仪器特定控制命令是指每个程控仪器完成自身命令操作的特定命令。

  详细的SCPI命令语法请查阅相关资料,这里就不详述了。

 

3.VISA简介

  VISA是虚拟仪器软件架构(Virtual Instrument Software)的简称。

  VISA提供了用于仪器编程的标准I/O函数库,称为VISA库。VISA库提供了统一的设备资源管理、操作和使用机制,它独立于硬件设备、接口、操作系统和编程语言,具有与硬件结构无关的特点。它将用于每个仪器硬件总线类型的更低层次的驱动程序抽象化,并提供一个单一的API实现与仪器的通信,而不必考虑具体的总线接口。

  常用的VISA API有如下一些:

  (1)ViStatus viOpenDefaultRM(ViPSession vi);   //打开缺省资源管理器资源对话通道

  (2)ViStatus viOpen(ViSession sesn, ViRsrc name, ViAccessMode mode, ViUInt32 timeout, ViPSession vi); //打开特定资源的对话通道

  (3)ViStatus viClose(ViObject vi);         //关闭特定资源的对话通道

  (4)ViStatus viPrintf(ViSession vi, ViString writeFmt, ...);   //按设定格式向仪器写数据

  (5)ViStatus viScanf(ViSession vi, ViString readFmt, ...);   //按设定格式从仪器读取数据

  (6)ViStatus viRead(ViSession vi, ViPBuf buf, ViUInt32 cnt, ViPUInt32 retCnt);  //从仪器同步读取数据

  (7)ViStatus viWrite(ViSession vi, ViBuf  buf, ViUInt32 cnt, ViPUInt32 retCnt);  //向仪器同步写入数据

  (8)ViStatus viClear(ViSession vi);         //清除数据

 

4.编程示例

  下面的代码示例了如何通过GPIB接口对2220G-30-1型号的双通道直流电源进行控制。程序运行效果如图1所示。

图1 GPIB示例运行效果

4.1加载VISA库的头文件和库文件

  为了在工程项目中使用VISA API函数对程控仪器进行控制,需要加载VISA库的头文件visa.h和库文件visa32.lib。这两个文件可以在安装GPIB驱动后,在“C:\Program Files\IVI Foundation\VISA\WinNT”目录下的include和lib目录下找到。

  加载这两个文件的具体方法如下:

1 #include "include//visa.h"                                //包含VISA头文件和库文件
2 #pragma comment(lib, "lib//msc//visa32.lib")

4.2连接设备

  点击图1中的“连接设备”按钮,将调用viOpen()函数打开特定资源的对话通道。若对话通道打开成功,则向仪器发送“*IDN?”命令读取设备信息。具体实现代码如下:

复制代码
 1 /*
 2  * 函数功能 : 点击"连接设备"按钮时,该函数被调用
 3  * 备    注 : 
 4  * 作    者 : 博客园 依旧淡然
 5  */
 6 void CGPIBDemoDlg::OnButtonOpenDevice() 
 7 {
 8     viOpenDefaultRM(&m_ViSessionRM);
 9     if(VI_SUCCESS == viOpen(m_ViSessionRM, "GPIB0::1::INSTR", VI_NULL, VI_NULL, &m_ViSession))
10     {
11         char receiveBufferArrary[256] = {0};
12         viPrintf(m_ViSession, "*RST\n");                        //发送复位命令
13         viPrintf(m_ViSession, "*IDN?\n");                      //发送读取设备信息命令
14         viScanf(m_ViSession, "%t", &receiveBufferArrary);
15         m_IsConnected = true;
16         m_StaticDeviceState.Format("设备状态:已连接!");
17         m_StaticDeviceInfo.Format("设备信息:%s \n", receiveBufferArrary);
18         UpdateData(FALSE);
19     }
20     else
21     {
22         m_IsConnected = false;
23         MessageBox("连接设备失败!", "提示", MB_OK|MB_ICONWARNING);
24     }
25 }
复制代码

  由图1可以看到,连接设备成功之后,获取的设备信息为“Keithley instruments, 2220G-30-1, 9010179, 1.16-1.04”。这四个字段分别代表制造商、产品标号、产品序列号以及软件版本号。

4.3设置电压电流

  2220G-30-1型号的双通道直流电源可以设置输出0-30V的直流电压以及0-1.5A的电流。下面的代码给出了设置通道1的电压和电流的方法:

复制代码
 1 /*
 2  * 函数功能 : 点击"通道1设置"按钮时,该函数被调用
 3  * 备    注 : 
 4  * 作    者 : 博客园 依旧淡然
 5  */
 6 void CGPIBDemoDlg::OnButtonChannel1Setting() 
 7 {
 8     UpdateData(TRUE);
 9 
10     if(!m_IsConnected)
11     {
12         MessageBox("请先连接设备!", "提示", MB_OK|MB_ICONWARNING);
13         return;
14     }
15 
16     if(m_EditChannel1Voltage.IsEmpty())
17     {
18         MessageBox("输入电压不能为空!", "提示", MB_OK|MB_ICONWARNING);
19         return;
20     }
21 
22     if(m_EditChannel1Current.IsEmpty())
23     {
24         MessageBox("输入电流不能为空", "提示", MB_OK|MB_ICONWARNING);
25         return;
26     }
27 
28     viPrintf(m_ViSession, "INST:SEL CH1\n");                          //选择通道1
29     viPrintf(m_ViSession, "SOURCE:OUTP:ENAB ON\n");                    //使能输出
30     viPrintf(m_ViSession, "SOURCE:VOLT %sV\n", m_EditChannel1Voltage);         //设置输出电压
31     viPrintf(m_ViSession, "SOURCE:CURR %sA\n", m_EditChannel1Current);          //设置输出电流
32     viPrintf(m_ViSession, "SOURCE:OUTP ON\n");                         //输出
33 }
复制代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458690.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

标题在上边框中的html(fieldset标签)

<fieldset> <legend>标题</legend> 内容 </fieldset> 转载于:https://www.cnblogs.com/lswbk/p/4952820.html

移除项目中的CocoaPods

在项目中移除CocoaPods cocoaPods虽然很方便&#xff0c;但是我是真心的不喜欢用它&#xff0c;总是出错如果你觉得CocoaPods让你的项目出现了问题&#xff0c;不好用甚至是恶心&#xff0c;想将其从项目中彻底移除&#xff0c;也有方法&#xff1a; 1.删除工程文件夹下的Podf…

ShellExecute使用详解

有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。 1.CreateProcess因为使用复杂&#xff0c;比较少用。 2.WinExec主要运行EXE文件。如&#xff1a;WinExec(Notepad.exe Readme.txt, SW_SHOW); 3.ShellExecute不仅可以运行EXE文件&#xff0c;也可以运行…

javascript笔记整理(对象基础)

一、名词解释 1.基于对象&#xff08;一切皆对象&#xff0c;以对象的概念来编程&#xff09; 2.面向对象编程(Object Oriented Programming&#xff0c;OOP) A.对象(JavaScript 中的所有事物都是对象) B.对象的属性和行为 属性:用数据值来描述他的状态 行为:用来改变对象行为的…

java的安装和配置

JRE (JAVA Runtime Enviroment java运行环境),包括JVM(java虚拟机)和java程序所需的核心功能类库&#xff0c;如果只是运行java程序&#xff0c;只需安装JRE。 JDK &#xff08;Java Development Kit 开发工具包&#xff09;包括开发JAVA程序时所需的工具&#xff0c;包括JRE…

#if, #ifdef, #ifndef, #else, #elif, #endif的用法

#ifdef的用法 灵活使用#ifdef指示符&#xff0c;我们可以区隔一些与特定头文件、程序库和其他文件版本有关的代码。 代码举例&#xff1a;新建define.cpp文件 &#xff03;include "iostream.h" int main() { #ifdef DEBUG cout<< "Beginning ex…

redhat 6.6 安装 (LVM)

http://www.cnblogs.com/kerrycode/p/4341960.html转载于:https://www.cnblogs.com/zengkefu/p/4954955.html

MFC对话框最小化到托盘

1、在资源中的Icon中导入一个自己喜欢的图标&#xff0c;ID命名为IDR_MAINFRAME&#xff0c;将先前的IDR_MAINFRAME的图标删除掉&#xff1b; 2、在自己的Dialog头文件中定义一个变量 NOTIFYICONDATA m_nid&#xff0c;关于该结构体的具体信息可以查阅MSDN&#xff1b; 3、添加…

Android acache读后感

今天了解到了一个android轻量级的开源缓存框架,(github&#xff1a;https://github.com/yangfuhai/ASimpleCache),花了一点时间研究了一下源代码&#xff0c;大概的思路就是每个缓存目录对应一个Acache类&#xff0c;通过mInstanceMap关联&#xff08;个人觉得这个主要是减少对…

continue break

块作用域 一个块或复合语句是用一对花括号&#xff08;"{}"&#xff09;括起来的任意数量的简单的java语句。块定义了变量的作用范围。 1、嵌套块是方法内的嵌套&#xff0c;不包括类的花括号。在嵌套块内的 变量是不可以重复定义的。 2、不允许重复定义的是局部变…

GetVersionEx 获取系统版本信息

转自&#xff1a;http://blog.csdn.net/yyingwei/article/details/8286658 最近在windows 8上获取系统版本信息需要调用系统API&#xff0c;于是用到了GetVersionEx。 首先看一看函数原型&#xff1a; [cpp] view plaincopy BOOL GetVersionEx(POSVERSIONINFO pVersionInformat…

popoverController(iPad)

一、设置尺寸 提示&#xff1a;不建议&#xff0c;像下面这样吧popover的宽度和高度写死。 1 //1.新建一个内容控制器2 YYMenuViewController *menuVc[[YYMenuViewController alloc]init];3 4 //2.新建一个popoverController&#xff0c;并设置其内容控制器5 s…

静态成员变量和非静态成员变量的对比

静态成员变量和非静态成员变量的对比 1、存储的数据 静态成员变量存储的是所有对象共享的数据 非静态成员变量存储的是每个对象特有的数据 2、存储位置 静态成员变量是随着类的加载在方法区的静态区开辟内存了 非静态成员变量是随着对象的创建再堆中开辟内存 3、调用方式 静态成…

c++的thread类(c++线程简单用法)

最近看了一个Thread类&#xff08;忘记在哪里看的了&#xff09;&#xff0c;感觉不错。 创建线程时线程对应的函数必须是类的静态成员&#xff0c;由于静态成员无法访问类的非静态成员&#xff0c;我从前都是把对象的指针作为参数传递给线程函数来避免这个问题&#xff0c;但是…

[LeetCode]Merge Sorted Array

题目描述:(链接) Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note:You may assume that nums1 has enough space (size that is greater or equal to m n) to hold additional elements from nums2. The number of eleme…

[LeetCode]Integer to Roman

题目描述:(链接&#xff09; Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. 解题思路&#xff1a; 1 class Solution {2 public:3 string intToRoman(int num) {4 vector<int> values{1000…

[c++]代理对象模式

代理对象 <code class"hljs cpp has-numbering" style"display: block; padding: 0px; box-sizing: border-box; font-family: Source Code Pro, monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius:…

this static 面向对象三大特点

面向对象三大特点&#xff1a;封装、继承、多态 封装&#xff1a;只对外界提供有用的属性和行为 this&#xff1a;是一个引用&#xff0c;总是指向当前对象 static 存放位置是方法区中的静态区 static特点 static修饰的成员变量随着类的加载就在静态区中开辟内存 所…

fastQC

Fastqc用途 FastQC aims to provide a simple way to do some quality control checks on raw sequence data coming from high throughput sequencing pipelines. It provides a modular set of analyses which you can use to give a quick impression of whether your data …

C++代理 Surrogate

容器通常只能包含一种类型的对象&#xff0c;所以很难在容器中存储对象本身。存储指向对象的指针&#xff0c;虽然允许通过继承来处理类型不同的问题&#xff08; 多态性 &#xff09;&#xff0c;但是也增加了内存分配的额外负担。所以我们通过定义名为 代理 的对象来解决该问…