#include "StdAfx.h" #include #include #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 = 10000; // 采样频率(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_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(((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; LONG nRetSizeWords(0); 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(((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(((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; }