📄 2005912.c
字号:
/********************************************************************************************************
创建人: 电子竞赛第五组成员
创建日期: 2005-09-10
创建地点: 西安
修改人: 电子竞赛第五组成员
修改日期: 2005-09-10
修改地点: 西安
功能描述: 运用数控机床上的逐点比较插补算法来实现悬挂物体控制系统的画图要求,
编程语言: c51
编译软件 keil
*******************************************************************************************************/
#include<reg51.h>
#include<math.h>
#include <intrins.h>
#define DataPort P1
#define busy 0x80
#define uchar unsigned char
#define uint unsigned int
unsigned char command,DRAM;
unsigned char count=0,sec=0; //秒计数器初始化
sbit RS=P3^6;
sbit RW=P3^7;
sbit E=P3^0;
void LCD_busy();
void LCDInt();
void LCDclr();
void xshuzi();
void yshuzi();
void banjing();
void caidan();
long long_yuanz(x,y);
long long_yuanf(x,y);
unsigned char kbscan(); //键盘
unsigned char key,i;
unsigned char xy[3];
void yshuzi();
void xshuzi();
void banjing();
void zhixianhs();
void yuanhs();
void LCDcom(unsigned char command);
void LCD_L1(unsigned char *pTable); //lcd
void LCD_L2(unsigned char *pTable);
void LCD_DW(unsigned char DRAM);
unsigned char code plus1[8] = { 0x0c, 0x06, 0x03, 0x09};
unsigned char code minu1[8] = { 0x09, 0x03, 0x06, 0x0c};
unsigned char code plus2[8] = { 0xc0, 0x60, 0x30, 0x90 };
unsigned char code minu2[8] = { 0x90, 0x30, 0x60, 0xc0 };
uchar idata TabXY[16]={
0x20,0x20,0x20,0x58,0x3A,0x20,0x20,0x20,0X20,0X20,0x59,0x3A,0x20,0x20,0x20,0x20
}; //lcd显示缓冲数组
uchar idata TabVR[16]={
0x20,0x20,0x20,0x54,0x49,0x4D,0x45,0x3A,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0X20
};
uchar code tab[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //lcd显示查表程序
uint n1,n2,x=0,y=0,k1; //n1 n2为第一 第二电机的所需转数,
bit cf1=0,cf2=0; //cf1,cf2为各个电机正反转的标志位
double h=1000,l=1060;
double f,z,f0,z0;
void delay(unsigned int x);
void contrl_1(bit cf, uint n);
void contrl_2(bit cf, uint n);
double long_z(x,y);
double long_f(x,y);
uint aa,bb,cc,x0,y0,r0,k=0x00; //k为线和园的区分标志
/************************************主函数*******************************************************************/
main(){
TMOD=0X11; //选择定时器0方式1
TH0=0x3c; //定时器置初值,定时50ms
TL0=0xb0;
TH1=0x3c;
TL1=0xb0;
TR1=1;
TR0=1; //启动定时器T0 暂时停止记时,开始画图的时候开始记数
ET0=0;
ET1=1;
PT1=1; //开定时器TO中断
EA=1; //开CPU中断
LCDInt();
LCDclr(); //lcd 初始化
/*********************************************************键盘值*****************************************/
while(1){
key=kbscan();
switch(key){
case 0x11:
//1
xy[i]=0x31;
TabXY[i]=0x31;
i++;
if(i==3)i=0;
break;
case 0x21:
xy[i]=0x32;
TabXY[i]=0x32;
i++; //2
if(i==3)i=0;
break;
case 0x41:
xy[i]=0x33;
TabXY[i]=0x33;
xy[i]=0x33;
i++; //3
if(i==3)i=0;
break;
case 0x81:
xy[i]=0x34;
TabXY[i]=0x34;
xy[i]=0x34;
i++;
if(i==3)i=0;
//4
break;
case 0x22:
xy[i]=0x35;
TabXY[i]=0x35;
xy[i]=0x35;
i++; //5
if(i==3)i=0;
break;
case 0x12:
xy[i]=0x36;
TabXY[i]=0x36;
//6
xy[i]=0x36;
i++;
if(i==3)i=0;
break;
case 0x42:
xy[i]=0x37;
TabXY[i]=0x37;
xy[i]=0x37;
i++; //7
if(i==3)i=0;
i++;
break;
case 0x82:
xy[i]=0x38;
TabXY[i]=0x38;
xy[i]=0x38;
i++;
if(i==3)i=0; //8
break;
case 0x14:
xy[i]=0x39;
TabXY[i]=0x39;
xy[i]=0x39;
i++; //9
if(i==3)i=0;
break;
case 0x24:
xy[i]=0x30;
TabXY[i]=0x30; //0
xy[i]=0x30;
i++;
if(i==3)i=0;
break;
case 0x44:
xshuzi();
break; //x
case 0x84:
yshuzi();
break; //y
case 0x18:
banjing();
break; //r
case 0x28:
case 0x48: ET0=1; zhixianhs();
//确认键
break;
case 0x88: ET0=1; yuanhs(); break;
}
}
}
/***********************************************键盘*********************************************/
void zhixianhs(){
double a ;
int m;
//为画直线标志
f0=1166.609; // sqrt((124*124)+(h+160)*(h+160));
x=0;y=0; //键盘输入数据
z0=1490.536; // sqrt((h+160)*(h+160)+(l-124)*(l-124));
while(y<y0&&x<x0)
{
m=(x0*y)-(y0*x); //直线
if(m>0)
{x++; m=m-y0; }
else if(m<0)
{ y++;m=m+x0;}
else
{ if(fabs(m-y0)<fabs(m+x0))
a=fabs(m-y0);
// a=(m-300)<(m+200)?(m-300):(m+200
else
a=fabs(m+x0);
if(a>=fabs(m+x0-y0))
{y++;x++;}
else
{ if(fabs(m-y0)<fabs(m+x0)) x++;
else y++;}
}
f=long_f(x,y);
if(f0<f)
{ cf1=0; n1=(f-f0)*5;}
else
{ cf1=1; n1=(f0-f)*5;}
f0=f;
contrl_1(cf1,n1); //
z=long_z(x,y);
if(z0 <z)
{ cf2=1; n2=(z-z0)*5;}
else
{ cf2=0; n2=(z0-z)*5;}
z0=z;
contrl_2(cf2,n2);
}
ET0=0;
}
/********************************延时函数********************************************************************/
void delay(unsigned int x)
{
unsigned int m,j;
for( m =0;m < x;m++ )
{
for( j =0;j<3;j++ );
}
}
/***********************************左边电机控制****************************************************************/
void contrl_1(bit cf,uint n)
{ uint m ;
//方向和圈数
if(cf==1){ for(m=0;m<n;m++)
{
P2=plus1[m%4];
delay(160); //逆时针
P2=0x00;
}
}
else { for(m=0;m<n;m++)
{ //顺时针
P2=minu1[m%4];
delay(160);
P2=0x00;
}
}
}
/*******************************************右边电机控制*****************************************************************/
void contrl_2(bit cf,uint n)
{ uint m;
//方向和圈数
if(cf==0){ for(m=0;m<n;m++)
{
P2=plus2[m%4];
delay(60);
P2=0x00;
}
}
else { for(m=0;m<n;m++)
{ P2=minu2[m%4];
delay(60);
P2=0x00;
}
}
}
/*****************************************************求z的长度**************************************/
double long_z(x,y)
{
double a2, a3,a4,a5;
a2=( double)((l-x-124)*(l-x-124));
a3=( double)((h+160-y)*(h+160-y));
a4= a2+a3;
a5=sqrt(a4); //求出z的长度, 开方,
return(a5);
}
/*************************************求f的长度***************************************************************/
double long_f(x,y)
{
double u2,a5,a6,v ;
a5=( double)(h-y+160)*(h+160-y);
a6=( double)(x+124)*(x+124);
u2=(a5+a6);
v=sqrt(u2);
return(v);
}
/*********************************************lcd写数据*************************************************************/
void LCD_DW(unsigned char DRAM)
{
LCD_busy();
RS=1;
RW=0;
DataPort=DRAM; //DRAM=DDRAM ADDRESS
E=1;
_nop_();
E=0;
return;
}
/*************************************************lcd第二行***************************************/
void LCD_L2(unsigned char *pTable)
{
unsigned int j;
LCDcom(0xC0);
for(j=0;j<16;j++)
{
DRAM=*pTable;
LCD_DW(DRAM);
pTable++;
}
return;
}
/***********************************************************lcd第一行的显示*******************************/
void LCD_L1(unsigned char *pTable)
{
unsigned int j;
LCDcom(0x80);
for(j=0;j<16;j++)
{
DRAM=*pTable;
LCD_DW(DRAM);
pTable++;
}
return;
}
/*******************************************lcd忙信号***************************************************/
void LCD_busy()
{
E=0;
RS=0;
RW=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -