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

📄 driver.cpp

📁 这是在windows环境下用VC开发的MCX运动控制芯片的演示程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
//
//	GD102 DOS驱动程序V1.0
//							Writer: hehang
//									2003.3.28
//////////////////////////////////////////////////////////////////////

#include "driver.h"

static REGISTER Reg;		// Reg记录WR1-WR5寄存器的值
static DRVLIST	DrvList;	// DrvList记录各轴SV,V,A,D,P,DP,C
static SYSLIST  SysList;	// SysList记录各轴M,AO,R,K,CP,CM
static CSVLIST	CsvList;	// CsvList记录各轴当前状态EP,LP,V,A

static void interrupt (*OldInt)(...);	// 旧中断向量
static int IntMask;						// 初始中断字
static unsigned int base_adr;			// 用户设置板卡基地址
static unsigned int irq_adr;			// 用户设置板卡中断地址

// 初始化板卡
void InitialBoard(unsigned int adr)
{
	base_adr = adr;
	Reset();				// Reset IC
	InitialAllData();
	UpdateSysData();
	UpdateDrvData();
}

// 初始化所有驱动参数
void InitialAllData()
{
	for (int i = 0; i < AXIS_NUM; i++)
	{
		SysList.m[i] = 1;
		SysList.ao[i] = 8;		// default = 8
		SysList.r[i] = 8000000;
		SysList.k[i] = 1000;
		SysList.cp[i] = 500000000;
		SysList.cm[i] = -500000000;

		DrvList.sv[i] = 1000;	// ADD:
		DrvList.v[i] = 1000;
		DrvList.a[i] = 100;
		DrvList.d[i] = 100;
		DrvList.p[i] = 0;
		DrvList.dp[i] = 0;
		DrvList.c[i] = 0;
	}
}

// 更新系统数据
void UpdateSysData(short axis)
{
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
		{
			if (fabs(R_MAX / SysList.m[i] - SysList.r[i]) > 0.01)
			{
				SetError();
				return;			// ADD:
			}
			SetR(1 << i, SysList.r[i]);
			SetK(1 << i, SysList.k[i]);
			SetAO(1 << i, SysList.ao[i]);
			SetCP(1 << i, SysList.cp[i]);
			SetCM(1 << i, SysList.cm[i]);
		}
	}
}	

// 更新驱动数据
void UpdateDrvData(short axis)
{
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
		{
			SetSV(1 << i, DrvList.sv[i]);
			SetV(1 << i, DrvList.v[i]);
			SetA(1 << i, DrvList.a[i]);
			SetD(1 << i, DrvList.d[i]);
			SetP(1 << i, DrvList.p[i]);
			SetDP(1 << i, DrvList.dp[i]);
			SetC(1 << i, DrvList.c[i]);
		}
	}
}

// 通用命令输出
void Command(short axis, unsigned int cmd)
{
	_OUTW(WR0, (axis << 8) | cmd);	// 向WR0写命令
}

// MCX312复位重置
void Reset()
{
	_OUTW(WR0, 0x8000);			// IC复位
	SetWR3(AXIS_XY, 0);			// I/O复位
	SetLP(AXIS_XY, 0);			// 逻辑位置清零
	SetEP(AXIS_XY, 0);			// 实际位置清零
}

// 急停
void Stop(int mode)
{
	if (mode == 0)
	{
		Command(AXIS_XY, STOP_I);	// 立即停止
	}
	else
	{
		Command(AXIS_XY, STOP_D);	// 减速停止
	}
}

// 退出系统的处理(如复位,错误存盘)
void ExitSystem()
{
	// ADD:
}

// 错误处理函数
void SetError()
{
	// ADD:
}

// 获得最近的错识码
int GetError()
{
	// ADD:
	return 0;
}

// 设置倍率
void SetM(short axis, float fdata)
{
	if (fdata < M_MIN)
	{
		SetError();
		fdata = M_MIN;
	}
	else if (fdata > M_MAX)
	{
		SetError();
		fdata = M_MAX;
	}
	long dwdata = long(R_MAX / fdata);
	SetWR67(dwdata);
	_OUTW(WR0, (axis << 8) | SET_R);

	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
		{
			SysList.r[i] = dwdata;
			SysList.m[i] = fdata;
		}
	}
}

// 设置范围
void SetR(short axis, long dwdata)
{
	if (dwdata > R_MAX)
	{
		SetError();
		dwdata = R_MAX;
	}
	else if (dwdata < R_MIN)
	{
		SetError();
		dwdata = R_MIN;
	}

	SetWR67(dwdata);
	_OUTW(WR0, (axis << 8) | SET_R);

	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
		{
			SysList.r[i] = dwdata;
			SysList.m[i] = float(R_MAX) / float(dwdata);
		}
	}
}

// 设置加加速
void SetK(short axis, unsigned int wdata)
{
	if (wdata < A_MIN)
	{
		SetError();
		wdata = A_MIN;
	}
	_OUTW(WR6, wdata);
	_OUTW(WR0, (axis << 8) | SET_K);
	
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			SysList.k[i] = wdata;
	}
}

// 设置加速度
void SetA(short axis, int wdata)
{
	if (wdata > A_MAX)
	{
		SetError();
		wdata = A_MAX;
	}
	else if (wdata < A_MIN)
	{
		SetError();
		wdata = A_MIN;
	}
	_OUTW(WR6, wdata);
	_OUTW(WR0, (axis << 8) | SET_A);

	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			DrvList.a[i] = wdata;
	}
}

// 设置减速度
void SetD(short axis, int wdata)
{
	if (wdata > A_MAX)
	{
		SetError();
		wdata = A_MAX;	
	}
	else if (wdata < A_MIN)
	{
		SetError();
		wdata = A_MIN;
	}
	_OUTW(WR6, wdata);
	_OUTW(WR0, (axis << 8) | SET_D);

	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			DrvList.d[i] = wdata;
	}
}

// 设置初始速度
void SetSV(short axis, int wdata)
{
	if (wdata > V_MAX)
	{
		SetError();
		wdata = V_MAX;
	}
	else if (wdata < V_MIN)
	{
		SetError();
		wdata = V_MIN;
	}
	_OUTW(WR6, wdata);
	_OUTW(WR0, (axis << 8) | SET_SV);

	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			DrvList.sv[i] = wdata;
	}
}

// 设置驱动速度
void SetV(short axis, int wdata)
{
	if (wdata > V_MAX)
	{
		SetError();
		wdata = V_MAX;
	}
	else if (wdata < V_MIN)
	{
		SetError();
		wdata = V_MIN;
	}
	_OUTW(WR6, wdata);
	_OUTW(WR0, (axis << 8) | SET_V);
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			DrvList.v[i] = wdata;
	}
}

// 设置输出脉冲数
void SetP(short axis, long dwdata)
{
	SetWR67(dwdata);
	_OUTW(WR0, (axis << 8) | SET_P);
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			DrvList.p[i] = dwdata;
	}
}

// 设置手动减速点
void SetDP(short axis, long dwdata)
{
	SetWR67(dwdata);
	_OUTW(WR0, (axis << 8) | SET_DP);
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			DrvList.dp[i] = dwdata;
	}
}

// 设置圆心脉冲数
void SetC(short axis, long dwdata)
{
	SetWR67(dwdata);
	_OUTW(WR0, (axis << 8) | SET_C);
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			DrvList.c[i] = dwdata;
	}
}

// 设置逻辑计数器
void SetLP(short axis, long dwdata)
{
	SetWR67(dwdata);
	_OUTW(WR0, (axis << 8) | SET_LP);
}

// 设置实位计数器
void SetEP(short axis, long dwdata)
{
	SetWR67(dwdata);
	_OUTW(WR0, (axis << 8) | SET_EP);
}

// 设置正向比较寄存器
void SetCP(short axis, long dwdata)
{
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if ((1 << i) & axis)
		{
			SetWR2(1 << i, Reg.wr2[i] | 0x1);	// 使能软件正限位
			SysList.cp[i] = dwdata;
		}
	}
	SetWR67(dwdata);
	_OUTW(WR0, (axis << 8) | SET_CP);
}

// 设置负向比较寄存器
void SetCM(short axis, long dwdata)
{
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if ((1 << i) & axis)
		{
			SetWR2(1 << i, Reg.wr2[i] | 0x2);	// 使能软件负限位
			SysList.cm[i] = dwdata;
		}
	}
	SetWR67(dwdata);
	_OUTW(WR0, (axis << 8) | SET_CM);
}

// 设置加速计数器偏移量
void SetAO(short axis, int wdata)
{
	_OUTW(WR6, wdata);
	_OUTW(WR0, (axis << 8) | SET_AO);
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			SysList.ao[i] = wdata;
	}
}

// 读逻辑计数器
long ReadLP(short axis)
{
	long dl6, dh6, dl7, dh7, ret;
	_OUTW(WR0, (axis << 8) | READ_LP);

	dl6 = inportb(base_adr + RR6);
	dh6 = inportb(base_adr + RR6 + 1);
	dl7 = inportb(base_adr + RR7);
	dh7 = inportb(base_adr + RR7 + 1);
	ret = dl6 + (dh6 << 8) + (dl7 << 16) + (dh7 << 24);
	return ret;
}

// 读实位计数器
long ReadEP(short axis)
{
	long dl6, dh6, dl7, dh7, ret;
	_OUTW(WR0, (axis << 8) | READ_EP);

	dl6 = inportb(base_adr + RR6);
	dh6 = inportb(base_adr + RR6 + 1);
	dl7 = inportb(base_adr + RR7);
	dh7 = inportb(base_adr + RR7 + 1);
	ret = dl6 + (dh6 << 8) + (dl7 << 16) + (dh7 << 24);
	return ret;
}

// 读当前驱动速度
int ReadCV(short axis)
{
	int d6;
	_OUTW(WR0, (axis << 8) | READ_CV);
	d6 = _INW(RR6);
	return d6;
}

// 读当前加速度
int ReadCA(short axis)
{
	int d6;
	_OUTW(WR0, (axis << 8) | READ_CA);
	d6 = _INW(RR6);
	return d6;
}

/////////////////////////////////////////////////////////////////////
//
// 8位数据线读写端口
void _OUTW(unsigned int adr, unsigned int wdata)
{
	adr += base_adr;
	outportb(adr + 1, (wdata >> 8) & 0xff);
	outportb(adr, wdata & 0xff);
}

unsigned int _INW(unsigned int adr)
{
	unsigned int ldata, hdata;
	adr += base_adr;
	ldata = inportb(adr);
	hdata = inportb(adr + 1);
	return ((hdata << 8) + ldata);
}

// 写寄存器WR1-WR5,WR67
void SetWR1(short axis, unsigned int wdata)
{
	_OUTW(WR0, (axis << 8) | SET_NOP);	// WR1-3必须选择轴
	_OUTW(WR1, wdata);
	for (int i = 0; i < AXIS_NUM; i++)
	{
		if (axis & (1 << i))
			Reg.wr1[i] = wdata;
	}
}

void SetWR2(short axis, unsigned int wdata)
{
	_OUTW(WR0, (axis << 8) | SET_NOP);	// WR1-3必须选择轴
	_OUTW(WR2, wdata);

⌨️ 快捷键说明

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