我有一张AlazarTech的采集卡,官方提供了控制台采集程序。我想把控制台程序移植到MFC界面,实现当Trig端口有触发时,从CHA CHB两个端口获得电压值,并在MFC窗口中显示两个端口获得信号的波形。控制台程序如下:
#include <stdio.h>
#include <conio.h>
#include "AlazarError.h"
#include "AlazarApi.h"
#include "AlazarCmd.h"
#define BUFFER_COUNT 4
U16 *BufferArray[BUFFER_COUNT] = { NULL };
double SamplesPerSec = 0.;
BOOL ConfigureBoard(HANDLE boardHandle);
BOOL AcquireData(HANDLE boardHandle);
int main(int argc, char* argv[])
{
// TODO: Select a board
U32 systemId = 1;
U32 boardId = 1;
// Get a handle to the board
HANDLE boardHandle = AlazarGetBoardBySystemID(systemId, boardId);
if (boardHandle == NULL)
{
printf("Error: Unable to open board system Id %u board Id %u\n", systemId, boardId);
return 1;
}
// Configure the board's sample rate, input, and trigger settings
if (!ConfigureBoard(boardHandle))
{
printf("Error: Configure board failed\n");
return 1;
}
// Make an acquisition, optionally saving sample data to a file if (!AcquireData(boardHandle))
{
printf("Error: Acquisition failed\n");
return 1;
}
return 0;
}
//----------------------------------------------------------------------------
// Function    :  ConfigureBoard
// Description :  Configure sample rate, input, and trigger settings
//----------------------------------------------------------------------------
BOOL ConfigureBoard(HANDLE boardHandle)
{
RETURN_CODE retCode;
// TODO: Specify the sample rate (see sample rate id below)
SamplesPerSec = 20.e6;
// TODO: Select clock parameters as required to generate this sample rate.
// For example: if samplesPerSec is 100.e6 (100 MS/s), then:
// - select clock source INTERNAL_CLOCK and sample rate SAMPLE_RATE_100MSPS
// - select clock source FAST_EXTERNAL_CLOCK, sample rate SAMPLE_RATE_USER_DEF,
//   and connect a 100 MHz signalto the EXT CLK BNC connector.
retCode = AlazarSetCaptureClock(
boardHandle, // HANDLE -- board handle
INTERNAL_CLOCK, // U32 -- clock source id
SAMPLE_RATE_20MSPS, // U32 -- sample rate id
CLOCK_EDGE_RISING, // U32 -- clock edge id
0 // U32 -- clock decimatio
);
if (retCode != ApiSuccess)
{
printf("Error: AlazarSetCaptureClock failed -- %s\n", AlazarErrorToText(retCode));
return FALSE;
}
// TODO: Select CHA input parameters as required
retCode = AlazarInputControl(
boardHandle, // HANDLE -- board handle
CHANNEL_A, // U8 -- input channel 
DC_COUPLING, // U32 -- input coupling id
INPUT_RANGE_PM_800_MV, // U32 -- input range id
IMPEDANCE_50_OHM // U32 -- input impedance id
);
if (retCode != ApiSuccess)
{
printf("Error: AlazarInputControl failed -- %s\n", AlazarErrorToText(retCode));
return FALSE;
}
// TODO: Select CHA bandwidth limit as required
retCode = AlazarSetBWLimit(
boardHandle, // HANDLE -- board handle
CHANNEL_A, // U8 -- channel identifier
0 // U32 -- 0 = disable, 1 = enable
);
if (retCode != ApiSuccess)
{
printf("Error: AlazarSetBWLimit failed -- %s\n", AlazarErrorToText(retCode));
return FALSE;
}
// TODO: Select CHB input parameters as required
retCode = 
AlazarInputControl(
boardHandle, // HANDLE -- board handle
CHANNEL_B, // U8 -- channel identifier
DC_COUPLING, // U32 -- input coupling id
INPUT_RANGE_PM_800_MV, // U32 -- input range id
IMPEDANCE_50_OHM  // U32 -- input impedance id
);
if (retCode != ApiSuccess)
{
printf("Error: AlazarInputControl failed -- %s\n", AlazarErrorToText(retCode));
return FALSE;
}
// TODO: Select CHB bandwidth limit as required

retCode = AlazarSetBWLimit(
boardHandle, // HANDLE -- board handle
CHANNEL_B, // U8 -- channel identifier
0 // U32 -- 0 = disable, 1 = enable
);
if (retCode != ApiSuccess)
{
printf("Error: AlazarSetBWLimit failed -- %s\n", AlazarErrorToText(retCode));
return FALSE;
}
// TODO: Select trigger inputs and levels as required
retCode = AlazarSetTriggerOperation(
boardHandle, // HANDLE -- board handle
TRIG_ENGINE_OP_J,// U32 -- trigger operation 
TRIG_ENGINE_J, // U32 -- trigger engine id
TRIG_CHAN_A, // U32 -- trigger source id
TRIGGER_SLOPE_POSITIVE, // U32 -- trigger slope id
128, // U32 -- trigger level from 0 (-range) to 255 (+range)
TRIG_ENGINE_K, // U32 -- trigger engine id
TRIG_DISABLE, // U32 -- trigger source id for engine K
TRIGGER_SLOPE_POSITIVE, // U32 -- trigger slope id
128 // U32 -- trigger level from 0 (-range) to 255 (+range)
);
if (retCode != ApiSuccess)
{
printf("Error: AlazarSetTriggerOperation failed -- %s\n", AlazarErrorToText(retCode));
return FALSE;
}
// TODO: Select external trigger parameters as required
retCode =AlazarSetExternalTrigger( 
boardHandle, // HANDLE -- board handle
DC_COUPLING, // U32 -- external trigger coupling id
ETR_5V // U32 -- external trigger range id
);
// TODO: Set trigger delay as required. 
double triggerDelay_sec = 0.;
U32 triggerDelay_samples = (U32) (triggerDelay_sec * SamplesPerSec + 0.5);
retCode = AlazarSetTriggerDelay(boardHandle, triggerDelay_samples);
if (retCode != ApiSuccess)
{
printf("Error: AlazarSetTriggerDelay failed -- %s\n", AlazarErrorToText(retCode));
return FALSE;
}
// TODO: Set trigger timeout as required. 
// NOTE:
// The board will wait for a for this amount of time for a trigger event. 
// If a trigger event does not arrive, then the board will automatically 
// trigger. Set the trigger timeout value to 0 to force the board to wait 
// forever for a trigger event.
//
// IMPORTANT: 
// The trigger timeout value should be set to zero after appropriate 
// trigger parameters have been determined, otherwise the 
// board may trigger if the timeout interval expires before a 
// hardware trigger event arrives.
double triggerTimeout_sec = 0.;
U32 triggerTimeout_clocks = (U32) (triggerTimeout_sec / 10.e-6 + 0.5);
retCode = AlazarSetTriggerTimeOut(
boardHandle, // HANDLE -- board handle
triggerTimeout_clocks,// U32 -- timeout_sec / 10.e-6 (0 means wait forever)
);
if (retCode != ApiSuccess)
{
printf("Error: AlazarSetTriggerTimeOut failed -- %s\n", AlazarErrorToText(retCode));
return FALSE;
}
// TODO: Configure AUX I/O connector as required
retCode = AlazarConfigureAuxIO(
boardHandle, // HANDLE -- board handle
AUX_OUT_TRIGGER,// U32 -- mode
0 // U32 -- parameter
);
if (retCode != ApiSuccess)
{
printf("Error: AlazarConfigureAuxIO failed -- %s\n", AlazarErrorToText(retCode));
return FALSE;
}
return TRUE;
}
MFC采集

解决方案 »

  1.   

    BOOL AcquireData(HANDLE boardHandle)
    {
    // TODO: Select the total acquisition length in seconds double acquisitionLength_sec = 10.; // TODO: Select the number of samples in each DMA buffer U32 samplesPerBuffer = 1024 * 1024; // TODO: Select which channels to capture (A, B, or both) U32 channelMask = CHANNEL_A | CHANNEL_B;  // TODO: Select if you wish to save the sample data to a file BOOL saveData = FALSE; // Calculate the number of enabled channels from the channel mask  int channelCount = 0; switch (channelMask)
    {
    case CHANNEL_A:
    case CHANNEL_B:
    channelCount = 1;
    break;
    case CHANNEL_A | CHANNEL_B:
    channelCount = 2;
    break;
    default:
    printf("Error: Invalid channel mask %08X\n", channelMask);
    return FALSE;
    } // Get the sample size in bits, and the on-board memory size in samples per channel U8 bitsPerSample;
    U32 maxSamplesPerChannel;
    RETURN_CODE retCode = AlazarGetChannelInfo(boardHandle, &maxSamplesPerChannel, &bitsPerSample);
    if (retCode != ApiSuccess)
    {
    printf("Error: AlazarGetChannelInfo failed -- %s\n", AlazarErrorToText(retCode));
    return FALSE;
    } // Calculate the size of each DMA buffer in bytes U32 bytesPerSample = (bitsPerSample + 7) / 8;
    U32 bytesPerBuffer = bytesPerSample * samplesPerBuffer * channelCount; // Calculate the number of buffers in the acquisition INT64 samplesPerAcquisition = (INT64) (SamplesPerSec * acquisitionLength_sec + 0.5);
    U32 buffersPerAcquisition = (U32) ((samplesPerAcquisition + samplesPerBuffer - 1) / samplesPerBuffer); // Create a data file if required FILE *fpData = NULL; if (saveData)
    {
    fpData = fopen("data.bin", "wb");
    if (fpData == NULL)
    {
    printf("Error: Unable to create data file -- %u\n", GetLastError());
    return FALSE;
    }
    }

    // Allocate memory for DMA buffers BOOL success = TRUE; U32 bufferIndex;
    for (bufferIndex = 0; (bufferIndex < BUFFER_COUNT) && (success == TRUE); bufferIndex++)
    {
    #ifdef _WIN32 // Allocate page aligned memory
    BufferArray[bufferIndex] = (U16*) VirtualAlloc(NULL, bytesPerBuffer, MEM_COMMIT, PAGE_READWRITE);
    #else
    BufferArray[bufferIndex] = (U16*) malloc(bytesPerBuffer);
    #endif
    if (BufferArray[bufferIndex] == NULL)
    {
    printf("Error: Alloc %u bytes failed\n", bytesPerBuffer);
    success = FALSE;
    }
    }

    // Configure the board to make an AutoDMA acquisition if (success)
    {
    U32 admaFlags = ADMA_EXTERNAL_STARTCAPTURE | // Start acquisition when AlazarStartCapture is called
    ADMA_TRIGGERED_STREAMING; // Acquire a continuous stream of sample data with trigger retCode = 
    AlazarBeforeAsyncRead(
    boardHandle, // HANDLE -- board handle
    channelMask, // U32 -- enabled channel mask
    0, // long -- offset from trigger in samples
    samplesPerBuffer, // U32 -- samples per buffer
    1, // U32 -- records per buffer (must be 1)
    buffersPerAcquisition, // U32 -- records per acquisition 
    admaFlags // U32 -- AutoDMA flags
    ); 
    if (retCode != ApiSuccess)
    {
    printf("Error: AlazarBeforeAsyncRead failed -- %s\n", AlazarErrorToText(retCode));
    success = FALSE;
    }
    } // Add the buffers to a list of buffers available to be filled by the board for (bufferIndex = 0; (bufferIndex < BUFFER_COUNT) && (success == TRUE); bufferIndex++)
    {
    U16* pBuffer = BufferArray[bufferIndex];
    retCode = AlazarPostAsyncBuffer(boardHandle, pBuffer, bytesPerBuffer);
    if (retCode != ApiSuccess)
    {
    printf("Error: AlazarPostAsyncBuffer %d failed -- %s\n", bufferIndex, AlazarErrorToText(retCode));
    success = FALSE;
    }
    } // Arm the board to begin the acquisition  if (success)
    {
    retCode = AlazarStartCapture(boardHandle);
    if (retCode != ApiSuccess)
    {
    printf("Error: AlazarStartCapture failed -- %s\n", AlazarErrorToText(retCode));
    success = FALSE;
    }
    }

    // Wait for each buffer to be filled, process the buffer, and re-post it to the board. if (success)
    {
    printf("Capturing %d buffers ... press any key to abort\n", buffersPerAcquisition); DWORD startTickCount = GetTickCount();
    U32 buffersCompleted = 0;
    INT64 bytesTransferred = 0;

    while (buffersCompleted < buffersPerAcquisition)
    {
    // TODO: Set a buffer timeout that is longer than the time 
    //       required to capture all the records in one buffer. DWORD timeout_ms = 5000; // Wait for the buffer at the head of the list of available buffers
    // to be filled by the board. bufferIndex = buffersCompleted % BUFFER_COUNT;
    U16* pBuffer = BufferArray[bufferIndex];
    retCode = AlazarWaitAsyncBufferComplete(boardHandle, pBuffer, timeout_ms);
    if (retCode != ApiSuccess)
    {
    printf("Error: AlazarWaitAsyncBufferComplete failed -- %s\n", AlazarErrorToText(retCode));
    success = FALSE;
    } if (success)
    {
    // This buffer is full and has been removed from the list
    // of buffers available to the board. buffersCompleted++;
    bytesTransferred += bytesPerBuffer; // TODO: Process sample data in this buffer. 
    //
    // While you are processing this buffer, the board is 
    // filling the next available buffer(s). You must finish 
    // processing this buffer and make it available to the 
    // board before the board fills all available buffer(s). 
    // 
    // Records in the buffer are arranged as follows: R0A, R0B,
    // where Rxy is a segment of a single record.
    //
    // Sample values for each enabled channel are arranged 
    // contiguously in the buffer, where a 14-bit sample code occupies 
    // the most significant bits of each 16-bit sample value.
    //
    // Sample codes are unsigned by default so that:
    // - a sample code of 0x0000 represents a negative full scale input signal;
    // - a sample code of 0x2000 represents a 0V signal;
    // - a sample code of 0x3FFF represents a positive full scale input signal. if (saveData)
    {
    // Write buffer to file
    size_t bytesWritten = fwrite(pBuffer, sizeof(BYTE), bytesPerBuffer, fpData);
    if (bytesWritten != bytesPerBuffer)
    {
    printf("Error: Write buffer %d failed -- %u\n", buffersCompleted, GetLastError());
    success = FALSE;
    }
    }
    }

    // Add the buffer to the end of the list of available buffers so that 
    // the board can fill it with data from another segment of the acquisition. if (success)
    {
    retCode = AlazarPostAsyncBuffer(boardHandle, pBuffer, bytesPerBuffer);
    if (retCode != ApiSuccess)
    {
    printf("Error: AlazarPostAsyncBuffer failed -- %s\n", AlazarErrorToText(retCode));
    success = FALSE;
    }
    } // If the acquisition failed, exit the acquisition loop if (!success)
    break; // If a key was pressed, exit the acquisition loop

    if (_kbhit())
    {
    printf("Aborted...\n");
    break;
    } // Display progress printf("Completed %u buffers\r", buffersCompleted);
    } // Display results double transferTime_sec = (GetTickCount() - startTickCount) / 1000.;
    printf("Capture completed in %.2lf sec\n", transferTime_sec); double buffersPerSec;
    double bytesPerSec;
    if (transferTime_sec > 0.)
    {
    buffersPerSec = buffersCompleted / transferTime_sec;
    bytesPerSec = bytesTransferred / transferTime_sec;
    }
    else
    {
    buffersPerSec = 0.;
    bytesPerSec = 0.;
    } printf("Captured %d buffers (%.4g buffers per sec)\n", buffersCompleted, buffersPerSec);
    printf("Transferred %I64d bytes (%.4g bytes per sec)\n", bytesTransferred, bytesPerSec);
    } // Abort the acquisition retCode = AlazarAbortAsyncRead(boardHandle);
    if (retCode != ApiSuccess)
    {
    printf("Error: AlazarAbortAsyncRead failed -- %s\n", AlazarErrorToText(retCode));
    success = FALSE;
    } // Free all memory allocated for (bufferIndex = 0; bufferIndex < BUFFER_COUNT; bufferIndex++)
    {
    if (BufferArray[bufferIndex] != NULL)
    {
    #ifdef _WIN32
    VirtualFree(BufferArray[bufferIndex], 0, MEM_RELEASE);
    #else
    free(BufferArray[bufferIndex]);
    #endif
    }
    } // Close the data file if (fpData != NULL)
    fclose(fpData);

    return success;
    }
      

  2.   

    http://download.csdn.net/detail/haohaoxuexiVV/2770705
      

  3.   

    在对话框里面放个static控件就可以了,然后setdlgitemtext
      

  4.   

    谢谢你,这个我知道。我想知道的是BOOL ConfigureBoard(HANDLE boardHandle);
    BOOL AcquireData(HANDLE boardHandle);这两个函数放在哪个位置?如何调用他们?还有就是如何实现对API函数在我提供的触发条件下获得我想要的值。能说的再稍微详细一点吗?
      

  5.   

    1.
    建立一个对话框程序,这个简单,用响导生成就可以了
    2.
    在对话框里重载定时消息:WM_TIMER(好象是这么写的消息)
    3.
    在对话框里的初始化函数(OnInitDialog类似这么写的),里加上初始化定时:
    m_TimeHandle=SetTimer(1,1000,NULL);//第一个参数是定时器句柄,用来识别多个定时器,这里定为1,第二个参数是定时时间,单位毫秒,这里设为1秒执行定时消息函数,第三个设为NULL就行了
    4.
    m_TimeHandle在对话框里的头文件里定义:UINT_PTR m_TimeHaneld;//好象是这么写的类型,如果不对,就UINT也可以.
    5.
    ConfigureBoard放在对话框里初始化函数里执行一次就可以了.AcquireData放在定时器函数里调用,就是1秒执行一次采集.
    6.定时器中断函数:
    if(nID==m_TimeHandle)//nID是定时器函数的参数,用来区别是哪个定时器
    {
    AcquireData(boardHandle);
    }
      

  6.   

    谢谢你。不过什么时候采集信号并不是用设置定时器来决定的。我是想通过外部触发信号来决定什么时候采集信号。我主要是不知道那几个API函数如何用,包括AlazarStartCapture和 retCode=AlazarSetExternalTrigger( 
                boardHandle,    // HANDLE -- board handle
                DC_COUPLING,    // U32 -- external trigger coupling id
                ETR_5V        // U32 -- external trigger range id
                );等等。这种枚举类型的如何定义和赋值?
    谢谢。