#include "StdAfx.h" #include "PciCh365Mgr.h" #include "LogMgr.h" #include "LaipuVbDllMgr.h" #include "PciPortMgr.h" #include "ExceptionMsg.h" #include "Mirror.h" #define LASER_PORT 7//激光开关端口 CPciCh365Mgr *gPciCh365Mgr = new CPciCh365Mgr; CPciCh365Mgr::CPciCh365Mgr(void) { } CPciCh365Mgr::~CPciCh365Mgr(void) { } bool CPciCh365Mgr::ReadDll() { m_PciCh365Handle = LoadLibrary( "CH365DLL.DLL" ); if( !m_PciCh365Handle ) { gLogMgr->WriteDebugLog("pci 卡动态链接库CH365DLL.DLL 读取失败",_LOG_ERROR); return false; } //读取需要的函数地址 bool result = true; result &= ((CH365mOpenDevice = (pCH365mOpenDevice)GetProcAddress( m_PciCh365Handle, "CH365mOpenDevice" )) != NULL); result &= ((CH365mReadIoByte = (pCH365mReadIoByte)GetProcAddress( m_PciCh365Handle, "CH365mReadIoByte" )) != NULL); result &= ((CH365mSetA15_A8 = (pCH365mSetA15_A8)GetProcAddress( m_PciCh365Handle, "CH365mSetA15_A8" )) != NULL); result &= ((CH365mWriteIoByte = (pCH365mWriteIoByte)GetProcAddress( m_PciCh365Handle, "CH365mWriteIoByte" )) != NULL); result &= ((CH365mCloseDevice = (pCH365mCloseDevice)GetProcAddress( m_PciCh365Handle, "CH365mCloseDevice" )) != NULL); if(!result) { gLogMgr->WriteDebugLog("CH365DLL.DLL 函数提取失败",_LOG_ERROR); return false; } return true; } #if 1 //初始化pci 卡 void CPciCh365Mgr::Ini() { m_bIni = false;//pci 卡是否初始化成功 m_OutPortStateLow = 0;//记录当前输出端口的状态--用于向端口写数据 m_OutPortStateHigh = 0;//记录当前输出端口的状态--用于向端口写数据 //获取硬件支持的高精度计数器的频率 IniClockFre(); if(ReadDll())//读取dll { //自己初始化pci 卡 if(IniPciCard()) { #if 0 gLaipuVbDllMgr->VbIniCard(m_OutPortStateLow,m_OutPortStateHigh); //初始化输出 端口的状态 IniOutPortState(); #endif } //关闭激光端口 CloseLaserPort(); } } //自己初始化pci 卡 bool CPciCh365Mgr::IniPciCard() { //初始化pci 卡 m_DeviceHandle = CH365mOpenDevice(0,true,true); if((int)m_DeviceHandle==-1) { gLogMgr->WriteDebugLog("未发现ch365 pci 卡",_LOG_ERROR); return false; } //初始化输入端口(否则输入端口无法读取) UCHAR ChByte = 0xFF; CH365mSetA15_A8(0,ChByte);//恢复高8位地址 m_bIni = true; gLogMgr->WriteDebugLog("ch 365 pci 初始化成功"); return true; } //初始化输出 端口的状态 void CPciCh365Mgr::IniOutPortState() { gLogMgr->WriteDebugLog("IniOutPortState",_LOG_FUNC); int OutPortDefaultStateL = gPciPortMgr->GetOutPortDefaultStateL(); int OutPortDefaultStateH = gPciPortMgr->GetOutPortDefaultStateH(); for(int i=0;i<8;i++)//低八位 { if(IsBitOn((BYTE)OutPortDefaultStateL,i)) { SPciPort PciPort; PciPort.num = i; WritePortState(PciPort,true); } } for(int i=0;i<8;i++)//高八位 { if(IsBitOn((BYTE)OutPortDefaultStateH,i)) { SPciPort PciPort; PciPort.num = i+8; WritePortState(PciPort,true); } } } //检查pci 是否初始化了,没有则抛出异常,也就是说调用这个函数时PCI 必须初始化 void CPciCh365Mgr::CheckIniState() { if(!m_bIni) { CString str(_T("PCI 卡未初始化")); CExceptionMsg Msg; Msg.SetMsg(str); throw Msg; } } #endif #if 1//延时 //微秒级延时,us为微秒 void CPciCh365Mgr::DelayTime(unsigned int us) { if(m_bHasSmartClock && us>0) { LARGE_INTEGER start, end; LONGLONG count = (us*m_ClockFre.QuadPart)/(1000*1000); QueryPerformanceCounter(&start); count = count + start.QuadPart ; do { QueryPerformanceCounter(&end); }while(end.QuadPartWriteDebugLog("获取高精度计时器频率失败",_LOG_ERROR); } else { gLogMgr->WriteDebugLog("获取高精度计时器频率成功"); } } #endif #if 1 //从指定端口读入一个字节 BOOL CPciCh365Mgr::ReadIoPortByte(int PortAddr,long &PortVal) { BOOL result = FALSE; UCHAR ChByte; USHORT mAddr=(USHORT)PortAddr; UINT mIndex= 0 ; if(PortAddr<255) { if(CH365mReadIoByte(mIndex,(PVOID)mAddr,&ChByte)) { PortVal = (long)ChByte; result = TRUE; } } else { ChByte = PortAddr/256; CH365mSetA15_A8(0,ChByte);//设定高8位地址 PortAddr = PortAddr%256; if(CH365mReadIoByte(mIndex,(PVOID)&PortAddr,&ChByte)) { PortVal = (long)ChByte; result = TRUE; } ChByte = 0xFF; CH365mSetA15_A8(0,ChByte);//恢复高8位地址 } return result; } //向指定端口写入一个字节 void CPciCh365Mgr::WriteIoPortByte(int PortAddr,long PortVal) { UCHAR ChByte; if(PortAddr<255) { USHORT mAddr=(USHORT)PortAddr; ChByte = (UCHAR)PortVal; CH365mWriteIoByte(0,(PVOID)mAddr,ChByte);//端口写入一次时间大约需要4us } else { ChByte = PortAddr>>8; CH365mSetA15_A8(0,ChByte);//设定高8位地址 USHORT mAddr=(USHORT)(PortAddr%256); ChByte = (UCHAR)PortVal; CH365mWriteIoByte(0,(PVOID)mAddr,ChByte); ChByte = 0xFF; CH365mSetA15_A8(0,ChByte);//恢复高8位地址 } } //设置端口状态 void CPciCh365Mgr::WritePortState(SPciPort PciPort,bool bOpen) { //检查pci 初始化状态 CheckIniState(); if(PciPort.num == -1) return; //处理高八位还是低八位 bool bLow = LowOrHight(PciPort.num); //获得输出端口状态 long &OutPortState = GetOutPortState(bLow); //获得端口地址 int PortAddr = GetPortAddr(bLow,true); //反向操作 if(PciPort.bReverse) { bOpen = !bOpen; } if(bOpen) { OutPortState = SetBitOn(OutPortState,PciPort.num); WriteIoPortByte(PortAddr,OutPortState); } else { OutPortState = SetBitOff(OutPortState,PciPort.num); WriteIoPortByte(PortAddr,OutPortState); } } //发送一个脉冲 //PortNum 端口号0~15 //Delay 是脉冲延时us void CPciCh365Mgr::SendOnePulse(SPciPort PciPort,unsigned int Delay) { //检查pci 初始化状态 CheckIniState(); //处理高八位还是低八位 bool bLow = LowOrHight(PciPort.num); //获得端口地址 int PortAddr = GetPortAddr(bLow,true); //获得输出端口状态 long &OutPortState = GetOutPortState(bLow); //先高后低--------------------------------- OutPortState = SetBitOn(OutPortState,PciPort.num); WriteIoPortByte(PortAddr,OutPortState); DelayTime(Delay); OutPortState = SetBitOff(OutPortState,PciPort.num); WriteIoPortByte(PortAddr,OutPortState); DelayTime(Delay); } #endif //关闭激光端口 void CPciCh365Mgr::CloseLaserPort() { SPciPort PciPort; PciPort.num = LASER_PORT; gLogMgr->WriteDebugLog("关闭端口","PortNum", LASER_PORT); bool b = false; if(gMirror->IsLaserSwitch()) b = !b; try { gPciCh365Mgr->WritePortState(PciPort,b); } catch(CExceptionMsg &Msg) { CString str("Func : CloseLaserPort---->"); str += Msg.GetMsgStr(); gLogMgr->WriteDebugLog(str,_LOG_ERROR); } }