#include<reg51.h>
#include<math.h>
#define ulong unsigned long
sbit Xdr=P0^1;
sbit Xpu=P0^0;
sbit Ydr=P0^3;
sbit Ypu=P0^2;
sbit Xkey=P3^3;
sbit Xchange=P3^2;
sbit Ykey=P3^1;
sbit Ychange=P3^0;
sbit key=P3^5; //定义启动开关位
sbit RELAY = P3^4; //定义继电器控制位
void delay(int a) //延时
{
int i;
for(i=a;i>0;i--);
}
void taibi() //抬笔
{
delay(1000);
RELAY=1;
delay(1000);
}
void xiabi() //下笔
{
delay(1000);
RELAY=0;
delay(1000);
}
void line(float x,float y,char n) //直线插补子程序,n为象限
{
ulong xe,ye,and;
long f;
Xpu=0;
Ypu=0;
xe=8*x; //坐标与脉冲数转换
ye=8*y;
and=xe+ye; //计算总脉冲数
f=0; //原始偏差
switch(n) //判断象限
{
case 1: //第一象限
{
Xdr=1; //+X
Ydr=1; //+Y
break;
}
case 2: //第二象限
{
Xdr=0;
Ydr=1;
break;
}
case 3: //第三象限
{
Xdr=0;
Ydr=0;
break;
}
case 4: //第四象限
{
Xdr=1;
Ydr=0;
break;
}
}
while(and>0) //发脉冲、计算偏差,下降沿有效
{
if(f>=0) //X轴动一步
{
Xpu=1;
delay(2);
Xpu=0;
delay(5);
f=f-ye; //计算新偏差
}
else //Y轴动一步
{
Ypu=1;
delay(2);
Ypu=0;
delay(5);
f=f+xe;
}
and=and-1; //终点判别
}
}
void arc(float x0,float y0,float x,float y,char n,char r) //圆弧插补子程序 n为象限 r为顺逆
{
ulong xm,ym,and;
long f;
float c,d;
xm=8*x0;
ym=8*y0;
c=x-x0;
if(c<0)
{
c=-c;
}
d=y-y0;
if(d<0)
{
d=-d;
}
and=(c+d)*8; //总脉冲数
f=0; //原始偏差
Xpu=0;
Ypu=0;
if(((r=='s')&&((n==1)||(n==3)))||((r=='n')&&((n==2)||(n==4))))//一三象限顺圆,二四象限逆圆
{
switch(n) //根据象限确定XY轴进给方向
{
case 1: //第一象限顺圆 +X -Y
{
Xdr=1;
Ydr=0;
break;
}
case 2: //第二象限逆圆 -X -Y
{
Xdr=0;
Ydr=0;
break;
}
case 3: //第三象限顺圆 -X +Y
{
Xdr=0;
Ydr=1;
break;
}
case 4: //第四象限逆圆 +X +Y
{
Xdr=1;
Ydr=1;
break;
}
}
while(and>0) //坐标进给
{
if(f>=0) //在圆外面Y轴走一步
{
Ypu=1;
delay(2);
Ypu=0;
delay(5);
f=f-2*ym+1; //新偏差计算
ym=ym-1;
}
else //在圆里面X轴走一步
{
Xpu=1;
delay(2);
Xpu=0;
delay(5);
f=f+2*xm+1;
xm=xm+1;
}
and=and-1; //终点判别
}
}
else //一三象限逆圆,二四象限顺圆
{
switch(n) //根据象限确定进给方向
{
case 1:
{
Xdr=0;
Ydr=1;
break;
}
case 2:
{
Xdr=1;
Ydr=1;
break;
}
case 3:
{
Xdr=1;
Ydr=0;
break;
}
case 4:
{
Xdr=0;
Ydr=0;
break;
}
}
while(and>0)
{
if(f>=0)
{
Xpu=1;
delay(2);
Xpu=0;
delay(5);
f=f-2*xm+1;
xm=xm-1;
}
else
{
Ypu=1;
delay(2);
Ypu=0;
delay(5);
f=f+2*ym+1;
ym=ym+1;
}
and=and-1;
}
}
}
void main() //主函数
{
Xdr=1;
Xpu=0;
Ydr=0;
Ypu=0;
RELAY=0;
while(1)
{
if(key==0)
{
delay(10000);
xiabi();
arc(0,375,375,0,4,'n'); //以O为原点绘制圆弧AA1
arc(375,0,0,375,1,'n'); //以O为圆点绘制圆弧A1B
arc(0,8843,3550,8066,3,'s'); //以01为原点绘制圆弧BC
line(81,927,2); //以C为原点绘制直线CD
arc(377,318,494,0,4,'n'); //以O2为原点绘制圆弧DD1
arc(494,0,0,494,1,'n'); //以O2为原点绘制圆弧D1D2
arc(0,494,494,0,2,'n'); //以O2为原点绘制圆弧D2D3
arc(494,0,375,321,3,'n'); //以O2为原点绘制圆弧D3E
line(62,718,4); //以E为原点绘制直线EF
arc(569,2691,2614,855,3,'s'); //以O3为原点绘制圆弧FG
arc(50,835,836,0,4,'n'); //以O4为原点绘制圆弧GG1
arc(836,0,0,836,1,'n'); //以O4为原点绘制圆弧G1G2
arc(0,836,836,0,2,'n'); //以O4为原点绘制圆弧G2H
arc(3500,20,459,3470,3,'n'); //以O3为原点绘制圆弧HI
arc(5170,1362,5346,0,1,'s'); //以O5为原点绘制圆弧II1
arc(5346,0,696,5300,4,'s'); //以O5为原点绘制圆弧I1J
arc(29,374,375,0,2,'n'); //以O6为原点绘制圆弧JJ1
arc(375,0,0,375,3,'n'); //以O6为原点绘制圆弧J1K
arc(724,6048,6096,0,4,'n'); //以O5为原点绘制圆弧KK1
arc(6096,0,6003,1063,1,'n'); //以O5为原点绘制圆弧K1L
arc(3376,8968,0,9593,3,'n'); //以O1为原点绘制圆弧LA
taibi(); //抬笔
if(key==0)
{
line(2211,2647,3); //以A为原点移动平台到M
}
xiabi(); //下笔
if(key==0)
{
arc(366,82,0,375,1,'n'); //以O7为原点绘制圆弧MM1
arc(0,375,375,0,2,'n'); //以O7为原点绘制圆弧M1N
arc(375,0,366,82,3,'n');
arc(4265,960,4371,0,1,'s'); //以O8为原点绘制圆弧NN1
arc(4371,0,1913,3931,4,'s'); //以O8为原点绘制圆弧N1P
arc(178,337,389,0,2,'n'); //以O9为原点绘制圆弧PP1
arc(389,0,0,389,3,'n'); //以O9为原点绘制圆弧P1P2
arc(0,389,150,337,4,'n'); //以O9为原点绘制圆弧P2Q
arc(2241,4605,5121,0,4,'n'); //以O8为原点绘制圆弧QQ1
arc(5121,0,4996,1125,1,'n'); //以O9为原点绘制圆弧Q1M
}
taibi(); //抬笔
if(key==0)
{
line(5175,2303,1); //移动平台到R
}
xiabi(); //下笔
if(key==0)
{
line(1276,3526,2); //以R为原点绘制直线RS
arc(2345,2250,0,3250,2,'s');//以O10为原点绘制圆弧SS1
arc(0,3250,2345,2250,1,'s');//以O10为原点绘制圆弧S1T
line(1276,3526,3); //以T为原点绘制直线TU
arc(235,85,0,250,4,'s'); //以O11为原点绘制圆弧UU1
arc(0,250,250,0,3,'s'); //以O11为原点绘制圆弧U1U2
arc(250,0,235,85,2,'s'); //以O11为原点绘制圆弧U2V
line(1008,2778,1); //以V为原点绘制直线VW
arc(1604,2827,0,3250,4,'s'); //以O12为原点绘制圆弧WW1
arc(0,3250,1604,2827,3,'s'); //以O12为原点绘制圆弧W1X
line(1008,2778,4); //以X为原点绘制直线XY
arc(235,85,250,0,1,'s'); //以O13为原点绘制圆弧YY1
arc(250,0,0,250,4,'s'); //以O13为原点绘制圆弧Y1Y2
arc(0,250,235,85,3,'s'); //以O13为原点绘制圆弧Y2Z
}
taibi(); //抬笔
if(key==0)
{
line(512,3526,2); //移动平台直下一起点
}
xiabi(); //下笔
if(key==0)
{
arc(1581,2250,0,2750,2,'s'); //以O10为原点绘制圆弧M1M2
arc(0,2750,1581,2250,1,'s'); //以O10为原点绘制圆弧M2N
arc(1581,2250,0,2750,4,'s'); //以O12为原点绘制圆弧N1N2
arc(0,2750,1581,2250,3,'s'); //以O12为原点绘制圆弧N2M1
}
taibi(); //抬笔
}
else
{
if(Xkey==0) //X轴方向
{
delay(1000);
if(Xkey==0)
{
Xdr=!Xdr;
while(!Xkey);
delay(1000);
}
}
if(Ykey==0) //Y轴方向
{
delay(1000);
if(Ykey==0)
{
Ydr=!Ydr;
while(!Ykey);
delay(1000);
}
}
if(Xchange==0) //X轴移动
{
delay(1000);
while(Xchange==0)
{
Xpu=1;
delay(2);
Xpu=0;
delay(5);
}
}
if(Ychange==0) //Y轴移动
{
delay(1000);
while(Ychange==0)
{
Ypu=1;
delay(2);
Ypu=0;
delay(5);
}
}
}
}
}