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 + -
显示快捷键?