mainform.cpp

来自「16 relay output channels and 16 isolated」· C++ 代码 · 共 657 行 · 第 1/2 页

CPP
657
字号
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "MainForm.h"
#include "..\..\..\..\include\driver.h"
#include "CheckForm.h"
#include "math.h"


//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;

#define WAVE_SINE                   0
#define WAVE_TRIANGLE               1
#define WAVE_SQUARE                 2
#define SINE_TRIANGLE               3

typedef struct {
    char Wavename[20];
    int wWaveform;
    float fMagnitude;
    float fOffset;
    int wPeriod;
} SWAVE, FAR *LPSWAVE;

static  SWAVE sWave[3] ={
                       {"SINE",
                        WAVE_SINE,          // output waveform A index
                        2.00f,      // the magnitude of output waveform A
                        2.00f,      // the offset of output waveform A
                        2048},       // the points of one period
                       {"TRIANGLE",
                        WAVE_TRIANGLE,          // output waveform B index
                        1.00f,      // the magnitude of output waveform B
                        3.00f,      // the offset of output waveform B
                        2048},       // the points of one period
                       {"SQUARE",
                        WAVE_SQUARE,          // output waveform C index
                        2.00f,      // the magnitude of output waveform C
                        2.00f,      // the offset of output waveform C
                        2048}       // the points of one period
 };

const MaxEntries = 255;
DEVLIST DeviceList[MaxEntries + 1];
long ErrCde;
char szErrMsg[80];
ULONG lDeviceNum;                     //Advantech Device Number in your system
LONG   lDriverHandle;                  //Driver handle
static char szDescription[80];         //description for Select Device
static      DEVFEATURES     DevFeatures;           // structure for device features
static      PT_DeviceGetFeatures  ptDevGetFeatures;// structure for DeviceGetFeatures
static      PT_FAODmaStart     ptFAODmaStart;     // FAODMAStart table
static      PT_FAOLoad         ptFAOLoad;         // FAOLoad table
static      PT_FAOScale        ptFAOScale;        // FAOScale table
static      PT_FAOCheck        ptFAOCheck;        // FAOCheck table
static      PT_EnableEvent     ptEnableEvent;     // Enable event
static      PT_CheckEvent      ptCheckEvent;      // Check event
static      PT_AllocateDMABuffer  ptAllocateDMABuffer;  // buffer table

USHORT      gwChannel = 0;             // output channel
static  DWORD  gdwPacerRate = 10000;    // pacer rate
//Donghai changed 4096 to 32768
static  ULONG  gulConvNum = 32768;      // conversion number
static  USHORT gwCyclicMode = 1;        // cyclic or non-cylic mode
static  USHORT gwBufferMode = 0;        // buffer: single or double
static  USHORT gwEvtFlag = 1;           // event enable(0)
static  USHORT gwExtTrig = 0;

static  USHORT gwActiveBuf = 0;     // return by FAOCheck
static  USHORT gwOverrun   = 0;     // return by FAOCheck
static  USHORT gwStopped   = 0;     // return by FAOCheck
static  ULONG gulRetrieved = 0;     // return by FAOCheck
static  USHORT gwHalfReady = 0;     // return by FAOCheck

static  ULONG  gwActualBufSize = 0; // actual allocate buffer size

//buffer
HGLOBAL hBuf, hVoltageBuf, hBinaryBuf;
FLOAT  far * lpVoltageBuf;
USHORT far * lpBinaryBuf;
USHORT far * lpBuf;
LONG pBuffer;


ULONG gulIntCounter     = 0;  // counter by InterruptEvent
ULONG gulBfChgCounter   = 0;  // counter by BuffChangeEvent
ULONG gulOverrunCounter = 0;  // counter by OverrunEvent

bool bThreadloop = true;
static  USHORT gwRepeatCount = 0;  // number of dma terminal count

//---------------------------------------------------------------------------
void SetRealBuffer(float far *lpBuf, long num, LPSWAVE lpWave)
{
    int i, r, half;
    float slope;

    switch (lpWave->wWaveform)
    {
        case WAVE_SINE:
             for (i = 0; i < num; i ++)
	     {
               *(lpBuf+i) = (float)(lpWave->fMagnitude
                            * sin(6.28318*(double)i/(double)lpWave->wPeriod)
                            + lpWave->fOffset);
	    }
             break;
        case WAVE_TRIANGLE:
             slope = lpWave->fMagnitude * 4.0f / (float)lpWave->wPeriod;
             for (i = 0; i < num; i ++)
            {
                    r = i % lpWave->wPeriod;
                    half = (int)((float)lpWave->wPeriod / 2.0f);
                    if (r <= half)
                       *(lpBuf + i) = slope * r - lpWave->fMagnitude
                                      + lpWave->fOffset;
                    else
                       *(lpBuf + i) = slope * (lpWave->wPeriod - r)
                                      - lpWave->fMagnitude + lpWave->fOffset;
              }
             break;
        case WAVE_SQUARE:
             for (i = 0; i < num; i ++)
             {
                    r = i % lpWave->wPeriod;
                    half = (int)((float)lpWave->wPeriod / 2.0f);
                    if (r <= half)
                       *(lpBuf + i) = lpWave->fOffset - lpWave->fMagnitude;
                    else
                       *(lpBuf + i) = lpWave->fOffset + lpWave->fMagnitude;
             }
             break;
        case SINE_TRIANGLE:
	     ULONG x;
	     double y;

             slope = lpWave->fMagnitude * 4.0f / (float)lpWave->wPeriod;
             for (i = 0; i < num; i ++)
	     {
	      	if(i%2)
	     	{
	           modf(((double)i/2.0),(double *)&y);
		   y = y + 1;
                    r = ((USHORT)y) % lpWave->wPeriod;
                    half = (int)((float)lpWave->wPeriod / 2.0f);
                    if (r <= half)
                       *(lpBuf + i) = slope * r - lpWave->fMagnitude
                                      + lpWave->fOffset;
                    else
                       *(lpBuf + i) = slope * (lpWave->wPeriod - r)
                                      - lpWave->fMagnitude + lpWave->fOffset;
		 }
		 else
		 {
		    x = i/2;
		    *(lpBuf+i) = (float)(lpWave->fMagnitude
                          * sin(6.28318*(double)x/(double)lpWave->wPeriod)
                            + lpWave->fOffset);
		  }
	     }
             break;
    }

}

//---------------------------------------------------------------------------
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::SelectClick(TObject *Sender)
{
    USHORT usMaxChannel;
    AnsiString temp;
    char   szExpName[15];                      // expansion name
    int i;
    DRV_SelectDevice(Handle, True, (ULONG*)&lDeviceNum, szDescription);
    labDevice->Caption = AnsiString(szDescription);
    ErrCde = DRV_DeviceOpen(lDeviceNum,
                (LONG far *)&lDriverHandle);

    if (ErrCde != SUCCESS)
    {
        strcpy(szErrMsg,"Device open error !");
        Application->MessageBox((LPCSTR)szErrMsg,"Device Open",MB_OK);
        DRV_DeviceClose((LONG far *)&lDriverHandle);
        return ;
    }
    //
    // get number of counter channels
    //

    ptDevGetFeatures.buffer = (LPDEVFEATURES)&DevFeatures;
    ptDevGetFeatures.size = sizeof(DEVFEATURES);
    if ((ErrCde = DRV_DeviceGetFeatures(lDriverHandle,
        (LPT_DeviceGetFeatures)&ptDevGetFeatures)) != SUCCESS)
    {
        DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
        Application->MessageBox((LPCSTR)szErrMsg,"Driver Message",MB_OK);
        DRV_DeviceClose((LONG far *)&lDriverHandle);
        return ;
    }

     cmbChannel->Clear();


     // setting dialog box for channel setting
     // fill in the channel listbox with the available channel
     // in the AO subsection (start with channel 0)
     for (int i=0; i< (int)DevFeatures.usMaxAOChl; ++i)
            cmbChannel->Items->Add(IntToStr(i));
     cmbChannel->ItemIndex =0;
     //  close device
     DRV_DeviceClose((LONG far *)&lDriverHandle);
}
 //---------------------------------------------------------------------------
void __fastcall TfrmMain::FormCreate(TObject *Sender)
{
        for( int i=0; i<3; i++)
            cmbWaveForm->Items->Add(sWave[i].Wavename);
        cmbWaveForm->ItemIndex = 0;    
        SelectClick(NULL);

}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::ExitClick(TObject *Sender)
{
    Close();        
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::cmbWaveFormChange(TObject *Sender)
{
      edtMagnitude->Text.sprintf("%f", sWave[cmbWaveForm->ItemIndex].fMagnitude);
      


}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::StartClick(TObject *Sender)
{

     gwChannel = cmbChannel->ItemIndex;
     bThreadloop = true;
     gwEvtFlag = radEnable->Checked;
     gwCyclicMode = radCyclic->Checked;
     gwExtTrig = radExternal->Checked;
     gulConvNum = StrToInt( edtConv->Text);
     gdwPacerRate = StrToInt( edtRate->Text);
     if( (ErrCde = DRV_DeviceOpen(lDeviceNum,(LONG far *)&lDriverHandle ))
                 != SUCCESS)
     {
        DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
        Application->MessageBox(szErrMsg,"Driver Message",MB_OK);
     }

    // Step 2: Allocate memory used by driver
    if((hBuf=(USHORT far *)GlobalAlloc(GPTR,
        sizeof(USHORT) * gulConvNum)) == 0)
    {
        Application->MessageBox("Not enough memory for buffer ",
            "High Speed",MB_OK);
        DRV_DeviceClose((LONG far *)&lDriverHandle);
        return ;
    }

    // Step 3: Allocate memory for real voltage
    if((hVoltageBuf=(FLOAT far *)GlobalAlloc(GPTR,
        sizeof(FLOAT) * gulConvNum)) == 0)
    {
        Application->MessageBox("Not enough memory for buffer ",
            "High Speed",MB_OK);
        GlobalFree(hBuf);
        DRV_DeviceClose((LONG far *)&lDriverHandle);
        return ;
    }

    // Step 4: Allocate memory for binary data
    if((hBinaryBuf=(USHORT far *)GlobalAlloc(GPTR,
        sizeof(USHORT) * gulConvNum)) == 0)
    {
        Application->MessageBox("Not enough memory for buffer ",
            "High Speed",MB_OK);
        GlobalFree(hBuf);
        GlobalFree(hVoltageBuf);
        DRV_DeviceClose((LONG far *)&lDriverHandle);
        return ;
    }

    // Step 5: Allocate DMA buffer for DMA transfer
    ptAllocateDMABuffer.CyclicMode = gwCyclicMode;
    ptAllocateDMABuffer.RequestBufSize = gulConvNum * 2;
    ptAllocateDMABuffer.ActualBufSize = &gwActualBufSize;
    ptAllocateDMABuffer.buffer = &pBuffer;
    if ((ErrCde = DRV_AllocateDMABuffer(lDriverHandle,
        (LPT_AllocateDMABuffer)&ptAllocateDMABuffer)) != SUCCESS)
    {
        DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
        Application->MessageBox(szErrMsg,"Driver Message",MB_OK);
        GlobalUnlock(hBuf); GlobalFree(hBuf);
        GlobalUnlock(hVoltageBuf); GlobalFree(hVoltageBuf);
        GlobalUnlock(hBinaryBuf); GlobalFree(hBinaryBuf);
        DRV_DeviceClose((LONG far *)&lDriverHandle);
        return ;
    }

    // Lock down buffer
    lpBuf        = (USHORT far *)GlobalLock(hBuf);
    lpBinaryBuf  = (USHORT far *)GlobalLock(hBinaryBuf);
    lpVoltageBuf = (FLOAT far  *)GlobalLock(hVoltageBuf);

    // set real voltage to hVoltageBuf
    sWave[cmbWaveForm->ItemIndex].fMagnitude=edtMagnitude->Text.ToDouble();
    sWave[cmbWaveForm->ItemIndex].fOffset=edtOffset->Text.ToDouble();
    sWave[cmbWaveForm->ItemIndex].wPeriod=edtPeriod->Text.ToInt();
    SetRealBuffer(lpVoltageBuf, gulConvNum, &(sWave[cmbWaveForm->ItemIndex]));

    // Step 6: call FAOScale for transfer voltage to binary data
    ptFAOScale.VoltArray = lpVoltageBuf;
    ptFAOScale.BinArray  = lpBuf;
    ptFAOScale.chan      = gwChannel;
    ptFAOScale.count     = gulConvNum;
    if ((ErrCde = DRV_FAOScale(lDriverHandle,
        (LPT_FAOScale)&ptFAOScale)) != 0)

⌨️ 快捷键说明

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