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

203 lines
7.4 KiB
C

/**************************************************************************/
/* Asynchronous SRQ Event Handling Example */
/* */
/* This example shows how to use an asynchronous event handling function */
/* that is called when a service request (SRQ) is issued. */
/* This code uses VISA functions and sets a flag in the handler for the */
/* occurrence of a service request 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 An Event Handler For SRQ Events */
/* Enable SRQ Events */
/* Write A Command To The Instrument To Cause It To Generate An SRQ */
/* Start An Infinite Loop That Can Only Be Stopped By A Handler Flag */
/* Print Out The 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 SRQ event handler */
ViStatus _VI_FUNCH SRQhandler(ViSession vi, ViEventType etype, ViEvent event, ViAddr userHandle);
#define READ_BUFFER_SIZE 4096
static unsigned char data[READ_BUFFER_SIZE];
static ViAddr uhandle;
static ViStatus status;
static ViUInt32 BytesToRead;
static ViSession inst;
static ViSession defaultRM;
static ViSession Sessionparam;
static ViEventType EventTypeparam;
static ViAddr Addressparam;
static ViUInt32 rcount, rdcount=0;
static volatile ViBoolean stopflag = VI_FALSE;
static int letter;
static char stringinput[256];
/*
* The instrument session, the type of event, and a handle to the event are
* passed to the event handler function along with a user handle which is basically a
* label that could be used to reference the handler.
* First, the event handler calls viReadSTB() to get the serial poll byte from the
* instrument. With GPIB SRQ events, viReadSTB() must be called otherwise
* later SRQ events will not be detected. The handler then reads in the
* data to a global variable and sets a flag that allows the program to
* finish. This is an instrument specific implementation that requires
* viWrite() and viRead() to be called here. Always return VI_SUCCESS from your handler.
*/
ViStatus _VI_FUNCH SRQhandler(ViSession vi, ViEventType etype, ViEvent event, ViAddr userHandle)
{
ViUInt16 stb;
Sessionparam = vi;
EventTypeparam = etype;
Addressparam = userHandle;
status = viReadSTB (inst, &stb);
strcpy (stringinput,"SENS: DATA?\n");
status = viWrite (vi, (ViBuf)stringinput, (ViUInt32)strlen(stringinput), &rcount);
BytesToRead = READ_BUFFER_SIZE - 1;
status = viRead (vi, data, BytesToRead, &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 address 2. A handle to this session is
* returned in the handle inst.
*/
status = viOpen (defaultRM, "GPIB::2::INSTR", VI_NULL, VI_NULL, &inst);
if (status < VI_SUCCESS)
{
printf("Could not open a session to the device simulator\nHit enter to continue.");
fflush(stdin);
getchar();
goto Close;
}
/*
* Now we install the handler for service request events.
* We must pass our instrument session to the handler, the type of
* event to handle, the handler function name and a user handle
* which acts as a user-defined handle passed to the handler
* function.
*/
status = viInstallHandler (inst, VI_EVENT_SERVICE_REQ, SRQhandler, uhandle);
if (status < VI_SUCCESS)
{
printf("The event handler could not be successfully installed.\nHit enter to continue.");
fflush(stdin);
getchar();
goto Close;
}
/* Now we must actually enable the service request event so that our
* handler will see the events. Note that one of the parameters is
* VI_HNDLR indicating that we want the SRQ events to be handled by
* an asynchronous handler. The alternate mechanism for handling
* events is to queue them and read events from the queue when
* you want to dequeue them in your program.
*/
status = viEnableEvent (inst, VI_EVENT_SERVICE_REQ, VI_HNDLR, VI_NULL);
if (status < VI_SUCCESS)
{
printf("The SRQ event could not be enabled.\nHit enter to continue.");
fflush(stdin);
getchar();
goto Close;
}
/*
* Now the VISA write function is used to instruct the
* instrument to generate a sine wave and assert the SRQ line
* when it is finished. Notice that this is specific to one
* particular instrument.
*/
strcpy (stringinput,"*ESE 0x01; *SRE 0x20; SOUR:FUNC SIN; *OPC\n");
status = viWrite (inst, (ViBuf)stringinput, (ViUInt32)strlen(stringinput), &rcount);
printf("The program has passed all of the other status tests.\n");
if (status < VI_SUCCESS)
{
printf("Error writing to the instrument.\nHit enter to continue.");
fflush(stdin);
getchar();
goto Close;
}
/*
* Now the program goes into a wait loop which will only terminate
* if a service request event triggers the asynchronous callback.
*/
printf("Hit enter to continue.");
letter = getchar();
/*
* If the asynchronous event handler was called, then stopflag was set.
* Now, we print out the data read back.
*/
if (stopflag == VI_TRUE)
{
/* rdcount was set in callback */
/* Add a NULL terminator to the read buffer */
data[rdcount] = '\0';
printf ("Here is the data %s\n", data);
printf ("Hit enter to continue.");
fflush(stdin);
getchar();
}
/*
* Now we must uninstall the event handler, and close the session to
* the instrument and the session to the resource manager.
*/
status = viUninstallHandler (inst, VI_EVENT_SERVICE_REQ, SRQhandler, uhandle);
if (status < VI_SUCCESS)
{
printf("There was an error uninstalling the handler.\nHit enter to continue.");
fflush(stdin);
getchar();
}
Close:
status = viClose (inst);
status = viClose (defaultRM);
return 0;
}