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

📄 pm5320.cpp

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

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


//结构信息开始<5320>
//#define PM5320_SPECIAL
struct PM518_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路
//电子所的
//	unsigned short DZS_CardManorVer;//5320
//	unsigned char DZS_CardMinorVer; //' '

//	unsigned short DZS_MaxADinitCode;//65535(16位卡最大原码为65535)
//	unsigned char DZS_MaxAISingleChannel;//8(0--7)共8路,无双通道方式
//	unsigned short DZS_MaxDAinitCode;//4095(12位卡最大原码为4095)
//	unsigned char DZS_MaxAOChannel;      //16(0--15)共16路
//PM518的
	unsigned short PM518_CardManorVer;//518
	unsigned char PM518_CardMinorVer; //' '

	unsigned short PM518_MaxADinitCode;//65535(16位卡最大原码为65535)
	unsigned char PM518_MaxAISingleChannel;//32(0--31)共32路,无双通道方式
	unsigned short PM518_MaxDAinitCode;//4095(12位卡最大原码为4095)
	unsigned char PM518_MaxAOChannel;      //8(0--7)共8路

//////////////////////PM518的DIO//////////////////////////////////
//卡型号
//	unsigned short PM518_CardManorVer;//'PM518'
//	unsigned char PM518_CardMinorVer; //' '
//用于参数检查的值
	unsigned char PM518_MaxIOChannel;  //7(0--7)共8路,每组8个通道
	unsigned char PM518_MaxIOGroup;   //2(0--2)共3组
//其他寄存器
	unsigned char PM518_ROff_IOMode; //15
//DI、DO相关信息
	unsigned char PM518_ROff_DIOGroup[3];//0xC-0xE(读,读I/O 输入数据)
///////////////////////////////////////////////////////////////////

//AD相关信息,本卡是一个AIW型的卡
	PM518_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

//////////////////电子所的AD/////////////////////
	//unsigned char DZS_ROff_ADctrlReg;	  //10
	//unsigned char DZS_ROff_ADchannel;   //0(写,写通道代码,选通道)
	//unsigned char DZS_ROff_ADstart;     //0(启动A/D转换)
	//bool DZS_ADWriteStart;              //false(默认为写启动,5320为读启动)
	//unsigned char DZS_ROff_ADresultWord;//2(读,读12位或16位A/D转换结果)
	//unsigned short DZS_ADresultMask;      //0xFFFF(16位结果)
	//unsigned long DZS_ADJumpChannelTime;//0(默认),AD通道切换时间,替代原ADcha

///////////////////PM518的AD//////////////////////////
	//unsigned char PM518_ROff_ADfreqReg; //1(写,写入AD定时启动分频系数0-255)
	//unsigned char PM518_ROff_ADctrlReg;	//10
	//unsigned char PM518_ROff_ClearFIFO;   //1(写,清空FIFO,同时清空AD控制寄存器)
	//unsigned char PM518_ROff_FIFOstatus;	//10
	//unsigned char PM518_ROff_ADchannel;   //0(写,写通道代码,选通道)
	//unsigned char PM518_ROff_ADstart;     //0(启动A/D转换)
	//bool PM518_ADWriteStart;              //false(默认为写启动,5320为读启动)
	//unsigned char PM518_ROff_ADresultWord;//2(读,读12位或16位A/D转换结果)
	//unsigned short PM518_ADresultMask;      //0xFFFF(16位结果)
	//unsigned long PM518_ADJumpChannelTime;//0(默认),AD通道切换时间,替代原ADcha

	char AIRangeArr[7];//模拟量输入范围
//DA相关信息,本卡是一个AO48型的卡
	PM518_AO_W AOW;//是一个结构
	//unsigned char ROff_DAchannel;//0x4(写,写通道代码,选通道)
	//unsigned char ROff_DAWord;//0x6(写,写16位D/A数据)
	//unsigned short DAWordMask;//0x0FFF可能需要屏蔽掉一些位

	//////////////////电子所的DA/////////////////////
	//unsigned char DZS_ROff_DAchannel;//0x6(写,写通道代码,选通道)
	//unsigned char DZS_ROff_DAWord;//0x8(写,写16位D/A数据)
	//unsigned short DZS_DAWordMask;//0x0FFF可能需要屏蔽掉一些位

	//////////////////PM518的DA/////////////////////
	//unsigned char PM518_ROff_DAchannel;//0x6(写,写通道代码,选通道)
	//unsigned char PM518_ROff_DAWord;//0x8(写,写16位D/A数据)
	//unsigned short PM518_DAWordMask;//0x0FFF可能需要屏蔽掉一些位

	char AORangeArr[11];//模拟量输出范围

///////////////DZS电位器//////////////////////////////
//	PM5320_DWQ DWQ;
	//unsigned char DZS_DWQctrlReg;//0X4
	//unsigned long DZS_DWQfull;//0x0
	//unsigned long DZS_DWQzero;//0x1000
	//unsigned char DZS_W;//5
	//unsigned char DZS_MASK;//0xfff

///////////////PM518////////////////////////////////
	PM518_DWQ PM518_DWQ;
	//unsigned char pm518_DWQctrlReg;//0X4
	//unsigned long pm518_DWQfull;//0x0
	//unsigned long pm518_DWQzero;//0x1000
	//unsigned char pm518_W;//4
	//unsigned char pm518_MASK;//0xfff
};
PM518_INFO pm518 = {518,' ',65535,31,4095,7,\
					  7,2,\
					  15,\
					{12,13,14},\
12,8,0,0,false,2,8,0x8000,0x8000,2,0xFFFF,0,\
/*10,0,0,false,2,0xffff,0,\*/
1,10,1,10,0,0,false,2,0xffff,0,\
{0,1,2,-3,-4,5,-6},\
/*0x4,0x6,0x0FFF,\
0x6,0x8,0x0FFF,\*/
0x6,0x8,0x0FFF,\
{0,1,-2,-3,-4,-5,-6,-7,-8,-9,-10},\
/*0x4,0x0,0x1000,0x5,0xfff,\*/
0x4,0x0,0x1000,0x4,0xfff};
//结构信息结束</5320>

long DAout[4];
//int AIT;	//一个单位是4095数,用fifo半满信号实现

//函数开始<5320>

//////////////////PM518的//////////////////////////////

//////////////////以下是ADDA的//////////////////////////

long _stdcall ZT_PM518SetADfreq(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, pm518.AIW.PM518_ROff_ADfreqReg, ADfreq);
	return ZT_SUCCESS;
}

//////////////////////////新函数:前16通道增益设定///////////////////////////////////

long _stdcall ZT_PM518_inc(unsigned long nAddr,\
						   int chA[8],\
						   int chB[8])
{	
	nAddr = CheckAddr(nAddr);
	int i;
	unsigned long valueA=0,valueB=0;

	for(i=0;i<8;i++){
	chA[i]&=0x3;
	chB[i]&=0x3;
	valueA=(valueA|(chA[i]<<(i*2)))&0xffff;
	valueB=(valueB|(chB[i]<<(i*2)))&0xffff;
	}
	WriteW(nAddr,0x4,valueA);
	WriteW(nAddr,0x6,valueB);

	return ZT_SUCCESS;
}

/////////////////////////////////////////////////////////////

long _stdcall ZT_PM518_AISingle(unsigned long nAddr,\
								unsigned long nCh,\
								unsigned long AIRange,\
								unsigned long AIInc,\
								unsigned long nCount,\
								unsigned long ADOverTime)
//新版518 后16路的增益设定
{	
	//unsigned short ctrlreg=ReadW(nAddr,pm518.AIW.PM518_ROff_ADctrlReg)&0xfff;
	unsigned short ctrlreg=0;
	int zengyi=((AIInc&0x3)<<8)&0x300;
	ctrlreg=ctrlreg|zengyi;

	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);
	//写控制字软件启动
	WriteW( nAddr, pm518.AIW.PM518_ROff_ADctrlReg, ctrlreg);
//	WriteW( nAddr, pm518.AIW.PM518_ROff_ADchannel, 0);

//	ReadW(nAddr, pm5320.AIW.DZS_ROff_ADctrlReg);
	//要先设置AD通道,再设置AD控制寄存器
	WriteW( nAddr, pm518.AIW.PM518_ROff_ADchannel, nCh);

//	WriteW( nAddr, pm518.AIW.PM518_ROff_ADctrlReg, ctrlreg);

	double tempVal = 0;//设为double型,防止溢出
	for(unsigned long i=0; i<nCount; i++)
	{
	//软件启动AD,每次都要启动
	ReadW( nAddr, pm518.AIW.PM518_ROff_ADstart );
	//判断AD状态
	DWORD startTime,endTime;
	if( ADOverTime != 0 ) startTime=GetTickCount();//记录开始时间
	//需要防止死机,因为用户可能输入错误的IO地址,导致AD永远不能进行
	while( (ReadW(nAddr,pm518.AIW.PM518_ROff_ADctrlReg) & 0x8000))//查询AD状态
	{
		if( ADOverTime != 0 )
		{
			endTime = GetTickCount();
			if( endTime - startTime >= ADOverTime )//大于60ms比较保险,GetTickCount()只精确到55ms
			{
				m_errorLevel = ERR_AD_OVERTIME;//AD超时错
				return -1;//如果超过60ms秒以上就退出
			}
		}
	}
	//读AD结果,字读操作
	unsigned short result16bit;
	result16bit = ReadW(nAddr,pm518.AIW.PM518_ROff_ADresultWord);
	//转换范围
	if( AIRange != 0 )//如果为原码方式,不转换
		{
		result16bit = (unsigned short)changeToAIRange( result16bit, pm518.PM518_MaxADinitCode, AIRange );		
		tempVal = tempVal + result16bit;//累加结果
		}
	else
		tempVal = tempVal + result16bit;//累加结果
	}
	return (long)(tempVal/nCount);	
//	return ctrlreg;	
}


long _stdcall ZT_PM518_DWQ(	unsigned long nAddr,\
							unsigned long fValue,\
							unsigned long zValue)
{
//	int i;
//	nAddr = CheckAddr(nAddr);
//	if(m_errorLevel != ZT_SUCCESS) return -1;
//	
//	WriteW(nAddr, pm518.PM518_DWQ.PM518_DWQctrlReg,(pm518.PM518_DWQ.PM518_DWQzero+(zValue&pm518.PM518_DWQ.PM518_MASK)));
//	for(i=0;i<9;i++)
//	ReadW(nAddr, pm518.PM518_DWQ.PM518_W);
//
//	WriteW(nAddr, pm518.PM518_DWQ.PM518_DWQctrlReg,(fValue&pm518.PM518_DWQ.PM518_MASK));
//	for(i=0;i<9;i++)
//	ReadW(nAddr, pm518.PM518_DWQ.PM518_W);
	int i=0,j=0;
	zValue|=0x100;
//	outportb(base+8,0);
	WriteW( nAddr, 8, 0);
	for(i=10;i>-1;i--){
		long d8402=(zValue>>i)&1;
		long d8403=(fValue>>i)&1;
//		outportb(base+8,d8402);
		WriteW( nAddr, 8, d8402);
		WriteW( nAddr, 8, d8403);
		for(j=0;j<10;j++)
			ReadW(nAddr,0x20);
//		delaytimes(10);
		d8402|=2;
		//d8403|=2;
//		outportb(base+8,d8402);
		WriteW( nAddr, 8, d8402);
		WriteW( nAddr, 8, d8403);
		for(j=0;j<10;j++)
			ReadW(nAddr,0x20);
//		delaytimes(10);
	}
//	outportb(base+8,0);
//	outportb(base+8,4);
	WriteW( nAddr, 8, 0);
	WriteW( nAddr, 8, 4);

	return ZT_SUCCESS;
}

long _stdcall ZT_PM518_AOSingle(unsigned long nAddr,\
								unsigned long nCh,\
								long nValue,\
								unsigned long AORange)
{	
	int i=0,ov=0;
	//检查参数
//	nAddr = CheckAddr(nAddr);//使地址在0x100--0x3F0之间
	nCh = nCh - m_nCountFrom;
	if( nCh > pm518.PM518_MaxAOChannel ) m_errorLevel = ERR_PARAMETER_CH;

	if( AORange > MAX_AO_RANGE || pm518.AORangeArr[AORange] < 0 ) m_errorLevel = ERR_PARAMETER_AO_RANGE;

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

	unsigned long AOInitCode;
	AOInitCode = getAOInitCode(nValue, pm518.PM518_MaxDAinitCode, AORange);

	DAout[nCh]=AOInitCode;
	nValue&=0xfff;
	nValue|=(nCh<<14);
	if(nCh<4){
/*将DAC7625的LREG置高,CLK和CS置低*/

⌨️ 快捷键说明

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