⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setup.c

📁 使用NI公司的LabwindowsCVI平台开发虚拟仪器频谱分析仪的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <ansi_c.h>
#include <analysis.h>
#include <Dataacq.h>
#include <cvirte.h>						// Needed if linking in external compiler; harmless otherwise
#include <userint.h>
#include "setup.h"
#include <nidaqex.h>					// Holds typedef for shortened declarations like i32, f64, etc.

static int panelHandle;					// Reference to user interface
static u16 iDevice;						// Device number (assigned by configuration, specified by user)
int bStart = 0;							// Boolean used to determine if timer callback should acquire data
u16 iWindow;							// Window applied to acquired data
int iChan2Graph;						// Channel to graph, according to user
f64 dDesiredRate;						// Rate of acquisition (pts/sec)
int numChans;							// Number of channels to acquire
u16 TransformSize;						// Actual size of transform (currently either 1024, 2048, or 4096)
i16 *chanVect;							// Integer array of channels that initializes mult channel acquisition
i16 *gainVect;							// Integer array of gains used to initialize multiple channel acquisition
int newIndex;							// Current position within buffer
i32 *Buffer;							// Double Buffer used by card for acquisition
i32 *plot;		  						// Binary data obtained from acquisition
f64 *vplot;								// Scaled voltage data
f64 *power;								// Scaled data after FFT conversion to Power Spectrum
u16 Resolution;							// User chosen specification (currently either 495, 950, or 1900)
int start;								// Position of newest unread element


/* Protorype for DSA_board function */   
void board(void);

//******************************************
// main
//******************************************
int main (int argc, char *argv[])
{
	if (InitCVIRTE (0, argv, 0) == 0)	/* Needed if linking in external compiler; harmless otherwise */
		return -1;	/* out of memory */
	if ((panelHandle = LoadPanel (0, "setup.uir", PANEL)) < 0)
		return -1;
	DisplayPanel (panelHandle);

	/* Begin by removing Stop button -- you have to start first */
	SetCtrlAttribute (panelHandle, PANEL_STOP, ATTR_VISIBLE, 0);
	
	/* Default option to start is using DSA 4451, so remove the extra channel options */
	SetCtrlAttribute (panelHandle, PANEL_CH2, ATTR_VISIBLE, 0);
	SetCtrlAttribute (panelHandle, PANEL_CH3, ATTR_VISIBLE, 0);
	SetCtrlAttribute (panelHandle, PANEL_GAIN2, ATTR_VISIBLE, 0);
	SetCtrlAttribute (panelHandle, PANEL_GAIN3, ATTR_VISIBLE, 0);
	SetCtrlAttribute (panelHandle, PANEL_COUPLING2, ATTR_VISIBLE, 0);
	SetCtrlAttribute (panelHandle, PANEL_COUPLING3, ATTR_VISIBLE, 0);

	board();
	
	RunUserInterface ();
	return 0;
}
 
//******************************************
// StartAcquire - When you push Start, the
// program should allow the user to only
// choose Stop or change window style. Also,
// get the values from the controls and
// initialize the device to run.  Note that
// the timer actually checks the double
// buffer and performs the acquisition and
// plotting.
//******************************************
int CVICALLBACK StartAcquire (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	int temp1, temp2;				// Extra variables used for counting purposes (in for loop)
	int iCh[4];						// Integer array of selected channels to monitor
	i16 iGain[4];					// Integer array of gain for each channel
	u16 iCoup[4];					// Integer array of coupling choice for each channel
	int iTrigger;					// Start Trigger option: external or internal
	i16 iTimebase;					// Timebase specified by DAQ_Rate
	i16 iSampleInterval;			// Sample interval specified by DAQ_Rate
	f64 dActualRate;				// Actual Acquisiton Rate - used for DAQ_Set_Clock (DSA Only)
	float Range;
	float max;
	
	switch (event)
		{
		case EVENT_COMMIT:
			/* Get channel information */
			GetCtrlVal (panelHandle, PANEL_CH0, &iCh[0]);
			GetCtrlVal (panelHandle, PANEL_CH1, &iCh[1]);
			GetCtrlVal (panelHandle, PANEL_CH2, &iCh[2]);
			GetCtrlVal (panelHandle, PANEL_CH3, &iCh[3]);
			
			/* Determine number of channels to acquire */
			numChans = iCh[0] + iCh[1] + iCh[2] + iCh[3]; 			// Determine how many channels to scan
			
			/* If user chooses to watch no channels, warn user */
			if (numChans == 0)
			{
				bStart = 0;
				MessagePopup ("Warning: No Channels Chosen",
							  "You have not chosen any channels to acquire.  Please check at least one box.");
				break;
			}
			
			bStart = 1;

			/* When start acquisition, user can only choose stop */
			SetCtrlAttribute (panelHandle, PANEL_START, ATTR_VISIBLE, 0);
			SetCtrlAttribute (panelHandle, PANEL_STOP, ATTR_VISIBLE, 1);
			SetCtrlAttribute (panelHandle, PANEL_QUIT, ATTR_VISIBLE, 0);

			/* Dim controls so that user will not change them during operation */
			SetCtrlAttribute (panelHandle, PANEL_DEVICE, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_BOARD, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_TRIGGER, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_CHLABEL, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_CH0, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_CH1, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_CH2, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_CH3, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_RANGEDESC, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_RANGE, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_GAINTITLE, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_GAIN0, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_GAIN1, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_GAIN2, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_GAIN3, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_COUPTITLE, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_COUPLING0, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_COUPLING1, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_COUPLING2, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_COUPLING3, ATTR_DIMMED, 1);
			SetCtrlAttribute (panelHandle, PANEL_RESOLUTION, ATTR_DIMMED, 1);
			
			/* Clear the graphs */
			ClearStripChart (panelHandle, PANEL_TIMECHART);
			DeleteGraphPlot (panelHandle, PANEL_FREQGRAPH, -1, VAL_IMMEDIATE_DRAW);
			

			/* Get values from controls */
			GetCtrlVal (panelHandle, PANEL_DEVICE, &iDevice);
			GetCtrlVal (panelHandle, PANEL_TRIGGER, &iTrigger);
			GetCtrlVal (panelHandle, PANEL_COUPLING0, &iCoup[0]);
			GetCtrlVal (panelHandle, PANEL_COUPLING1, &iCoup[1]);
			GetCtrlVal (panelHandle, PANEL_COUPLING2, &iCoup[2]);
			GetCtrlVal (panelHandle, PANEL_COUPLING3, &iCoup[3]);
			GetCtrlVal (panelHandle, PANEL_GAIN0, &iGain[0]);
			GetCtrlVal (panelHandle, PANEL_GAIN1, &iGain[1]);
			GetCtrlVal (panelHandle, PANEL_GAIN2, &iGain[2]);
			GetCtrlVal (panelHandle, PANEL_GAIN3, &iGain[3]);
			GetCtrlVal (panelHandle, PANEL_RESOLUTION, &Resolution);
			GetCtrlVal (panelHandle, PANEL_WINDOW, &iWindow);
			GetCtrlVal (panelHandle, PANEL_RANGE, &Range);
			
			/* Initialize board with chosen device, start trigger */
			DAQ_Config (iDevice, iTrigger, 0);
			
			chanVect = calloc (numChans, sizeof(short));    	// Creates a channel array of proper size
			gainVect = calloc (numChans, sizeof(short));    	// Creates a gain array of proper size
			
			/* Add the chosen channels to chanVect */
			temp1 = 0;
			for (temp2=0;temp2<4;temp2++)
			{
				if (iCh[temp2])										// If the user has chosen to monitor channel
				{
					/* The first channel is the default display */
					if (!temp1)
					{
						SetCtrlVal (panelHandle, PANEL_CHAN2GRAPH, temp2);
						iChan2Graph = 0;
					}
					
					chanVect[temp1] = temp2;						// Add channel to array
					gainVect[temp1] = iGain[temp2];        			// Apply no gain to channels
					temp1++;										// Increment to next element of chanVect (gainVect)
			
					/* Check coupling values and set to proper constants */
					if (iCoup[temp2] == 0)
					{
						iCoup[temp2] = ND_AC;
					}
					else
					{
						iCoup[temp2] = ND_DC;
					}
			
					/* Configure channel for chosen coupling - available on DSA 445x and PCI-611x boards */
					AI_Change_Parameter (iDevice, temp2, ND_AI_COUPLING, iCoup[temp2]);
				}
			}

			/* Determine required rate of acquisition necessary to get specified frequency
			   range and resolution */
			dDesiredRate = (1024/475.0)*Range;

			/* Multiply lines of resolution by 1024/475 (combination of Nyquist Theorem and DSA
			   properties) to get number of points to acquire for proper FFT. */
			TransformSize = Resolution * 1024/475;
			
			/* Set the buffer length equal to eight times the FFT Transform length times number of channels */
			Buffer = (i32 *) calloc (8*TransformSize*numChans, sizeof(i32));
			
			/* Allocate the plot arrays to the proper size */
			plot      = (i32 *) calloc (TransformSize, sizeof(i32));
			vplot     = (f64 *) calloc (TransformSize, sizeof(f64));
			power     = (f64 *) calloc (TransformSize, sizeof(f64));

			/* Set increment of time domain's X-axis */
			SetCtrlAttribute (panelHandle, PANEL_TIMECHART, ATTR_XAXIS_GAIN,
							  1/dDesiredRate);

			/* Set the y-axis of the time domain */
			switch (gainVect[0])
			{
				case -20:
					max = 42.4;
					break;
				case -10:
					max = 31.6;
					break;
				case 0:
					max = 10;
					break;
				case 10:
					max = 3.16;
					break;
				case 20:
					max = 1;
					break;
				case 30:
					max = .316;
					break;
				case 40:
					max = .1;
					break;
				case 50:
					max = .0316;
					break;
				case 60:
					max = .01;
					break;			   
			}
		
			SetAxisScalingMode (panelHandle, PANEL_TIMECHART, VAL_LEFT_YAXIS,
								VAL_MANUAL, -max, max);
					
			/* Set X-axis range and scale for frequency graph */
			SetCtrlAttribute (panelHandle, PANEL_FREQGRAPH, ATTR_XAXIS_GAIN, dDesiredRate/TransformSize);
			SetAxisScalingMode (panelHandle, PANEL_FREQGRAPH, VAL_XAXIS,
								VAL_MANUAL, 0.0, Range*TransformSize/dDesiredRate);

			/* Configure timeout value -- this is how long device allows
			   for DAQ_DB_Transfer to complete.  Note that the second parameter
			   is the number of clock ticks to wait (1 tick = 0.55 sec). */
			Timeout_Config (iDevice, 100);
			
			/* Configure the card for double buffered acquisition so that infinite memory not required */
			DAQ_DB_Config (iDevice, 1);
			
			/* Set rate of acquisition on DSA board */
			DAQ_Set_Clock (iDevice, 0, dDesiredRate, 0, &dActualRate);
			
			/* Set scan method for multiple channels */
			SCAN_Setup (iDevice, numChans, chanVect, gainVect);
			
			/* Begin scanning of channels - note the last four parameters don't matter for DSA boards */
			SCAN_Start (iDevice, (i16 *)Buffer, 8*TransformSize*numChans, 0, 0, 0, 0);
			
			/* Buffer begins reading at element 0 */
			newIndex = 0;
			
			/* DSA_Monitor's reader also starts at 0 */
			start = 0;
			
			break;
		}
	return 0;
}

//******************************************
// CheckAndPlot - If you have chosen Start,
// this function will check the readiness of
// the buffer during timer ticks.  If it is
// half-full, it pulls out half the data and
// plots them as requested.
//******************************************
int CVICALLBACK CheckAndPlot (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	int index,status;					// Current location within buffer
	short daqStop;					// 1 if acquisition stops due to error
	double deltaF;					// Resolution of FFT, according to AutoPowerSpectrum
	WindowConst WinCons;			// Output parameter of ScaledWindow function

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -