📄 pm5320.cpp
字号:
// ------------------------------------------------- //
// 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 + -