Files
usb-6009/NI-VISA/Examples/C/Gpib/AsyncIO.c
2024-11-01 11:47:29 -07:00

178 lines
7.1 KiB
C

/**************************************************************************/
/* Asynchronous I/O Completion Example */
/* */
/* This example shows how to use an asynchronous event handling function */
/* that is called when an asynchronous input/output operation completes. */
/* Compare this to viRead and viWrite which block the application until */
/* either the call returns successfully or a timeout occurs. Read and */
/* write operations can be quite slow sometimes, so these asynchronous */
/* operations will allow you processor to perform other tasks. */
/* The code uses VISA functions and sets a flag in the callback upon */
/* completion of an asynchronous read from a GPIB device to break out of */
/* an otherwise infinite loop. The flow of the code is as follows: */
/* */
/* Open A Session To The VISA Resource Manager */
/* Open A Session To A GPIB Device */
/* Install A Handler For Asynchronous IO Completion Events */
/* Enable Asynchronous IO Completion Events */
/* Write A Command To The Instrument */
/* Call The Asynchronous Read Command */
/* Start A Loop That Can Only Be Broken By A Handler Flag Or Timeout */
/* Print Out The Returned Data */
/* Close The Instrument Session */
/* Close The Resource Manager Session */
/**************************************************************************/
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
/* Functions like strcpy are technically not secure because they do */
/* not contain a 'length'. But we disable this warning for the VISA */
/* examples since we never copy more than the actual buffer size. */
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "visa.h"
/* Prototype for the event handler for asynchronous i/o completion */
ViStatus _VI_FUNCH AsyncHandler(ViSession vi, ViEventType etype, ViEvent event, ViAddr userHandle);
#define READ_BUFFER_SIZE 4096
static ViJobId job;
static unsigned char data[READ_BUFFER_SIZE];
static ViAddr uhandle;
static ViStatus status, StatusSession;
static ViSession inst, Sessionparam;
static ViEventType EventTypeparam;
static ViAddr Addressparam;
static ViUInt32 BytesToWrite;
static ViSession defaultRM;
static ViUInt32 rcount, RdCount;
static volatile ViBoolean stopflag = VI_FALSE;
static int letter;
static char stringinput[256];
/*
* The handler function. The instrument session, the type of event, and a
* handle to the event are passed to the function along with a user handle
* which is basically a label that could be used to reference the handler.
* The only thing done in the handler is to set a flag that allows the
* program to finish. Always return VI_SUCCESS from your handler.
*/
ViStatus _VI_FUNCH AsyncHandler(ViSession vi, ViEventType etype, ViEvent event, ViAddr userHandle)
{
Sessionparam = vi;
EventTypeparam = etype;
Addressparam = userHandle;
viGetAttribute (event, VI_ATTR_STATUS, &StatusSession);
viGetAttribute (event, VI_ATTR_RET_COUNT, &RdCount);
stopflag = VI_TRUE;
return VI_SUCCESS;
}
int main (void)
{
/*
* First we open a session to the VISA resource manager. We are
* returned a handle to the resource manager session that we must
* use to open sessions to specific instruments.
*/
status = viOpenDefaultRM (&defaultRM);
if (status < VI_SUCCESS)
{
printf("Could not open a session to the VISA Resource Manager!\n");
exit (EXIT_FAILURE);
}
/*
* Next we use the resource manager handle to open a session to a
* GPIB instrument at device 2. A handle to this session is
* returned in the handle inst. Please consult the NI-VISA User Manual
* for the syntax for using other instruments.
*/
status = viOpen (defaultRM, "GPIB::2::INSTR", VI_NULL, VI_NULL, &inst);
/*
* Now we install the handler for asynchronous i/o completion events.
* To install the handler, we must pass our instrument session, the type of
* event to handle, the handler function name and a user handle
* which acts as a handle to the handler function.
*/
status = viInstallHandler (inst, VI_EVENT_IO_COMPLETION, AsyncHandler, uhandle);
/* Now we must actually enable the I/O completion event so that our
* handler will see the events. Note, one of the parameters is
* VI_HNDLR indicating that we want the events to be handled by
* an asynchronous event handler. The alternate mechanism for handling
* events is to queue them and read events off of the queue when
* you want to check them in your program.
*/
status = viEnableEvent (inst, VI_EVENT_IO_COMPLETION, VI_HNDLR, VI_NULL);
/*
* Now the VISA write command is used to send a request to the
* instrument to generate a sine wave. This demonstrates the
* synchronous read operation that blocks the application until viRead()
* returns. Note that the command syntax is instrument specific.
*/
/*
* Here you specify which string you wish to send to your instrument.
* The command listed below is device specific. You may have to change
* command to accommodate your instrument.
*/
strcpy(stringinput,"SOUR:FUNC SIN; SENS: DATA?\n");
BytesToWrite = (ViUInt32)strlen(stringinput);
status = viWrite (inst, (ViBuf)stringinput,BytesToWrite, &rcount);
/*
* Next the asynchronous read command is called to read back the
* date from the instrument. Immediately after this is called
* the program goes into a loop which will terminate
* on an i/o completion event triggering the asynchronous callback.
* Note that the asynchronous read command returns a job id that is
* a handle to the asynchronous command. We can use this handle
* to terminate the read if too much time has passed.
*/
status = viReadAsync (inst, data, READ_BUFFER_SIZE - 1, &job);
printf("\n\nHit enter to continue.");
letter = getchar();
/*
* If the asynchronous callback was called and the flag was set
* we print out the returned data otherwise we terminate the
* asynchronous job.
*/
if (stopflag == VI_TRUE)
{
/* RdCount was set in the callback */
/* Add a NULL terminator to the read buffer */
data[RdCount] = '\0';
printf ("Here is the data: %s", data);
}
else
{
status = viTerminate (inst, VI_NULL, job);
printf("The asynchronous read did not complete.\n");
}
printf ("\nHit enter to continue.");
fflush(stdin);
getchar();
/*
* Now we close the instrument session and the resource manager
* session to free up resources.
*/
status = viClose(inst);
status = viClose(defaultRM);
return 0;
}