📄 dadmabm.cpp
字号:
/*
****************************************************************************************
* Program : DADMABM.CPP *
* Description : Demo program for analog output function with Bus Master DMA triggering *
* Boards Supp. : *
* APIs used : DRV_DeviceOpen,DRV_DeviceClose, DRV_GetErrorMessage, *
* DRV_FAODmaStart, DRV_FAOStop, DRV_FAOScale, *
* DRV_AllocateDMABuffer, DRV_FreeDMABuffer *
* Revision : 1.00 *
* Date : 10/16/2003 Advantech Co., Ltd. *
****************************************************************************************
*/
#include <windows.h>
#include <windef.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include "..\..\..\..\include\driver.h"
#include "..\..\..\..\include\event.h"
#define MAX_DEVICES 100
HGLOBAL hVoltageBuf, hBinaryBuf;
/******************************
* Local function declaration *
******************************/
void ErrorHandler(DWORD dwErrCde);
void ErrorStop( long*, DWORD, long* , USHORT**, float**);
void SetRealBuffer(float *lpBuf, long num, USHORT);
BOOL AllocateDataBuffer(
long lDrvHandle,
int iSamples,
long *plDMABuf,
USHORT **pBinaryBuf,
float **pFloatBuf);
void FreeDataBuffer(long lDrvHandle, long *plDMABuf, USHORT **pBinaryBuf,
float **pFloatBuf);
void UserThread();
DWORD dwThreadID;
HANDLE hThreadHandle;
BOOL bThreadloop;
long lDriverHandle;
void main()
{
DWORD dwErrCde;
ULONG lDevNum;
int i;
USHORT usChan;
USHORT usNumberOfOutputs;
short gnNumOfDevices;
short nOutEntries;
DEVLIST DeviceList[MAX_DEVICES ];
long lDmaBuf; //DMA buffer pointer
float* pfVoltageBuf; //User buffer
USHORT* pusBinaryBuf; //User buffer
PT_FAOScale tFAOScale;
PT_FAODmaStart tFAODmaStart; // FAODMAStart table
PT_EnableEvent tEnableEvent;
//Step 1: Display hardware and software settings for running this example
printf("\n\t\t\t Demo the Analog Output with Bus Master DMA (Only for cyclic mode)\n\n");
printf("Before running this example,\n");
printf("please use the device installation utility to add the device on Device Number.\n\n");
// Add type of PC Laboratory Card
dwErrCde = DRV_DeviceGetList(&DeviceList[0], MAX_DEVICES, &nOutEntries);
// Return the number of devices which you install in the system using
// Device Installation
dwErrCde = DRV_DeviceGetNumOfList(&gnNumOfDevices);
printf("This is the installed device list:\n");
for (i = 0; i < gnNumOfDevices; i++)
{
printf(" %3.3d %s\n",DeviceList[i].dwDeviceNum,DeviceList[i].szDeviceName);
}
//Step 2: Input parameters
printf("\nPlease input parameters:");
printf("\nDevice Number (check the device installation utility): ");
scanf("%d", &lDevNum);
printf("\nOutput Channel: ");
scanf("%d", &usChan);
usNumberOfOutputs = 32768; // minimum number of outputs = 2048
//Step 3: Open device
dwErrCde = DRV_DeviceOpen(lDevNum, &lDriverHandle);
if (dwErrCde != SUCCESS)
{
ErrorHandler(dwErrCde);
printf("Program terminated!\n");
printf("Press any key to exit....");
getch();
exit(1);
}
// Step 4: Allocate buffer for driver, user buffer of real voltage,
// and DMA buffer for cyclic mode DMA transfer
if( AllocateDataBuffer(
lDriverHandle, //Driver handle
usNumberOfOutputs, //Data count
&lDmaBuf, //DMA buffer allocated
&pusBinaryBuf, //Binary data buffer
&pfVoltageBuf)==false) //User voltage buffer allocated
{
printf("Program terminated\n");
DRV_DeviceClose(&lDriverHandle);
printf("Press any key to exit....");
getch();
exit(1);
}
// Step 5: Set values into user buffer by the specified output waveform
SetRealBuffer(pfVoltageBuf, usNumberOfOutputs, usNumberOfOutputs);
// Step 6: Call DRV_FAOScale to scale real values of user buffer
// into binary values for driver
tFAOScale.VoltArray = pfVoltageBuf;
tFAOScale.BinArray = pusBinaryBuf;
tFAOScale.chan = usChan;
tFAOScale.count = usNumberOfOutputs;
dwErrCde = DRV_FAOScale(lDriverHandle, &tFAOScale);
if (dwErrCde != SUCCESS)
{
ErrorStop(&lDriverHandle, dwErrCde, &lDmaBuf,
&pusBinaryBuf, &pfVoltageBuf);
return;
}
// Step 7: Enable event feature
tEnableEvent.EventType = ADS_EVT_AO_INTERRUPT;
tEnableEvent.Enabled = 1;
tEnableEvent.Count = 1;
if ((dwErrCde = DRV_EnableEvent(lDriverHandle,
(LPT_EnableEvent)&tEnableEvent)) != 0)
{
ErrorStop(&lDriverHandle, dwErrCde, &lDmaBuf,
&pusBinaryBuf, &pfVoltageBuf);
return ;
}
tEnableEvent.EventType = ADS_EVT_AO_BUFCHANGE;
if ((dwErrCde = DRV_EnableEvent(lDriverHandle,
(LPT_EnableEvent)&tEnableEvent)) != 0)
{
ErrorStop(&lDriverHandle, dwErrCde, &lDmaBuf,
&pusBinaryBuf, &pfVoltageBuf);
return ;
}
tEnableEvent.EventType = ADS_EVT_AO_TERMINATED;
if ((dwErrCde = DRV_EnableEvent(lDriverHandle,
(LPT_EnableEvent)&tEnableEvent)) != 0)
{
ErrorStop(&lDriverHandle, dwErrCde, &lDmaBuf,
&pusBinaryBuf, &pfVoltageBuf);
return ;
}
tEnableEvent.EventType = ADS_EVT_AO_UNDERRUN;
if ((dwErrCde = DRV_EnableEvent(lDriverHandle,
(LPT_EnableEvent)&tEnableEvent)) != 0)
{
ErrorStop(&lDriverHandle, dwErrCde, &lDmaBuf,
&pusBinaryBuf, &pfVoltageBuf);
return ;
}
// Step 8: Call DRV_FAODmaStart to start output operation
// You can call DRV_FAOCheck to check the operation status
// or you can use event functions.
tFAODmaStart.buffer = (LONG far *)pusBinaryBuf; // analog output data
tFAODmaStart.TrigSrc = 0; // 0: internal, 1: external trigger
tFAODmaStart.SampleRate = 100000; // output rate
tFAODmaStart.chan = usChan; // output channel
tFAODmaStart.count = usNumberOfOutputs; // output number
dwErrCde = DRV_FAODmaStart(lDriverHandle, &tFAODmaStart);
if (dwErrCde != SUCCESS)
{
ErrorStop(&lDriverHandle, dwErrCde, &lDmaBuf,
&pusBinaryBuf, &pfVoltageBuf);
return;
}
// Step 9: Press any key to stop the operation by calling DRV_FAOStop
printf("\nOutput sine waveform on channel %d with frequency %5.3fHz.",
tFAODmaStart.chan, (float)(tFAODmaStart.SampleRate)/tFAODmaStart.count);
printf("\nPress any key to stop the operation....");
hThreadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) UserThread, NULL, 0, (LPDWORD)&dwThreadID);
getch();
bThreadloop = FALSE;
WaitForSingleObject(hThreadHandle, INFINITE);
//Stop DA DMA action
dwErrCde = DRV_FAOStop(lDriverHandle);
if (dwErrCde != SUCCESS) ErrorHandler(dwErrCde);
// Step 10: Free all buffer
FreeDataBuffer(lDriverHandle, &lDmaBuf, &pusBinaryBuf, &pfVoltageBuf);
// Step 11: Close device
dwErrCde = DRV_DeviceClose(&lDriverHandle);
}//main
/**********************************************************************
* Function: SetRealBuffer
* Set output values for sine wave.
* Paramaters: lpBuf, IN/OUT, data buffer pointer
* num, IN, Data count.
* wPeriod, IN, the points of one period
* return: none
**********************************************************************/
void SetRealBuffer(float *lpBuf, long num, USHORT wPeriod)
{
int i;
float fMagnitude = 2.00f; // the magnitude of output waveform
float fOffset = 2.00f; // the offset of output waveform
for (i = 0; i < num; i ++)
*(lpBuf+i) = (float)(fMagnitude * sin(6.28318*(double)i/(double)wPeriod) + fOffset);
}// SetRealBuffer
/**********************************************************************
* Function: ErrorHandler
* Show the error message for the corresponding error code
* input: dwErrCde, IN, Error code
* return: none
**********************************************************************/
void ErrorHandler(DWORD dwErrCde)
{
char szErrMsg[180];
DRV_GetErrorMessage(dwErrCde, szErrMsg);
printf("\nError(%d): %s\n", dwErrCde & 0xffff, szErrMsg);
}//ErrorHandler
/**********************************************************************
* Function: ErrorStop
* Release all resource and terminate program if error occurs
* Paramaters: pDrvHandle, IN/OUT, pointer to Driver handle
* dwErrCde, IN, Error code.
* return: none
**********************************************************************/
void ErrorStop( long* pDrvHandle,
DWORD dwErrCde,
long* plDMABuf,
USHORT** pBinaryBuf,
float** pFloatBuf)
{
//Error message
ErrorHandler(dwErrCde);
printf("Program terminated!\n");
//Free buffer
FreeDataBuffer(*pDrvHandle, plDMABuf, pBinaryBuf, pFloatBuf);
//Close device
DRV_DeviceClose(pDrvHandle);
exit(1);
}//ErrorStop
/**********************************************************************
* Function: AllocateDataBuffer
* Allocate data buffer for DMA transfer.
* Paramaters: lDrvHandle, IN, Driver handle
* iSamples, IN, Data count.
* plDMABuf, OUT, DMA buffer pointer.
* needed for internal DMA transfer.
* pBinaryBur, OUT, binary data buffer./
* pFloatBuf, OUT, float data buffer for user set voltage.
* return: TRUE - memory allocate correctly.
* FALSE - allocate error
**********************************************************************/
BOOL AllocateDataBuffer(
long lDrvHandle,
int iSamples,
long *plDMABuf,
USHORT **pBinaryBuf,
float **pFloatBuf)
{
PT_AllocateDMABuffer ptAllocDMA;
unsigned long lActualSize;
DWORD dwErrCde;
// Allocate DMA buffer for DMA transfer
ptAllocDMA.CyclicMode = 1; // 0: non-cyclic mode, 1: cyclic-mode
ptAllocDMA.RequestBufSize = iSamples*2 ; // request buffer size, double for 12bits
ptAllocDMA.ActualBufSize = &lActualSize; // actual returned buffer size
ptAllocDMA.buffer = (long*)plDMABuf; // returned buffer address
dwErrCde = DRV_AllocateDMABuffer(lDrvHandle, &ptAllocDMA);
if (dwErrCde != SUCCESS)
{
ErrorHandler(dwErrCde);
return(false);
}
//Allocate memory for binary RAW data buffer
hBinaryBuf = GlobalAlloc(GPTR, iSamples * sizeof(USHORT));
if (hBinaryBuf == 0)
{
DRV_FreeDMABuffer(lDrvHandle, (LPARAM)plDMABuf);
printf("\nError: Allocate memory error.\n");
return(false);
}
// Allocate memory for floating voltage user buffer.
hVoltageBuf = GlobalAlloc(GPTR,iSamples * sizeof(FLOAT));
if (hVoltageBuf == 0)
{
GlobalFree(*pBinaryBuf);
DRV_FreeDMABuffer(lDrvHandle, (LPARAM)plDMABuf);
*pBinaryBuf = NULL;
printf("\nError: Allocate memory error.\n");
return(false);
}
*pBinaryBuf = (USHORT far *)GlobalLock(hBinaryBuf);
*pFloatBuf = (FLOAT far *)GlobalLock(hVoltageBuf);
return(true);
}//AllocateDataBuffer
/**********************************************************************
* Function: FreeDataBuffer
* Free data buffer theat allocated by function AllocateDataBuffer
* Paramaters: lDrvHandle, IN, Driver handle.
* plDMABuf, IN/OUT, Address of DMA pointer
* pBinaryBur,IN/OUT, binary data buffer./
* pFloatBuf, IN/OUT, float data buffer for user set voltage.
* return: none
**********************************************************************/
void FreeDataBuffer(long lDrvHandle, long *plDMABuf, USHORT **pBinaryBuf,
float **pFloatBuf)
{
DRV_FreeDMABuffer(lDrvHandle, (LPARAM)plDMABuf);
GlobalUnlock(hVoltageBuf); GlobalFree(hVoltageBuf);
GlobalUnlock(hBinaryBuf); GlobalFree(hBinaryBuf);
*pBinaryBuf = NULL;
*pFloatBuf = NULL;
}//FreeDataBuffer
void UserThread()
{
USHORT usEventType;
LONG ErrCde;
PT_CheckEvent ptCheckEvent;
bThreadloop = TRUE;
int ibuf = 0;
while (bThreadloop) {
ptCheckEvent.EventType = &usEventType;
ptCheckEvent.Milliseconds = 5000;
if (ErrCde = DRV_CheckEvent(lDriverHandle, (LPT_CheckEvent)&ptCheckEvent)!=0) {
printf("Check event error!\n");
return;
}
if (usEventType == ADS_EVT_AO_INTERRUPT)
{
//printf("Interrupt event!\n");
}
// Process buffer change event
if (usEventType == ADS_EVT_AO_BUFCHANGE){
//ibuf++;
//printf("buffer change event %d!\n", ibuf);
//add your code here to handle buffer change event
}
// Process overrun event
if (usEventType == ADS_EVT_AO_UNDERRUN){
}
// Process terminate event
if (usEventType == ADS_EVT_AO_TERMINATED)
{
//add your code here to handle terminate event
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -