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

📄 pm5320.cpp

📁 pm518采集卡驱动源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	//检查参数
	nAddr = CheckAddr(nAddr);//使地址在0x100--0x3F0之间
	//若用户参数错,不继续执行
	if(m_errorLevel != ZT_SUCCESS) return -1;

	//读当前控制寄存器的状态,保存到一个变量中,因为清FIFO的同时会清空AD控制寄存器
	unsigned short regStatus = ReadW( nAddr, pm518.AIW.PM518_ROff_ADctrlReg);

	//清空FIFO,同时清空控制寄存器
	ReadW(nAddr, pm518.AIW.PM518_ROff_ClearFIFO);

	//因为读出的bit0是AD的转换状态,而FIFO当前是否使能读不到,所以一律把FIFO使能
	regStatus = (regStatus & 0xFFFE) + 0x1;
	//把AD控制寄存器的内容写回去
	WriteW( nAddr, pm518.AIW.PM518_ROff_ADctrlReg, regStatus);
	return ZT_SUCCESS;
}



long _stdcall ZT_PM518AIfifo(unsigned long nAddr,\
						   unsigned long nCh,\
						   unsigned long AIRange,\
						   long *pResultArr,\
						   unsigned long nCount,\
						   unsigned long ADOverTime)
{
//函数功能:软件启动AD,使能外部FIFO,采一批数,求平均值,只能用于单通道方式
//入口函数:
//         nAddr  :板卡基地址
//         nCh:    指定通道号(1-16)
//         AIRange:选择对采集到的AD原码值做何种变换,应该与AD采集量程(一般需跳线)相匹配:
//                  AIRange = 0,表示返回原码(0-65535),所有卡都有这种方式
//                  AIRange = 1,表示把原码值转化为 0 -- 5000mV 之间的值,如果此卡没有这种量程,不应选这种方式
//                  AIRange = 2,表示把原码值转化为 0 -- 10000mV 之间的值,如果此卡没有这种量程,不应选这种方式
//                  AIRange = 5,表示把原码值转化为 -5000 -- 5000mV 之间的值,如果此卡没有这种量程,不应选这种方式
//         pResultArr:是一个含有至少 nCount 个long型元素的缓冲区的首地址
//         nCount: 需要采集的次数,必须>0,并且不应超出缓冲区的长度
//         ADOverTime:设置超时时间,防止地址不对时死机,是一个毫秒数
//                     若 ADOverTime = 0 表不检查AD超时
//返回值:返回 nCount 次采样的平均值
//        若返回 -1 应该进一步调用 GetDll_LastErrNO 判断是否出错

	//1. 检查参数
	nAddr = CheckAddr(nAddr);//使地址在0x100--0x3F0之间
	nCh = nCh - m_nCountFrom;
	if( nCh > pm518.PM518_MaxAISingleChannel ) m_errorLevel = ERR_PARAMETER_CH;
	if( AIRange > MAX_AI_RANGE || pm518.AIRangeArr[AIRange] < 0 ) m_errorLevel = ERR_PARAMETER_AI_RANGE;
	if( nCount< 1 ) m_errorLevel = ERR_PARAMETER6;
	//若用户参数错,不继续执行
	if(m_errorLevel != ZT_SUCCESS) return -1;

	//清空FIFO
	ReadW(nAddr, pm518.AIW.PM518_ROff_ClearFIFO);

	//3. 要先设置AD通道,再设置AD控制寄存器,否则FIFO中可能会多出一些没用的数
	WriteW( nAddr, pm518.AIW.PM518_ROff_ADchannel, nCh);

	//2. 设置为单通道方式,使能外部FIFO,软件启动AD,不能用直接位或的方式
	//读当前控制寄存器的状态
	unsigned short regStatus = ReadW( nAddr, pm518.AIW.PM518_ROff_ADctrlReg);
	//BIT3 = 0:循环通道 1:单通道
	regStatus = 0x1;//(unsigned short)(1*0x8) + 1;
	WriteW( nAddr, pm518.AIW.PM518_ROff_ADctrlReg, regStatus);

	double tempVal = 0;//设为double型,防止溢出
	for(unsigned long i=0; i<nCount+5; i++)
	{
	//4. 软件启动AD,每次都要启动
	ReadW( nAddr, pm518.AIW.PM518_ROff_ADstart );

	//5. 判断FIFO状态
	
	//AD超时时间由用户指定
	DWORD startTime,endTime;
	if( ADOverTime != 0 ) startTime=GetTickCount();//记录开始时间
	//需要防止死机,因为用户可能输入错误的IO地址,导致AD永远不能进行
	while( (ReadW(nAddr,pm518.AIW.PM518_ROff_FIFOstatus) & 0xE000) == 0x2000)//查询FIFO是否非空
	{
		if( ADOverTime != 0 )
		{
			endTime = GetTickCount();
			if( endTime - startTime >= ADOverTime )//大于60ms比较保险,GetTickCount()只精确到55ms
			{
				m_errorLevel = ERR_AD_OVERTIME;//AD超时错
				return -1;//如果超过60ms秒以上就退出
			}
		}
	}
	//6. 读AD结果,字读操作
	unsigned short result16bit;
	result16bit = ReadW( nAddr, pm518.AIW.PM518_ROff_ADresultWord);//一次读出16位结果
//	result16bit = result16bit & (pm5320.AIW.ADresultMask);//屏蔽无效位
	//7. 转换结果
	if(i>=5)
	{
		if( AIRange != 0 )//如果为原码方式,不转换
		{
			pResultArr[i-5] = (long)changeToAIRange( result16bit, pm518.PM518_MaxADinitCode, AIRange );
		}
		else
		{
			pResultArr[i-5] = result16bit;
		}
		tempVal = tempVal + pResultArr[i-5];//累加结果
	}

	}

	return (long)(tempVal/nCount);
}
//函数结束</5320>

long _stdcall ZT_PM518TimerAIFIFO(unsigned long nAddr,\
								unsigned long nChMode,\
								unsigned long nCh,\
								unsigned long Fre,\
								unsigned long AIRange,\
								long *pResultArr,\
								unsigned long nCount,\
								unsigned long ADOverTime)
{
//函数功能:定时启动AD,使用内部FIFO,采一批数,求平均值
//          调用本函数之前,应该先确保已调用 ZT5320SetADfreq 设定了AD采样频率
//入口函数:
//         nAddr  :板卡基地址
//         nChMode:通道方式
//                  1 = 单通道
//                  0 = 多通道扫描方式
//         nCh:    当nChMode =1(单通道方式) 时,为通道号(1--16),通道号默认从1算起
//                  当nChMode =0(多通道扫描方式)时,多通道扫描中止通道号(1-16),通道号默认从1算起,例如设为2表示,通道1和通道2被自动扫描
//         AIRange:选择对采集到的AD原码值做何种变换,应该与AD采集量程(一般需跳线)相匹配:
//                  AIRange = 0,表示返回原码(0-65535),所有卡都有这种方式
//                  AIRange = 1,表示把原码值转化为 0 -- 5000mV 之间的值,如果此卡没有这种量程,不应选这种方式
//                  AIRange = 2,表示把原码值转化为 0 -- 10000mV 之间的值,如果此卡没有这种量程,不应选这种方式
//                  AIRange = 5,表示把原码值转化为 -5000 -- 5000mV 之间的值,如果此卡没有这种量程,不应选这种方式
//         pResultArr:是一个含有至少 nCount 个long型元素的缓冲区的首地址
//         nCount: 需要采集的次数,必须>0,并且不应超出缓冲区的长度
//         ADOverTime:设置超时时间,防止地址不对时死机,是一个毫秒数
//                     若 ADOverTime = 0 表不检查AD超时
//返回值:返回 nCount 次采样的平均值
//        若返回 -1 应该进一步调用 GetDll_LastErrNO 判断是否出错

	//1. 检查参数
	nAddr = CheckAddr(nAddr);//使地址在0x100--0x3F0之间
	nChMode = (nChMode != 0) ? 1 : 0;
	nCh = nCh - m_nCountFrom;
	if( nCh > pm518.PM518_MaxAISingleChannel ) m_errorLevel = ERR_PARAMETER_CH;
	//从直接操作寄存器的层面上来说,单通道时,通道号从0-15
	//多通道扫描方式时,指定的是“中止通道号(0-15)+1”
	nCh = (nChMode != 0) ? nCh : nCh+1;
	if( AIRange > MAX_AI_RANGE || pm518.AIRangeArr[AIRange] < 0 ) m_errorLevel = ERR_PARAMETER_AI_RANGE;
	if( nCount< 1 ) m_errorLevel = ERR_PARAMETER6;
	//若用户参数错,不继续执行
	if(m_errorLevel != ZT_SUCCESS) return -1;

	//清空FIFO
	ReadW(nAddr, pm518.AIW.PM518_ROff_ClearFIFO);

	//3. 要先设置AD通道,再设置AD控制寄存器,否则FIFO中可能会多出一些没用的数
	WriteW( nAddr, pm518.AIW.PM518_ROff_ADchannel, nCh);

	//2. 设置为单通道方式或多通道扫描方式,使能FIFO,定时启动AD,不能用直接位或的方式
	//读当前控制寄存器的状态
	//BIT10 = 0:循环通道 1:单通道
	unsigned long regStatus = ((nChMode<<6)+1)&0xff;
	//试验fifo半满中断
	WriteW( nAddr, pm518.AIW.PM518_ROff_ADctrlReg, regStatus);

	double tempVal = 0;//设为double型,防止溢出
	long erro=0;

	unsigned long Frein;
	Frein=Fre&0xff;
	WriteW( nAddr, 1, Frein);

	while( (erro=ReadW(nAddr,pm518.AIW.PM518_ROff_FIFOstatus) & 0x2000));//bit13-fifo hf 0x2000
	for(unsigned long i=0; i<nCount+10; i++)
	{

	//5. 判断AD转换状态
	
	//AD超时时间由用户指定
	DWORD startTime,endTime;
	if( ADOverTime != 0 ) startTime=GetTickCount();//记录开始时间
	//需要防止死机,因为用户可能输入错误的IO地址,导致AD永远不能进行
	{
		if( ADOverTime != 0 )
		{
			endTime = GetTickCount();
			if( endTime - startTime >= ADOverTime )//大于60ms比较保险,GetTickCount()只精确到55ms
			{
				m_errorLevel = ERR_AD_OVERTIME;//AD超时错
				return -1;//如果超过60ms秒以上就退出
			}
		}
	}
	//6. 读AD结果,字读操作
	unsigned short result16bit;
	result16bit = ReadW( nAddr, pm518.AIW.PM518_ROff_ADresultWord);//一次读出16位结果
	//7. 转换结果
	if(i>=10)
	{
		if( AIRange != 0 )//如果为原码方式,不转换
		{
			pResultArr[i-10] = (long)changeToAIRange( result16bit, pm518.PM518_MaxADinitCode, AIRange );
		}
		else
		{
			pResultArr[i-10]= result16bit;
		}
		tempVal = tempVal + pResultArr[i-10];//累加结果
		}
	}
	return regStatus; 
}
//函数结束</5320>

///////////////////////////////////化物所518特制函数//////////////////////////////////////
//函数开始</518>
long _stdcall ZT_PM518AIinit(unsigned long nAddr,\
							 unsigned long nChMode,\
							 unsigned long nCh,\
							 unsigned long Fre)
{
//函数功能:定时启动AD,使用内部FIFO,采一批数,求平均值
//          调用本函数之前,应该先确保已调用 ZT5320SetADfreq 设定了AD采样频率
//入口函数:
//         nAddr  :板卡基地址
//         nChMode:通道方式
//                  1 = 单通道
//                  0 = 多通道扫描方式
//         nCh:    当nChMode =1(单通道方式) 时,为通道号(1--16),通道号默认从1算起
//                  当nChMode =0(多通道扫描方式)时,多通道扫描中止通道号(1-16),通道号默认从1算起,例如设为2表示,通道1和通道2被自动扫描
//                     若 ADOverTime = 0 表不检查AD超时
//        若返回 -1 应该进一步调用 GetDll_LastErrNO 判断是否出错

	//1. 检查参数

	nAddr = CheckAddr(nAddr);//使地址在0x100--0x3F0之间
	nChMode = (nChMode != 0) ? 1 : 0;
	nCh = nCh - m_nCountFrom;
	if( nCh > pm518.PM518_MaxAISingleChannel ) m_errorLevel = ERR_PARAMETER_CH;
	//从直接操作寄存器的层面上来说,单通道时,通道号从0-15
	//                      多通道扫描方式时,指定的是“中止通道号(0-15)+1”
	nCh = (nChMode != 0) ? nCh : nCh+1;

	//若用户参数错,不继续执行
	if(m_errorLevel != ZT_SUCCESS) return -1;
	//Fre set
	unsigned long Frein;
	Frein=Fre&0xff;
	WriteW( nAddr, 1, Frein);

	//3. 要先设置AD通道,再设置AD控制寄存器,否则FIFO中可能会多出一些没用的数
	WriteW( nAddr, pm518.AIW.PM518_ROff_ADchannel, nCh);
	//fifo半满中断,clk ad采集方式
	unsigned long regStatus = (((nChMode<<6)+1)+0x8)&0xff;
	WriteW( nAddr, pm518.AIW.PM518_ROff_ADctrlReg, regStatus);	
	m_intflag=0;
//	return (long)(tempVal/nCount);
	return regStatus; 
//	return ADT; 
}
//函数结束</518>

//函数开始</518>
long _stdcall ZT_PM518INTENA(unsigned long nAddr,\
							 unsigned short *sfifo,\
							 unsigned short *eff)
{
	nAddr = CheckAddr(nAddr);	//使地址在0x100--0x3F0之间
	if(sfifo!=NULL)				//判断如果用户有指定缓冲区,将此地址传递给内核
	m_sfifo=sfifo;				//中断采集缓冲区
	else return -2;				//中断采集缓冲区,返回-2
	if(eff!=NULL)				//判断如果用户有指定缓冲区,将此地址传递给内核
	m_eff=eff;					//非半满采集缓冲区
	else return -3;				//非半满采集缓冲区未指定,返回-3
	return intenable(nAddr);	//返回中断状态
}

long _stdcall ZT_PM518INTIN(unsigned long nAddr)
{	
	nAddr = CheckAddr(nAddr);	//使地址在0x100--0x3F0之间
	return m_intflag;			//返回实际中断数
}

long _stdcall ZT_PM518INTTIMESET(unsigned long nAddr,unsigned long inttimein)
{
	nAddr = CheckAddr(nAddr);	//使地址在0x100--0x3F0之间
	m_inttime=inttimein;		//传递期待中断数
	return m_inttime;			//返回期待中断数
}

long _stdcall ZT_PM518READHFIFO(unsigned short *pResultArr,unsigned long wCount)
{	
	//调用内存方式读数函数
	PM5002K_ReadHFifo(hPM5002K,0,2,pResultArr,8192);

	return intflag_sec;
}
//返回采集结束时间
long _stdcall ZT_PM518TIMEENDS(unsigned long nAddr)
{
	nAddr = CheckAddr(nAddr);	//使地址在0x100--0x3F0之间
	return m_tendS;			//返回实际中断数
}

long _stdcall ZT_PM518TIMEENDMS(unsigned long nAddr)
{
	nAddr = CheckAddr(nAddr);	//使地址在0x100--0x3F0之间
	return m_tendMS;			//返回实际中断数
}






//消息
//在应用层将句柄传入g_hWndMessage
long _stdcall ZT_PM518INTHANDLE(unsigned long nAddr, HWND hWnd)
{
	nAddr = CheckAddr(nAddr);			//使地址在0x100--0x3F0之间
	SetMessageWindow((HWND) hWnd);		//HWND不加“()”编译失败?
	return 0;			
}
//函数结束</518>
/////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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