⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm5002k.cpp

📁 pm518采集卡驱动源码
💻 CPP
字号:
// ------------------------------------------------- //
//                   PM5002K  用WINDRV               //
// ------------------------------------------------- //

#include <AFXWIN.h>
#include <windows.h>
#include "pm5002k_lib.h"
#include "c:/windriver/include/status_strings.h"

#include "pm5002k.h"

#include <stdio.h>		//后加的


//陈新华       增加一个全局消息处理窗口句柄  g_hWndMessage 
HWND   g_hWndMessage;

//增加一个一个应用程序接口函数用来设置消息处理窗口句柄    g_hWndMessage 定义如下
  void SetMessageWindow(HWND hWnd) 
  { 
	  g_hWndMessage = hWnd;

  }
  //此函数由用户在设置采集卡参数调用

 

unsigned long m_errorLevel = 0;//返回错误号
unsigned long m_nCountFrom = 1;//默认通道号或芯片号从1开始算起
long AIRangeArr[MAX_AI_RANGE+1][2] = 
{{0,0},{0,5000},{0,10000},{1000,5000},{-2500,2500},{-5000,5000},{-10000,10000}};//模拟量输出范围

long AORangeArr[MAX_AO_RANGE+1][2] = 
{{0,0},{0,5000},{0,10000},{1000,5000},{-2500,2500},{-5000,5000},{-10000,10000},{0,0},{0,0},{0,10000},{4000,20000}};//模拟量输出范围


PM5002K_HANDLE hPM5002K = NULL;

unsigned short getAOInitCode(long nValue,\
							 unsigned long MaxDAinitCode,\
							 unsigned long AORangeIndex)
{
//根据指定的AORangeIndex把nValue转换为0-4095或0-255之间的值
// AORangeIndex=0 对应的数组元素只是用于占位,AORangeIndex=0一定不能转换
	if( AORangeIndex != 0 ) //不为原码方式,才转换,避免不必要的精度损失
	{
		long leftVal = AORangeArr[AORangeIndex][0];
		long rightVal = AORangeArr[AORangeIndex][1];
		if(nValue < leftVal) nValue = leftVal;
		if(nValue > rightVal) nValue = rightVal;
		long returnVal = (nValue - leftVal)*MaxDAinitCode/(rightVal-leftVal);
		return (unsigned short)returnVal;
	}
	else
	{
		return (unsigned short)nValue;
	}
}



unsigned long CheckAddr(unsigned long nAddr)
{
//检查地址范围,使地址在0x100--0x3F0之间
//用 nAddr = (nAddr | 0x100) & 0x3F0; 不行,对于0x2F0会有错
	if( nAddr < 0x100 )
	{
		nAddr = 0x100;
		m_errorLevel = ERR_PARAMETER_BASEADDR;
	}
	else if( nAddr > 0x3F0 )
	{
		nAddr = 0x3F0;
		m_errorLevel = ERR_PARAMETER_BASEADDR;
	}
	return nAddr;
}


unsigned long _stdcall GetDll_LastErrNO()
{
//得到当前的错误状态号
	return m_errorLevel;
}


void _stdcall ClearDll_LastErrNO()
{
//清除错误号
	m_errorLevel = 0;
}


unsigned long GetULongXBit(unsigned long dataDoubleWord,\
									unsigned long nBit)
{
//得到一个无符号长整型的某一位
	return (dataDoubleWord >> nBit) & 0x1;
}


unsigned long SetULongXBit(unsigned long dataDoubleWord,\
						   unsigned long nBit,\
						   unsigned long nState)
{
//设置一个无符号长整型的某一位,并将设置的无符号长整型返回
	unsigned long dataDoubleMask = 1;//必须设此变量,使它与dataDoubleWord匹配,
	//也就是如果用unsigned long 与 unsigned char 作位操作,高位结果与期望值不符
	if(nState != 0)
	{
//		dataDoubleMask = nState;
		dataDoubleMask = dataDoubleMask << nBit;
		return dataDoubleWord | dataDoubleMask;
	}
	else
	{
//		dataDoubleMask = 1;
		dataDoubleMask = ~(dataDoubleMask << nBit);//“~”才是按位取反,用“!”不行,会使非0全部为0
		return dataDoubleWord & dataDoubleMask;
	}
}

void _stdcall SetCountFrom(unsigned long nCountFrom)
{
//设置芯片号或通道号,从0开始还是从1开始
	m_nCountFrom = (nCountFrom!=0)?1:0;//只能为0或1
}


unsigned long _stdcall GetCountFrom()
{
//返回芯片号或通道号,从0开始还是从1开始
	return m_nCountFrom;
}


long _stdcall OpenDevicePM()
{
//打开设备,启动WinDriver,主要是为了设置m_errorLevel
    hPM5002K = NULL;
    if (!PM5002K_Open(&hPM5002K))
    {
		m_errorLevel = ERR_WINDRV;
		return -1;
    }
	m_errorLevel = ZT_SUCCESS;//没有调用可能改变m_errorLevel的函数,所以此处必须设置m_errorLevel
	return 0;
}


long _stdcall CloseDevicePM()
{
//关闭设备,关闭WinDriver,主要是为了设置m_errorLevel

	if( hPM5002K != NULL )//如果不为空才关闭
	{
	    PM5002K_Close(hPM5002K);
		m_errorLevel = ZT_SUCCESS;//没有调用可能改变m_errorLevel的函数,所以此处必须设置m_errorLevel
		return 0;
	}
	else
	{
		m_errorLevel = ERR_WINDRV;
		return -1;	
	}
}



double changeToAIRange(unsigned long ADInitCode,\
					   unsigned long MaxADinitCode,\
					   unsigned long AIRangeIndex)
{
//根据模拟量的极性及范围,返回结果
//转换结果形式,转换后的结果可正可负可为小数,所以用double
//注意用二维数组作形参时,第2维的维数不能省
//AIMode=0必须代表原码,否则会出错
	AIRangeIndex&=0xf;
	if( AIRangeIndex != 0 ) //不为原码方式,才转换,避免不必要的精度损失
	{
		double leftVal = AIRangeArr[AIRangeIndex][0];
		double rightVal = AIRangeArr[AIRangeIndex][1];
		double returnVal = (rightVal - leftVal)*ADInitCode/MaxADinitCode + leftVal;
		return returnVal;
	}
	else
	{
		return ADInitCode;
	}
}




unsigned char _stdcall ReadB(unsigned long nAddr,\
							 unsigned long nOffset)
{
//8位读
	unsigned char GetVal=0;
	GetVal = PM5002K_ReadByte(hPM5002K, 0, nAddr+nOffset-PM5002K_IORange0_ADDR);
	m_errorLevel = ZT_SUCCESS;//函数成功调用
	return (unsigned char)GetVal;
}

unsigned short _stdcall ReadW(unsigned long nAddr,\
							  unsigned long nOffset)
{
//16位读
	unsigned short GetVal=0;
	GetVal = PM5002K_ReadWord(hPM5002K, 0, nAddr+nOffset-PM5002K_IORange0_ADDR);
	m_errorLevel = ZT_SUCCESS;//函数成功调用
	return (unsigned short)GetVal;
}
  
unsigned long _stdcall ReadD(unsigned long nAddr,\
							 unsigned long nOffset)
{
//32位读
	unsigned long GetVal=0;
	GetVal = PM5002K_ReadDword(hPM5002K, 0, nAddr+nOffset-PM5002K_IORange0_ADDR);
	m_errorLevel = ZT_SUCCESS;//函数成功调用
	return (unsigned long)GetVal;
}

void _stdcall WriteB(unsigned long nAddr,\
					 unsigned long nOffset,\
					 unsigned long dataByte)
{
//8位写
	PM5002K_WriteByte(hPM5002K, 0, nAddr+nOffset-PM5002K_IORange0_ADDR, (unsigned char)dataByte);
	m_errorLevel = ZT_SUCCESS;//函数成功调用
}

void _stdcall WriteW(unsigned long nAddr,\
					 unsigned long nOffset,\
					 unsigned long dataWord)
{
//16位写
	PM5002K_WriteWord(hPM5002K, 0, nAddr+nOffset-PM5002K_IORange0_ADDR, (unsigned short)dataWord);
	m_errorLevel = ZT_SUCCESS;//函数成功调用
}

void _stdcall WriteD(unsigned long nAddr,\
					 unsigned long nOffset,\
					 unsigned long dataDoubleWord)
{
//32位写
	PM5002K_WriteDword(hPM5002K, 0, nAddr+nOffset-PM5002K_IORange0_ADDR, dataDoubleWord);
	m_errorLevel = ZT_SUCCESS;//函数成功调用
}
///////////////////////////中断中的回调函数//////////////////////////////////
void _stdcall PM5002K_Interrupt5HandlerRoutine(PM5002K_HANDLE hPM5002K,\
										PM5002K_Interrupt5_RESULT *intResult,\
										long *pResultArr,\
										int inttimein)
{	
	int i;
	int j;
	long flag_sfifo;
//	CString timeend; 
		//进入中断内存方式读4096数,读出数据个数是4096的倍数
	inttimein=m_inttime;		
		if((ReadW(0x100,10)&0x2000)==0){			//判断是否半满
		flag_sfifo=m_intflag*4096;					//m_intflag是进入中断的次数,*4096后得出本次中断中储存数据的位置
													//例:m_intflag=0时,储存在0~4095;m_intflag=1时,储存在(0~4095)+4096=4096~8191;
		PM5002K_ReadHFifo(hPM5002K,0,2,m_sfifo+flag_sfifo,8192);	//内存方式读取一次中断的数据,4096个
		m_intflag++;								//中断次数+1						
//		*m_eff++=m_intflag;							//试验中断次数
		}
		//当最后一次中断结束后读取fifo众剩余的数据,加上前面的数据就是完整采样过程
		if(m_intflag==inttimein){					//inttimein是中断次数,需要计算后用ZT_PM518INTTIMESET写入
		//通过判断fifo非空采集剩余数据
			j=0;						//?? no use
			for(i=0;i<4096;i++){		//由于此时fifo中的剩余数据<4096个,故循环4096次采样
				if((ReadW(0x100,10)&0x4000)!=0)		//判断fifo是否非空
//					*m_eff++=ReadW( 0x100, 2);			//无法让指针回到原点
					*(m_eff+(j++))=ReadW( 0x100, 2);
					}
				*(m_eff+4095)=j;
		//通过内存方式读取4096数
//			PM5002K_ReadHFifo(hPM5002K,0,2,m_eff,8192);
			//纪录采集结束时间测试采样的实时性
			//自定义系统消息请在这里添加

//陈新华 
			
			//发送自定义消息給给指定的窗口句柄 g_hWndMessage 
			
			::SendMessage(g_hWndMessage,WM_SAMPLE_FINISH, 0,0);//WM_SAMPLE_FINISH 即为自定义的消息
			//在此之前要先调用接口函数  SetMessageWindow  设置 g_hWndMessage 
		
//陈新华
			SYSTEMTIME sys; 
			GetLocalTime( &sys ); 
			m_tendS=sys.wSecond;
			m_tendMS=sys.wMilliseconds;
//			timeend.Format("%d秒%d毫秒",m_tendS,m_tendMS);   
//			AfxMessageBox(timeend);
			m_intflag=0;	//一轮采集结束,中断纪录归0
		}
}

//////////////////////////////成功的SFIFO///////////////////////////////
/*
void _stdcall PM5002K_Interrupt5HandlerRoutine(PM5002K_HANDLE hPM5002K,\
										PM5002K_Interrupt5_RESULT *intResult,\
										long *pResultArr)
{	
	int i,j;
	intflag=(UINT)intResult->dwCounter;
	if((intflag>intflag_sec)&&(intflag<10)){
		intflag_sec=intflag;
		for(i=0;i<4095;i++)pResultArr[i]=0;
		for(i=0;i<4095;i++){
		pResultArr[i]=ReadW( 0x100, 2);		//可以采到,传到m_sdata里
		m_sdata[i]=pResultArr[i];
		m_sfifo[i+intflag*4095]=m_sdata[i];
		}
	}
}
*/
///////////////////////////////简化的SFIFO//////////////////////////////////////
/*
void _stdcall PM5002K_Interrupt5HandlerRoutine(PM5002K_HANDLE hPM5002K,\
										PM5002K_Interrupt5_RESULT *intResult,\
										long *pResultArr,\
										int inttimein)
{	
	int i;
	long flag_sfifo;
	intflag=(UINT)intResult->dwCounter;
	inttimein=m_inttime;
	flag_sfifo=intflag*4095;

	if((intflag>intflag_sec)&&(intflag<inttimein)){
		intflag_sec=intflag;
		for(i=0;i<4095;i++)
		m_sfifo[i+flag_sfifo]=ReadW( 0x100, 2);
	}
}
*/
////////////////////////////////////////////////////////////////////////////////
unsigned long _stdcall intenable(unsigned long nAddr)
{
//使能中断,返回值0-禁止中断 1-使能中断 -1-中断开启失败
	int intena;

	 if (PM5002K_Interrupt5IsEnabled(hPM5002K))
            {
                PM5002K_Interrupt5Disable(hPM5002K);
				intena=0;
            }
            else
            {
				intena=1;
                if (!PM5002K_Interrupt5Enable(hPM5002K, PM5002K_Interrupt5HandlerRoutine))
				intena=-1;
            }
			return intena;
}


⌨️ 快捷键说明

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