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

📄 dadmabm.cpp

📁 16 relay output channels and 16 isolated digital input channels LED indicators to show activated
💻 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 + -