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

📄 14_6.c

📁 51事例原代码 事例多多 应该对初学者很有用
💻 C
字号:
//C51单片机线切割机控制程序 
//适用PHILIPS89C51RD2单片机,ROM内置、RAM外置,数码显示7位+7位共阴,键盘35只键

#include <reg51f.h>						//Philips 89C51Rx+
#include <absacc.h>
#include <math.h>

#define XYPORT XBYTE[0x8003]			//XY步进电机输出

signed long data m1 _at_ 0x10;				//加工判别函数
signed long data n1 _at_ 0x14;				//加工判别函数
union uni1
{
	signed long s;
	float f;
} freg1 _at_ 0x18,freg2 _at_ 0x1c;

bit cutting;				//正在切割某一程序段标记,=0时为切割下一段作准备
bit q;					//换象限标记

unsigned char bdata zw;	//加工指令
sbit zw_bit0=zw^0;		//=1 X-方向运动,=0 X+方向运动
sbit zw_bit1=zw^1;		//=1 Y-方向运动,=0 Y+方向运动
sbit zw_bit2=zw^2;		//=1 逆圆,=0 顺圆
sbit zw_bit3=zw^3;		//=1 直线,=0 圆
sbit zw_bit4=zw^4;		//=1 选择停标记
sbit zw_bit5=zw^5;		//=1 凹曲线,=0 凸曲线
sbit zw_bit6=zw^6;		//=1 4B格式,=0 3B格式
sbit zw_bit7=zw^7;		//=1 GX,=0 GY
unsigned char bdata zw4;//暂存加工指令


unsigned char data aa;	
unsigned char data bb;	
unsigned char data ck;	
unsigned long idata r;				//加工半径,二进制绝对值
unsigned long data j;				//加工时存放计数长度

signed long idata x0;				//加工起点,二进制
signed long idata y0;				//加工起点,二进制
signed long idata xe;				//加工终点,二进制
signed long idata ye;				//加工终点,二进制

unsigned char data ct;

unsigned char data xypnt;			//X、Y步进电机相位寄存

signed int idata dltr;				//补偿量
unsigned char xdata CUTTING_DATA[2501][13] _at_ 0x00EF;//外部RAM,存放切割程序

void error(void);					//出错,报警,返回input
void input(void);					//命令输入
void ndis(void);					//清输入所有显示位
void X_output(void);				//X 步进电机输出
void Y_output(void);				//Y 步进电机输出
void display_j(unsigned long xy);		//显示J计数
void get_cut_program(void);			//从RAM中取出切割程序整理进切割缓冲区
unsigned char chz(unsigned char c1);	//圆弧换象限
void chza(void);				//切割加工中圆弧换象限
signed long bias(signed long xy1);		//间隙补偿,偏移运算
void cut(void);					//切割主程序
unsigned char back (unsigned char s);	//步进电机环形分配器  逆时针转
unsigned char look (unsigned char s);	//步进电机环形分配器  顺时针转
void open(void);					//开脉冲源
void close(void);					//关脉冲源
void output(void);				//X、Y步进电机输出
void cutf(void);					//双向插补子程序


main()
{
SP=0xA8;
	AUXR|=0x02;			//指向外部RAM
	TMOD=0x20;			//定时器0为方式0,定时器1为方式2
	IP=0x02;			//定时器中断0为高优先级
	IT1=1;				//变频中断下降沿触发
	TL0=0x1A;TH0=0x8C;	//定时器0的时间常数(2ms,11.0592MHZ) P89C51RD2 6时钟周期
	TR0=1;				//启动定时器0
	IE=0xA3;			//开放显示中断和定时器2中断
	xypnt= 0x09;		//定相(三相六拍)
	output();
	ndis();				//清显示
	dltr=0;				//默认补偿量=0
	input();			//从键盘输入数据和命令
}

void cut(void)						//切割主程序
{
cut1:get_cut_program();				//从内存中读入程序
	if (zw_bit3==0)					//圆弧
		{						   
		ACC=zw&0x0F;pp=P;
		if (((pp==0)&&(x0==0))||((pp==1)&&(y0==0))) zw=chz(zw);//换象限
		}
	if (dltr!=0)					//间隙补偿值不为零,需要间隙补偿
		{
		if ((zw_bit3==0)&&(r<abs(dltr))&&(bbb_bias_flag==0))
//圆弧半径小于补偿量时出错
			{						//r<abs(dltr) 出错
			error();
			}
		if (zw_bit6!=0)				//直线与圆弧间隙补偿
			{
			x0=bias(x0);			//x0,y0,j,r 偏移补偿运算
		  	y0=bias(y0);
			xe=bias(xe);
			ye=bias(ye);
		  	j=bias(j);
			r=bias(r);
			}
		}
cut5:	if (zw_bit3!=0)				//直线
			{
			if (zw_bit0!=0) n1=-ye; else n1=ye;	//L2,L3 / L1,L4
			if (zw_bit1!=0) m1=xe; else m1=-xe;	//L3,L4 / L1,L2
			}
		else
			{						//圆弧,计算m1 m2 n1 n2初值
			m1=y0+y0;				//NR4,SR2,NR1,SR3
			if (zw_bit1!=0) m1=-m1;	//NR2,SR4,NR3,SR1
			m1=m1+1;
			n1=x0+x0;				//NR4,SR2,NR3,SR1
			if (zw_bit0!=0) n1=-n1;	//NR1,SR3,NR2,SR4
			n1=n1+1;
			}
		freg1.s=0;					//初始F=0
cut6:	cutf();
	display_buffer1[11]=zw&0x0F;	//显示加工指令
	display_j(j);					//显示j计数
	if (j!=0) 						//判终点
		{
cutf2:	chza();						//圆弧,判别是否换象限
		goto cut6;					//继续插补下一步
		}
	else
		{							//j=0,段号处理
		zw4=zw;						//暂存zw
		if (zw_bit7==0)				//双向终点判别,GY
			{
			while (x0!=xe)
				{
				if (x0<xe) zw&=0xFE;//x0+1-->x0
				else zw|=0x01;		//x0-1-->x0
				X_output();
				}
			}
		else
			{
			while (y0!=ye)
				{					//GX
				if (y0<ye) zw&=0xFD;//y0+1-->y0
				else zw|=0x02;		//y0-1-->y0
				Y_output();
				}
			}
		zw=zw4;	
		goto cut1;
		}
close();							//切割完,关脉冲电源
}

void cutf(void)						//八方向插补子程序
{
	open();							//开脉冲源
	freg2.s=freg1.s+m1;				//走Y后的偏差
	freg1.s=freg1.s+n1;				//走X后的偏差
	if (labs(freg1.s+freg1.s)<labs(freg2.s))
		{
		X_output();					//输出X
		if (zw_bit7!=0) j--;
		}
	else
		{
		if (labs(freg2.s+freg2.s)<labs(freg1.s))
			{
			freg1.s=freg2.s;
			Y_output();				//输出Y
			if (zw_bit7==0) j--;
			}
		else
			{
			freg1.s=freg2.s+n1;		//f=f+m1+n1
			X_output();				//输出X,Y
			Y_output();
			j--;
			}
		}
}

void X_output(void)					//X 步进电机输出
{
	unsigned char s;
	s=xypnt&0x07;					//取出x相位(三相六拍)
	if (zw_bit3==0) n1=n1+2;
	if (zw_bit0==0)
		{x0++;
		s=look(s);					//步进电机正走
		}
	else
		{x0--;
		s=back(s);					//步进电机反走
		}
	xypnt&=0xF8;					//将新的步进电机相位并入xypnt
	xypnt|=s;
	output();						//X 步进电机输出
}

void Y_output(void)					//Y 步进电机输出
{
	unsigned char s;
	s=xypnt&0x38;					//取出Y相位(三相六拍)
	s>>=3;							//(三相六拍)
	if (zw_bit3==0) m1=m1+2;
	if (zw_bit1==0)
		{
		y0++;
		s=look(s);
		}
	else
		{
		y0--;
		s=back(s);
		}
	s<<=3;
	xypnt&=0xc7;					//将新的步进电机相位并入xypnt
	xypnt|=s;	
	output();						//Y 步进电机输出
}

void get_cut_program(void)			//从RAM中取出切割程序整理进切割缓冲区
{
	unsigned char data *c1;
	void get_cut_program1(unsigned char data *c1,char s);//从RAM中取出3字节数据送进切割缓冲区
	c1=&x0;
	get_cut_program1(c1,0);			//得到x0
	c1=&y0;
	get_cut_program1(c1,3);			//得到y0
	c1=&j;
	get_cut_program1(c1,6);			//得到j
	c1=&r;
	get_cut_program1(c1,9);			//得到r
	zw=CUTTING_DATA[sech1][12];		//得到zw
}

void get_cut_program1(unsigned char data *c1,char s)	//从RAM中取出3字节数据送进切割缓冲区
{
	unsigned char i;
	*c1=0;
	for (i=0;i<=2;i++) {c1++;*c1=CUTTING_DATA[sech1][i+s];}
}

signed long  bias(signed long  m1)		//间隙补偿,偏移运算
{
	bit b=0;
	n1=abs(dltr);
	if (m1<0) {m1=abs(m1);b=1;}
	freg1.f=n1*m1;						//化为浮点数
	freg1.f=freg1.f/r;
	getfreg1();							//四舍五入
	n1=freg1.f;							//化为长整型
	if (dltr<0)
		if ((zw_bit5)!=0) m1=m1+n1;		//凹曲线
		else m1=m1-n1;					//凸曲线
	else if ((zw_bit5)!=0) m1=m1-n1;	//凹曲线
		else m1=m1+n1;					//凸曲线
	if (b!=0) m1=-m1;
return(m1);
}

unsigned char chz(unsigned char c1)		//圆弧换象限
{
	ACC=c1&0x0F;
	if (P==1) ACC^=0x01;
	else ACC^=0x02;
	c1&=0xF0;
	c1|=ACC;
return(c1);
}

void chza(void)			//切割加工中圆弧换象限
{
	if (zw_bit3==0)		//圆弧,判别是否换象限
		{
		ACC=zw&0x0F;pp=P;
		if (((pp==0)&&(x0==0))||((pp==1)&&(y0==0))) 
			{
			zw=chz(zw);	//换象限
			q=1;		//设立换象限标记
			}
		}
}

⌨️ 快捷键说明

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