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

📄 pm5320.cpp.bak

📁 pm518采集卡驱动源码
💻 BAK
📖 第 1 页 / 共 3 页
字号:
// ------------------------------------------------- //
//                   PM5320  新驱动                  //
// ------------------------------------------------- //

#include <windows.h>
#include "..\pm5002k.h"
#include "pm5320.h"


//结构信息开始<5320>
#define PM5320_SPECIAL
struct PM5320_INFO //PM5320信息
{
//卡型号
	unsigned short CardManorVer;//5320
	unsigned char CardMinorVer; //' '
//用于参数检查的值
	unsigned short MaxADinitCode;//65535(16位卡最大原码为65535)
	unsigned char MaxAISingleChannel;//15(0--15)共16路,无双通道方式
	unsigned short MaxDAinitCode;//4095(12位卡最大原码为4095)
	unsigned char MaxAOChannel;      //7(0--7)共8路
//AD相关信息,本卡是一个AIW型的卡
	PM5320_AIWFIFO AIW;//是一个结构
	//unsigned char ROff_ADfreqReg; //12(写,写入AD定时启动分频系数0-255)
	//unsigned char ROff_ADctrlReg;  //8(写,写入工作方式控制字) 
	//unsigned char ROff_ADchannel;   //0(写,写通道代码,选通道)
	//unsigned char ROff_ADstart;     //0(启动A/D转换)
	//bool ADWriteStart;              //false(默认为写启动,5320为读启动)
	//unsigned char ROff_ClearFIFO;   //2(写,清空FIFO,同时清空AD控制寄存器)
	//unsigned char ROff_FIFOstatus;  //8(读,查询FIFO是否为空)
	//unsigned short FIFOstatusMask;   //0x8000(FIFO状态屏蔽字节)
	//unsigned short FIFOstatusCanRead;//0x8000(FIFO中有新数据)
	//unsigned char ROff_ADresultWord;//2(读,读12位或16位A/D转换结果)
	//unsigned short ADresultMask;      //0xFFFF(16位结果)
	//unsigned long ADJumpChannelTime;//0(默认),AD通道切换时间,替代原ADcha
	char AIRangeArr[7];//模拟量输入范围
//DA相关信息,本卡是一个AO48型的卡
	PM5320_AO_W AOW;//是一个结构
	//unsigned char ROff_DAchannel;//0x4(写,写通道代码,选通道)
	//unsigned char ROff_DAWord;//0x6(写,写16位D/A数据)
	//unsigned short DAWordMask;//0x0FFF可能需要屏蔽掉一些位
	char AORangeArr[11];//模拟量输出范围
};
PM5320_INFO pm5320 = {5320,' ',65535,15,4095,7,\
12,8,0,0,false,2,8,0x8000,0x8000,2,0xFFFF,0,\
{0,1,2,-3,-4,5,-6},\
0x4,0x6,0x0FFF,\
{0,1,-2,-3,-4,-5,-6,-7,-8,-9,-10}};
//结构信息结束</5320>


//函数开始<5320>
long _stdcall ZT5320SetADfreq(unsigned long nAddr, unsigned long ADfreq)
{
//函数功能:设置AD采样频率
//入口函数:
//         nAddr  :板卡基地址
//         ADfreq :指定AD采样频率:100K/(ADfreq+1),ADfreq在0--255之间(0对应100K,1对应50K...)
//返回值:0表成功,-1表失败,函数调用失败时应进一步调用 GetDll_LastErrNO 判断出错原因

	//检查参数
	nAddr = CheckAddr(nAddr);//使地址在0x100--0x3F0之间
	//ADfreq必须在1-256之间
//	if( ADfreq < 1 || ADfreq > 256 ) m_errorLevel = ERR_PARAMETER2;
//	ADfreq = ADfreq - 1;//把ADfreq改为0-255之间后,才能写入分频寄存器
	if( ADfreq > 255 ) m_errorLevel = ERR_PARAMETER2;

	//若用户参数错,不继续执行
	if(m_errorLevel != ZT_SUCCESS) return -1;

	WriteW( nAddr, pm5320.AIW.ROff_ADfreqReg, ADfreq);
	return ZT_SUCCESS;
}
//函数结束</5320>


//函数开始<5320>
long _stdcall ZT5320GetFIFOstatus(unsigned long nAddr)
{
//函数功能:查询FIFO状态
//入口函数:
//         nAddr  :板卡基地址
//返回值:返回大于 0 的数表成功:
//        0 表FIFO空,
//        1 表FIFO非空但不到半满
//        2 表FIFO半满
//        3 表FIFO全满  
//        4 表未知状态  
//返回 -1表失败,函数调用失败时应进一步调用 GetDll_LastErrNO 判断出错原因

	//检查参数
	nAddr = CheckAddr(nAddr);//使地址在0x100--0x3F0之间
	//若用户参数错,不继续执行
	if(m_errorLevel != ZT_SUCCESS) return -1;
	//读当前控制寄存器的状态
	unsigned short regStatus = ReadW( nAddr, pm5320.AIW.ROff_ADctrlReg);
	regStatus = regStatus & 0xE000;
	long retVal = 0;
	switch(regStatus)
	{
		case 0x6000:
			retVal = 0;
			break;
		case 0xE000:
			retVal = 1;
			break;
		case 0xA000:
			retVal = 2;
			break;
		case 0x8000:
			retVal = 3;
			break;	
		default:
			retVal = 4;
	}
	return retVal;
}
//函数结束</5320>


//函数开始<5320>
long _stdcall ZT5320ClearFIFO(unsigned long nAddr)
{
//函数功能:清空FIFO,同时使能外部FIFO,但如果内部FIFO有效,内部FIFO优先,而外部FIFO仍然无效
//入口函数:
//         nAddr  :板卡基地址
//返回值:0表成功,-1表失败,函数调用失败时应进一步调用 GetDll_LastErrNO 判断出错原因

	//检查参数
	nAddr = CheckAddr(nAddr);//使地址在0x100--0x3F0之间
	//若用户参数错,不继续执行
	if(m_errorLevel != ZT_SUCCESS) return -1;

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

	//清空FIFO,同时清空控制寄存器
	WriteW(nAddr, pm5320.AIW.ROff_ClearFIFO, 0);

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


//函数开始<5320>
long _stdcall ZT5320AIfifo(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 > pm5320.MaxAISingleChannel ) m_errorLevel = ERR_PARAMETER_CH;
	if( AIRange > MAX_AI_RANGE || pm5320.AIRangeArr[AIRange] < 0 ) m_errorLevel = ERR_PARAMETER_AI_RANGE;
	if( nCount< 1 ) m_errorLevel = ERR_PARAMETER6;
	//若用户参数错,不继续执行
	if(m_errorLevel != ZT_SUCCESS) return -1;

	//清空FIFO
	WriteW(nAddr, pm5320.AIW.ROff_ClearFIFO, 0);

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

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

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

	//5. 判断FIFO状态
	
	//AD超时时间由用户指定
	DWORD startTime,endTime;
	if( ADOverTime != 0 ) startTime=GetTickCount();//记录开始时间
	//需要防止死机,因为用户可能输入错误的IO地址,导致AD永远不能进行
	while( (ReadW(nAddr,pm5320.AIW.ROff_FIFOstatus) & 0xE000) == 0x6000)//查询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, pm5320.AIW.ROff_ADresultWord);//一次读出16位结果
//	result16bit = result16bit & (pm5320.AIW.ADresultMask);//屏蔽无效位
	//7. 转换结果
	if(i>=5)
	{
		if( AIRange != 0 )//如果为原码方式,不转换
		{
			pResultArr[i-5] = (long)changeToAIRange( result16bit, pm5320.MaxADinitCode, AIRange );
		}
		else
		{
			pResultArr[i-5] = result16bit;
		}
		tempVal = tempVal + pResultArr[i-5];//累加结果
	}

	}

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


//函数开始<5320>
long _stdcall ZT5320AIiFIFO(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型元素的缓冲区的首地址

⌨️ 快捷键说明

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