这篇开发者地带文档的目的是为了向仪器驱动开发者展示如何利用VISA中的格式化I/O服务来执行各种各样的I/O任务。这篇文档假设您具有字符串格式化和ANSI-C格式化说明符的基本知识。关于VISA格式化说明符的更多信息,请参考NI-VISA程序员参考手册。
VISA为使用基于消息通信的仪器之间的通信提供了格式化和缓冲I/O能力。格式化能力包含那些ANSI-C指定的以及对在仪器系统中使用的协议的扩展。为了执行I/O,使用viPrintf(),viScanf(), 和 viQueryf()服务例程并提供合适的格式化字符串。
这篇文档列举了四种不同类别的格式化I/O:整数,浮点数,字符串和数据块。对于每一类都提供了一些例子和描述。在每个例子中,重点放在VISA I/O支持的在驱动开发中最经常使用的格式化说明符和与每种类型的格式化代码协同工作的不同的修饰符。为了消除冗余,所有的例子中的I/O操作都省略了错误检查例程。
1. 整数
2. 浮点数
3. 字符串
4. 数据块
在驱动开发中经常发现整数格式化。除了传递从仪器读取的数值,它页可以表示状态代码(布尔值)或者从仪器返回的错误代码。当对仪器读/写整数值时,你可以使用%d格式化代码,并与长度修饰符(h或者l)和数组修饰符(,)进行配合使用。
使用这个修饰符来对短(16位)整数进行操作。一般它们用来容纳测试结果和状态代码。
例子
这个例子展示了如何将从仪器返回的自测试结果扫描到一个短整数中。
/* Self Test */
…
ViInt16 testResult;
viPrintf (io, "*TST?\n");
viScanf (io, "%hd", testResult); /* read back the test result in short integer */
…
长整数 - %ld, %d
使用这个修饰符来对长(32位)整数进行操作。一般它们用来进行数据传输和错误代码。
例子
这个例子展示了如何将从仪器返回的错误代码扫描到一个32位整数中。
/* Error query */
…
ViInt32 errCode;
viPrintf(io, ":STAT:ERR?\n");
viScanf (io, "%d", &errCode); /* read back error code in integer */
…
这个例子展示了如何格式化采样数(一个32位整数)到一个要发送到仪器的命令字符串中。
/* Send Sample Count */
…
ViInt32 value = 5000;
viPrintf (io, ":SAMP:COUN %d;", value);
…
当对仪器读/写浮点数时,可以使用%f或%e格式化代码,并与长度修饰符(l或者L)和数组修饰符(,)进行配合使用。当编程进行数值传输时浮点数非常重要。
注意:在某些极端情况下,%f不能表示全部的浮点值时,此时使用%e。
使用这个修饰符来表示双精度(64位)浮点数。它们一般用于数据传输。
这个例子展示了如何扫描垂直范围(一个64位浮点数)。
例子
/* Query Vertical Range */
…
ViReal64 value;
viPrintf (io, ":CH1:SCA?\n");
viScanf (io, "%le", &value);
…
这个例子展示了如何格式化触发延时(一个64位浮点数)到一个发送到仪器的命令字符串。
/* Send Trigger Delay */
…
ViReal64 value = 50.0;
viPrintf (io, ":TRIG:<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />DEL %Le;", value);
…
在数据传输时,可以使用精度说明符来精确的指定小数的位数。这个修饰符设置数值的精度。
例子
这个例子展示了如何设置电压解析度。解析度以长双精度浮点数表示(64位)。精度修饰符.9说明小数点后有9位数字。在这种情况下,0.000000005被发送到仪器。
/* Set Resolution */
…
ViReal64 value = 0.0000000051;
viPrintf (io, "VOLT:RES %.9Le", value);
…
浮点数数组说明符(,)
这个修饰符从仪器读写浮点数数组。元素的个数可以用一个常数,星号(*)或者井号(#)表示。星号说明个数位于viPrintf()的第一个参数中。井号说明个数位于iScanf()的第一个参数中。常数可以在viPrintf() 和 viScanf()中使用。
例子
/* Create User Defined Mask */
…
ViInt32 maskSize = 100;
ViReal64 interleaved[100];
…
/* defines points in the specified mask in the selected user coordinates and store the points in the array */
…
viPrintf (io, ":MASK:MASK1:POINTS %*,Le", maskSize, interleaved);
…
Create User Defined Mask例子展示了如何向仪器发送一个长双精度数组。逗号表示参数是一个数组,星号说明从参数传递数组长度。
/* Read Multi-Point */
…
ViInt32 readingCnt = 50;
ViReal64 readingArray[50];
viPrintf (io, "READ?\n");
viScanf (io, "%,#Le", &readingCnt, readingArray);
…
Read Multi-Point例子展示了如何从仪器读取多个数据。逗号表示参数是一个数组,井号指明了从仪器返回的数据的实际个数。
/* FetchMulti-Point */
…
ViReal64 readingArray[1000];
viScanf(io, "%,1000le", readingArray);
…
Fetch Multi-Point展示了如何从仪器取出多个读数。逗号表示参数是一个数组,常数1000指明了读数的个数。
在传递字符串时,可以使用%s, %t, %T 和 %[]格式化代码和一个域宽修饰符。因为这是一个基于消息的通信系统,所以字符串格式化出现最为频繁。使用字符串格式化,你可以配置仪器以及查询仪器信息。
从仪器读取字符到一个字符串中,直到读取到一个空格。
例子
/* Trigger Source Query */
…
ViChar rdBuffer[BUFFER_SIZE];
ViInt32 rdBufferSize = sizeof(rdBuffer);
viPrintf (io, ":TRIG:SOUR?\n");
viScanf (io, "%#s", &rdBufferSize, rdBuffer);
…
Trigger Source Query查询触发源。仪器返回一个字符串,字符串的最大长度通过格式化字符串中的井号指定。参数rdBufferSize包含了输入的最大长度,它包含了实际读取的字节数。
从仪器读取字符到一个字符串中,直到读取到一个END字符。这通常是,但不总是换行符(\n)。使用%T解析换行符而不是END。
例子
/* Instrument Model Information */
…
ViChar moduleStr[BUFFER_SIZE];
ViInt32 modelNumber;
viPrintf (io, "*IDN?\n");
viScanf (io, "TEKTRONIX,TDS %ld,%t", &modelNumber, moduleStr);
…
Instrument Model Information查询一个泰克仪器的仪器型号。型号是一个长整数,它位于从仪器返回的字符串的前两个“,”之间。格式化字符串%t指定从仪器读取字符串直到遇到END。例如,仪器返回TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04\n,型号是210,模块字符串是0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04\n。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
如果没有星号,将从仪器读取字符直到读到^后面的字符。如果带星号,将抛弃读到的字符直到读到^后面的字符。
例子
/* Self Test */
…
ViChar testMessage[256];
viPrintf (io, "TST\n");
viScanf (io, "%256[^\n]", testMessage);
…
Self Test例子是展示了如何执行自测试。在这种情况下,格式化字符串%256[^\n]指定了字符串的最大宽度为256,并且终止于换行符(LF)。
/* Error Query */
…
ViInt32 errCode;
ViChar errMessage[MAX_SIZE];
viPrintf(io, ":STAT:ERR?\n");
viScanf (io, "%ld,\"%[^\"]\"", &errCode, errMessage);
…
Error Query例子展示了如何查询错误。仪器返回一个整数错误代码和一个带双引号的字符串。消息位于引号中。
/* Instrument Manufacturer */
…
ViChar rdBuffer[256];
viQueryf (io, "*IDN?", "%256[^,]%*T", rdBuffer);
…
Instrument Manufacturer例子展示了如何查询仪器制造商。制造商名称位于从仪器返回的字符串的第一部分,直到字符“,”。例如,仪器返回ROHDE&SCHWARZ,NRVD, 835430/066,V1.52 V1.40\n。制造商名称ROHDE&SCHWARZ。其余部分被舍弃。
/* Instrument Model Information */
…
ViChar rdBuffer[256];
viQueryf (io, "*IDN?", "%*[^,],%256[^,]%*T", rdBuffer);
…
Instrument Module Information例子展示了如何查询仪器型号。型号位于从仪器返回的字符串的第一部分,位于头两个字符“,”之间。例如,仪器返回ROHDE&SCHWARZ,NRVD, 835430/066,V1.52 V1.40\n。型号为NRVD。格式化字符串%*[^,]舍弃第一个字符“,”之前的所有字符。响应的最后部分也被舍弃。
/* Instrument Firmware Revision */
…
ViChar rdBuffer[256];
viQueryf (io, "ROM?", "%256[^\r]", rdBuffer);
…
Instrument Firmware Revision例子查询固件版本。固件版本信息是回车符(CR)之前的所有字符。
未完待续
用户173060 2009-7-2 10:22