490 lines
13 KiB
C++
490 lines
13 KiB
C++
#include "StdAfx.h"
|
|
#include <WinDef.h>
|
|
#include <WinBase.h>
|
|
#include "ART_PCI8622.h"
|
|
|
|
|
|
|
|
CART_PCI8622::CART_PCI8622()
|
|
{
|
|
m_hDevice=INVALID_HANDLE_VALUE;
|
|
m_hDmaEvent=NULL;
|
|
m_AD_LSB_MAX=0.0;
|
|
m_AD_LSB_HALF=0.0;
|
|
m_AD_LSB_RANGE=65536;
|
|
m_InputRange=0;
|
|
m_StopedSample=TRUE;
|
|
m_EnStartSample=FALSE;
|
|
m_EnGetData=FALSE;
|
|
m_iSampleMode=0;
|
|
m_iReadDataSize=100;
|
|
m_iFirstChannel=1;
|
|
m_iLastChannel=2;
|
|
}
|
|
|
|
CART_PCI8622::~CART_PCI8622()
|
|
{
|
|
|
|
}
|
|
//========================================
|
|
BOOL CART_PCI8622::Init()
|
|
{
|
|
BOOL rStatus(TRUE);
|
|
#ifdef _RELEASE_FULL_VERSION
|
|
if(m_hDevice == INVALID_HANDLE_VALUE)
|
|
{
|
|
int DeviceLgcID(0);
|
|
m_hDevice = PCI8622_CreateDevice(DeviceLgcID); // 创建设备对象
|
|
}
|
|
if(m_hDevice == INVALID_HANDLE_VALUE)
|
|
{
|
|
rStatus=FALSE;
|
|
}
|
|
#endif //_RELEASE_FULL_VERSION
|
|
return rStatus;
|
|
}
|
|
//========================================
|
|
BOOL CART_PCI8622::Exit()
|
|
{
|
|
BOOL rStatus(TRUE);
|
|
#ifdef _RELEASE_FULL_VERSION
|
|
if (!m_StopedSample)
|
|
{
|
|
rStatus=StopSampleData();
|
|
}
|
|
rStatus=PCI8622_ReleaseDevice(m_hDevice); // 释放设备对象
|
|
m_hDevice=INVALID_HANDLE_VALUE;
|
|
#endif //_RELEASE_FULL_VERSION
|
|
return rStatus;
|
|
}
|
|
//========================================
|
|
BOOL CART_PCI8622::SetSampleChannel(int _FirstChannel,int _LastChannel)
|
|
{
|
|
BOOL rStatus(TRUE);
|
|
|
|
if (_LastChannel<_FirstChannel)
|
|
{
|
|
rStatus=FALSE;
|
|
}
|
|
else
|
|
{
|
|
m_iFirstChannel=_FirstChannel;
|
|
m_iLastChannel=_LastChannel;
|
|
}
|
|
return rStatus;
|
|
}
|
|
|
|
//========================================
|
|
BOOL CART_PCI8622::SetSamplePara(int _Mode,int _ReadDataSize)
|
|
{
|
|
BOOL rStatus(TRUE);
|
|
m_iSampleMode=_Mode;
|
|
m_iReadDataSize=_ReadDataSize;
|
|
#ifdef _RELEASE_FULL_VERSION
|
|
memset(&ADBuffer, 0x00, sizeof(ADBuffer));
|
|
memset(&m_ADPara, 0x00, sizeof(m_ADPara)); // 将各项参数复位至确定值0(强烈建议)
|
|
switch(_Mode)
|
|
{
|
|
case E_ART_PCI8622_SAMPLE_DMA_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_NPT_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_HALF_SEQ:
|
|
{
|
|
// 预置硬件参数
|
|
m_ADPara.ADMode = PCI8622_ADMODE_SEQUENCE; // AD模式为连续模式
|
|
m_ADPara.FirstChannel = m_iFirstChannel; // 首通道
|
|
m_ADPara.LastChannel = m_iLastChannel; // 末通道
|
|
m_ADPara.Frequency = 25000; // 采样频率(Hz)
|
|
m_ADPara.GroupInterval = 50; // 组间间隔(uS)
|
|
m_ADPara.LoopsOfGroup = 1; // 组内各通道点数
|
|
m_ADPara.Gains = PCI8622_GAINS_1MULT;
|
|
m_ADPara.InputRange = m_InputRange; // 模拟量输入量程范围
|
|
|
|
m_ADPara.TriggerMode = PCI8622_TRIGMODE_SOFT; // 触发模式为软件触发
|
|
m_ADPara.TriggerType = PCI8622_TRIGTYPE_EDGE; // 触发类型为边沿触发
|
|
m_ADPara.TriggerDir = PCI8622_TRIGDIR_NEGATIVE; // 触发方向为负向
|
|
m_ADPara.TrigWindow = 40; // 触发灵敏度
|
|
|
|
m_ADPara.ClockSource = PCI8622_CLOCKSRC_IN; // 时钟源选用板内时钟源
|
|
m_ADPara.bClockOutput = FALSE; // 禁止时钟输出
|
|
m_ADPara.GroundingMode = PCI8622_GNDMODE_SE; // 单端方式(SE:Single end)
|
|
m_ADPara.TimeoutForNpt = 10; // 在非空方式下,设置超时时间为10秒钟(只在非空查询方式下有效)
|
|
break;
|
|
}
|
|
case E_ART_PCI8622_SAMPLE_NPT_TRIGCLK:
|
|
case E_ART_PCI8622_SAMPLE_DMA_TRIGCLK:
|
|
case E_ART_PCI8622_SAMPLE_HALF_TRIGCLK:
|
|
{
|
|
// 预置硬件参数
|
|
m_ADPara.ADMode = PCI8622_ADMODE_GROUP; // AD模式为连续模式
|
|
m_ADPara.FirstChannel = m_iFirstChannel; // 首通道
|
|
m_ADPara.LastChannel = m_iLastChannel; // 末通道
|
|
m_ADPara.Frequency = 250000; // 采样频率(Hz)
|
|
m_ADPara.GroupInterval = 50; // 组间间隔(uS)
|
|
m_ADPara.LoopsOfGroup = 10; // 组内各通道点数
|
|
m_ADPara.Gains = PCI8622_GAINS_1MULT;
|
|
m_ADPara.InputRange = m_InputRange; // 模拟量输入量程范围
|
|
|
|
m_ADPara.TriggerMode = PCI8622_TRIGMODE_SOFT; // 触发模式为软件触发
|
|
m_ADPara.TriggerType = PCI8622_TRIGTYPE_EDGE; // 触发类型为边沿触发
|
|
m_ADPara.TriggerDir = PCI8622_TRIGDIR_NEGATIVE; // 触发方向为负向
|
|
m_ADPara.TrigWindow = 40; // 触发灵敏度
|
|
|
|
m_ADPara.ClockSource = PCI8622_CLOCKSRC_OUT; // 时钟源选用板内时钟源
|
|
m_ADPara.bClockOutput = FALSE; // 禁止时钟输出
|
|
m_ADPara.GroundingMode = PCI8622_GNDMODE_SE; // 单端方式(SE:Single end)
|
|
m_ADPara.TimeoutForNpt = 10; // 在非空方式下,设置超时时间为10秒钟(只在非空查询方式下有效)
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
switch(m_InputRange)
|
|
{
|
|
case PCI8622_INPUT_N10000_P10000mV: // -10V - +10V
|
|
{
|
|
m_AD_LSB_MAX=20000.0;
|
|
m_AD_LSB_HALF=10000.0;
|
|
m_AD_LSB_RANGE=65536.0;
|
|
break;
|
|
}
|
|
case PCI8622_INPUT_N5000_P5000mV: // -5V - +5V
|
|
{
|
|
m_AD_LSB_MAX=10000.0;
|
|
m_AD_LSB_HALF=5000.0;
|
|
m_AD_LSB_RANGE=65536.0;
|
|
break;
|
|
}
|
|
case PCI8622_INPUT_N2500_P2500mV: // -2.5V - +2.5V.
|
|
{
|
|
m_AD_LSB_MAX=5000.0;
|
|
m_AD_LSB_HALF=2500.0;
|
|
m_AD_LSB_RANGE=65536.0;
|
|
break;
|
|
}
|
|
break;
|
|
case PCI8622_INPUT_0_P10000mV: // 0V - +10V
|
|
{
|
|
m_AD_LSB_MAX=10000.0;
|
|
m_AD_LSB_HALF=0.0;
|
|
m_AD_LSB_RANGE=65536.0;
|
|
break;
|
|
}
|
|
case PCI8622_INPUT_0_P5000mV: // 0V - +5V
|
|
{
|
|
m_AD_LSB_MAX=5000.0;
|
|
m_AD_LSB_HALF=0.0;
|
|
m_AD_LSB_RANGE=65536.0;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
m_AD_LSB_MAX=0.0;
|
|
m_AD_LSB_HALF=0.0;
|
|
m_AD_LSB_RANGE=65536.0;
|
|
break;
|
|
}
|
|
}
|
|
switch(_Mode)
|
|
{
|
|
case E_ART_PCI8622_SAMPLE_DMA:
|
|
case E_ART_PCI8622_SAMPLE_DMA_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_DMA_TRIGCLK:
|
|
{
|
|
m_hDmaEvent = PCI8622_CreateSystemEvent();
|
|
//if (!PCI8622_InitDeviceDmaAD(m_hDevice, m_hDmaEvent, &ADBuffer[0][0], 4096, SEGMENT_COUNT, HALF_SIZE_WORDS, &m_ADPara)) // 初始化硬件
|
|
if (!PCI8622_InitDeviceDmaAD(m_hDevice, m_hDmaEvent, &ADBuffer[0][0], m_iReadDataSize, SEGMENT_COUNT, HALF_SIZE_WORDS, &m_ADPara)) // 初始化硬件
|
|
{
|
|
rStatus=FALSE;
|
|
StopSampleData();
|
|
}
|
|
break;
|
|
}
|
|
case E_ART_PCI8622_SAMPLE_NPT:
|
|
case E_ART_PCI8622_SAMPLE_NPT_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_NPT_TRIGCLK:
|
|
{
|
|
if (!PCI8622_InitDeviceProAD(m_hDevice, &m_ADPara))
|
|
{
|
|
rStatus=FALSE;
|
|
StopSampleData();
|
|
}
|
|
break;
|
|
}
|
|
case E_ART_PCI8622_SAMPLE_HALF:
|
|
case E_ART_PCI8622_SAMPLE_HALF_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_HALF_TRIGCLK:
|
|
{
|
|
if (!PCI8622_InitDeviceProAD(m_hDevice, &m_ADPara))
|
|
{
|
|
rStatus=FALSE;
|
|
StopSampleData();
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (rStatus)
|
|
{
|
|
m_StopedSample=FALSE;
|
|
m_EnStartSample=TRUE;
|
|
}
|
|
|
|
|
|
#endif //_RELEASE_FULL_VERSION
|
|
return rStatus;
|
|
}
|
|
//========================================
|
|
BOOL CART_PCI8622::StartSampleData()
|
|
{
|
|
BOOL rStatus(TRUE);
|
|
#ifdef _RELEASE_FULL_VERSION
|
|
switch(m_iSampleMode)
|
|
{
|
|
case E_ART_PCI8622_SAMPLE_DMA:
|
|
case E_ART_PCI8622_SAMPLE_DMA_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_DMA_TRIGCLK:
|
|
{
|
|
rStatus=PCI8622_StartDeviceDmaAD(m_hDevice); // 启动设备
|
|
break;
|
|
}
|
|
case E_ART_PCI8622_SAMPLE_NPT:
|
|
case E_ART_PCI8622_SAMPLE_NPT_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_NPT_TRIGCLK:
|
|
{
|
|
rStatus=PCI8622_StartDeviceProAD(m_hDevice);
|
|
break;
|
|
}
|
|
case E_ART_PCI8622_SAMPLE_HALF:
|
|
case E_ART_PCI8622_SAMPLE_HALF_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_HALF_TRIGCLK:
|
|
{
|
|
rStatus=PCI8622_StartDeviceProAD(m_hDevice);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
m_StopedSample=FALSE;
|
|
m_EnGetData=TRUE;
|
|
#endif //_RELEASE_FULL_VERSION
|
|
return rStatus;
|
|
}
|
|
//========================================
|
|
BOOL CART_PCI8622::StopSampleData()
|
|
{
|
|
BOOL rStatus(TRUE);
|
|
#ifdef _RELEASE_FULL_VERSION
|
|
switch(m_iSampleMode)
|
|
{
|
|
case E_ART_PCI8622_SAMPLE_DMA:
|
|
case E_ART_PCI8622_SAMPLE_DMA_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_DMA_TRIGCLK:
|
|
{
|
|
rStatus=PCI8622_ReleaseDeviceDmaAD(m_hDevice); // 释放AD
|
|
rStatus=PCI8622_ReleaseSystemEvent(m_hDmaEvent);
|
|
break;
|
|
}
|
|
case E_ART_PCI8622_SAMPLE_NPT:
|
|
case E_ART_PCI8622_SAMPLE_NPT_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_NPT_TRIGCLK:
|
|
{
|
|
rStatus=PCI8622_ReleaseDeviceProAD(m_hDevice); // 释放AD
|
|
//rStatus=PCI8622_ReleaseDevice(m_hDevice); // 释放设备对象
|
|
break;
|
|
}
|
|
case E_ART_PCI8622_SAMPLE_HALF:
|
|
case E_ART_PCI8622_SAMPLE_HALF_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_HALF_TRIGCLK:
|
|
{
|
|
rStatus=PCI8622_ReleaseDeviceProAD(m_hDevice); // 释放AD
|
|
//rStatus=PCI8622_ReleaseDevice(m_hDevice); // 释放设备对象
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
m_EnStartSample=FALSE;
|
|
m_StopedSample=TRUE;
|
|
m_EnGetData=FALSE;
|
|
#endif //_RELEASE_FULL_VERSION
|
|
return rStatus;
|
|
}
|
|
//========================================
|
|
BOOL CART_PCI8622::GetData(double (*_Data)[HALF_SIZE_WORDS],int* _DataNumber)
|
|
{
|
|
BOOL rStatus(TRUE);
|
|
#ifdef _RELEASE_FULL_VERSION
|
|
if(!m_EnGetData)
|
|
{
|
|
return FALSE;
|
|
}
|
|
int nADChannel = 0;
|
|
WORD ADData(0);
|
|
double dVolt(0);
|
|
int Index(0);
|
|
switch(m_iSampleMode)
|
|
{
|
|
case E_ART_PCI8622_SAMPLE_DMA:
|
|
case E_ART_PCI8622_SAMPLE_DMA_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_DMA_TRIGCLK:
|
|
{
|
|
PCI8622_STATUS_DMA DMAStatus; // DMA状态参数
|
|
PCI8622_GetDevStatusDmaAD(m_hDevice, &DMAStatus);
|
|
bool bWait(true);
|
|
while(bWait) // 查询当前物理缓冲区数据是否已准备就绪
|
|
{
|
|
if(WaitForSingleObject (m_hDmaEvent, 100)==WAIT_OBJECT_0)
|
|
bWait=false; // 等待DMA事件
|
|
}
|
|
if(!PCI8622_GetDevStatusDmaAD(m_hDevice, &DMAStatus))
|
|
{
|
|
rStatus=FALSE;
|
|
StopSampleData();
|
|
}
|
|
if(DMAStatus.bBufferOverflow)
|
|
{
|
|
rStatus=FALSE;
|
|
}
|
|
|
|
for(m_SegmentID=0; m_SegmentID<SEGMENT_COUNT; m_SegmentID++)
|
|
{
|
|
if(DMAStatus.bSegmentSts[m_SegmentID])
|
|
{
|
|
TRACE1("[PCI8622_GetDevStatusDmaAD] m_SegmentID:%d.\r\n",m_SegmentID);
|
|
nADChannel = m_ADPara.FirstChannel;
|
|
for(Index=0; Index<m_iReadDataSize; Index++)
|
|
{
|
|
ADData = ((ADBuffer[m_SegmentID][Index]));
|
|
// 将原码转换为电压值
|
|
dVolt = static_cast<double>(((m_AD_LSB_MAX/m_AD_LSB_RANGE) * ADData - m_AD_LSB_HALF));
|
|
_Data[nADChannel][_DataNumber[nADChannel]]=dVolt;
|
|
_DataNumber[nADChannel]+=1;
|
|
nADChannel++;
|
|
if(nADChannel > m_ADPara.LastChannel)
|
|
{
|
|
nADChannel = m_ADPara.FirstChannel;
|
|
}
|
|
}
|
|
}
|
|
if(!PCI8622_SetDevStatusDmaAD(m_hDevice, m_SegmentID))
|
|
{
|
|
rStatus=FALSE;
|
|
StopSampleData();
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case E_ART_PCI8622_SAMPLE_NPT:
|
|
case E_ART_PCI8622_SAMPLE_NPT_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_NPT_TRIGCLK:
|
|
{
|
|
PCI8622_STATUS_AD ADStatus;
|
|
if(!PCI8622_GetDevStatusProAD(m_hDevice, &ADStatus))
|
|
{
|
|
rStatus=FALSE;
|
|
break;
|
|
}
|
|
m_SegmentID=0;
|
|
|
|
LONG nReadSizeWords = (m_iReadDataSize+1)*(1+m_iLastChannel-m_iFirstChannel)*10;
|
|
LONG nRetSizeWords(0);
|
|
|
|
//if (ADStatus.nRemainWords<nReadSizeWords)
|
|
//{
|
|
// nReadSizeWords=ADStatus.nRemainWords;
|
|
// rStatus=FALSE;
|
|
//}
|
|
|
|
PCI8622_ReadDeviceProAD_Npt(m_hDevice, ADBuffer[m_SegmentID], nReadSizeWords, &nRetSizeWords);
|
|
|
|
if(!PCI8622_GetDevStatusProAD(m_hDevice, &ADStatus))
|
|
{
|
|
rStatus=FALSE;
|
|
break;
|
|
}
|
|
nADChannel = m_ADPara.FirstChannel;
|
|
TRACE1("[PCI8622_ReadDeviceProAD_Npt] Retsize:%d.\r\n",nRetSizeWords);
|
|
for(Index=0; Index<nReadSizeWords; Index++)
|
|
{
|
|
ADData = ((ADBuffer[m_SegmentID][Index]));
|
|
// 将原码转换为电压值
|
|
dVolt = static_cast<double>(((m_AD_LSB_MAX/m_AD_LSB_RANGE) * (ADData&0xFFFF) - m_AD_LSB_HALF));
|
|
_Data[nADChannel][_DataNumber[nADChannel]]=dVolt;
|
|
_DataNumber[nADChannel]+=1;
|
|
nADChannel++;
|
|
if(nADChannel > m_ADPara.LastChannel)
|
|
{
|
|
nADChannel = m_ADPara.FirstChannel;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case E_ART_PCI8622_SAMPLE_HALF:
|
|
case E_ART_PCI8622_SAMPLE_HALF_SEQ:
|
|
case E_ART_PCI8622_SAMPLE_HALF_TRIGCLK:
|
|
{
|
|
PCI8622_STATUS_AD ADStatus;
|
|
LONG nReadSizeWords = 4096;
|
|
LONG nRetSizeWords(0);
|
|
m_SegmentID=0;
|
|
if(!PCI8622_GetDevStatusProAD(m_hDevice, &ADStatus))
|
|
{
|
|
rStatus=FALSE;
|
|
StopSampleData();
|
|
}
|
|
if(ADStatus.bHalf)
|
|
{
|
|
break; // 若板载FIFO存储器数据量达到半满以上,则退出状态查询,开始读取半满数据
|
|
}
|
|
if(!PCI8622_ReadDeviceProAD_Half(m_hDevice, ADBuffer[m_SegmentID], nReadSizeWords, &nRetSizeWords))
|
|
{
|
|
rStatus=FALSE;
|
|
StopSampleData();
|
|
}
|
|
else
|
|
{
|
|
nADChannel = m_ADPara.FirstChannel;
|
|
TRACE1("[PCI8622_ReadDeviceProAD_Half] Retsize:%d.\r\n",nRetSizeWords);
|
|
for(Index=0; Index<64; Index++)
|
|
{
|
|
ADData = ((ADBuffer[m_SegmentID][Index]));
|
|
// 将原码转换为电压值
|
|
dVolt = static_cast<double>(((m_AD_LSB_MAX/m_AD_LSB_RANGE) * ADData - m_AD_LSB_HALF));
|
|
_Data[nADChannel][_DataNumber[nADChannel]]=dVolt;
|
|
_DataNumber[nADChannel]+=1;
|
|
nADChannel++;
|
|
if(nADChannel > m_ADPara.LastChannel)
|
|
{
|
|
nADChannel = m_ADPara.FirstChannel;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_StopedSample=FALSE;
|
|
#else
|
|
UNREFERENCED_PARAMETER(_Data);
|
|
UNREFERENCED_PARAMETER(_DataNumber);
|
|
#endif //_RELEASE_FULL_VERSION
|
|
|
|
return rStatus;
|
|
|
|
}
|
|
|
|
|