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

📄 main.c

📁 使用c语言编写的单片机的应用程序
💻 C
字号:

#include <AT89X52.H>
#include <absacc.h>
#include <math.h>
#include <stdlib.h>

#define  uchar  unsigned char
#define  uint   unsigned int

#define Ram XBYTE[0x2000]
#define Rom XBYTE[0x4000]
//画线****************************
#define zheng 1   //收缩
#define fan 0     //释放
#define one_step 0.010
#define time_count 20000 //定时常数
//*****************************
extern void delay(uint dtime);

/*串口操作 *************************                  ******************************/
extern char getbyte(void);				//从接收缓冲区取一个byte,如不想等待则在调用前检测inbufsign是否为1。
extern putbyte(char c);					//放入一个字节到发送缓冲区
extern putstring(uchar  *puts);			//发送一个定义在程序存储区的字符串到串口
extern putbytes(uchar *outplace,uint j);//放一串数据到发送缓冲区,需要定义发送的字节数
extern puthex(uchar c);					//发送一个字节的hex码,分成两个字节发。
extern  bit   inbufsign;				//串口接收到数据标志
extern void serial_init (void);    		//串口初始化
#define CR putstring("\r\n")			//发送一个回车换行
#define XIAN 1
#define YUAN 2
#define QUXIAN 3
/*液晶操作***/
extern void lcd_cls(void);							//清屏
extern void lcd_string(uchar attr,uchar *string); 	//显示字符串
extern void Set_module_light(uchar module);
//extern void lcd_cursor(uchar x, uchar y);
//8279操作
extern void init8279();
//**********键盘操作
extern uchar data key;
//画线函数定义
uchar shape=0;
uint xdata num0 _at_ 0x209b;
uint xdata num1 _at_ 0x20a1;
uchar xdata state _at_ 0x20b0;
float xdata l_xishu _at_ 0x2008;
float xdata r_xishu _at_ 0x2010;
float xdata xstart _at_  0x2016;
float xdata ystart _at_ 0x201b;
float xdata xend _at_ 0x2020;
float xdata yend _at_ 0x2026;
float xdata xcur _at_ 0x202b;
float xdata ycur _at_ 0x2030;


uchar xdata direction_l _at_ 0x2040;
uchar xdata direction_r _at_ 0x2042;


static uchar xdata keystr[2][4] _at_ 0x2072;
static uchar xdata count _at_ 0x207b,isy _at_ 0x207c;

uchar xdata x_temp _at_ 0x2100;
uchar xdata y_temp _at_ 0x2102;
uchar xdata xystr[3] _at_ 0x2103;

double xdata pt1_x _at_ 0x2200,pt1_y _at_ 0x2208,
					 	pt2_x _at_ 0x2210,pt2_y _at_ 0x2218,
						temp _at_ 0x2220, motorl_step _at_ 0x2228,
					 motorr_step _at_ 0x2230;
uint xdata timer0_l _at_ 0x2068,timer1_l _at_ 0x206c;
uint data timer1_r;
void GetPCdata()
	{
		if(inbufsign!=1)
			return;
		if(getbyte() == 0x05);
		{
			key=getbyte();
//			sdkey=key;
		}
   }

//	uchar sdkey;

//左电机正转函数
void step0_z(uchar i)
{
	switch(i)
		{
			case 0:
				P1_0=0;
				P1_1=0;
				break;
			case 1:
				P1_0=1;
				P1_1=0;
				break;
			case 2:
				P1_0=1;
				P1_1=1;
				break;
			case 3:
				P1_0=0;
				P1_1=1;
				break;
		}
}
//左电机反转函数
void step0_f(uchar i)
{
	switch(i)
		{
			case 0:
				P1_0=0;
				P1_1=1;
				break;
			case 1:
				P1_0=1;
				P1_1=1;
				break;
			case 2:
				P1_0=1;
				P1_1=0;
				break;
			case 3:
				P1_0=0;
				P1_1=0;
				break;
		}

}
//右电机正转函数
void step1_z(uchar i)
{
	switch(i)
		{
			case 0:
				P1_2=0;
				P1_3=0;
				break;
			case 1:
				P1_2=1;
				P1_3=0;
				break;
			case 2:
				P1_2=1;
				P1_3=1;
				break;
			case 3:
				P1_2=0;
				P1_3=1;
				break;
		}

}
//左电机反转函数
void step1_f(uchar i)
{
	switch(i)
		{
			case 0:
				P1_2=0;
				P1_3=1;
				break;
			case 1:
				P1_2=1;
				P1_3=1;
				break;
			case 2:
				P1_2=1;
				P1_3=0;
				break;
			case 3:
				P1_2=0;
				P1_3=0;
				break;
		}

}
//上面的变量赋初值后调用下面函数计算电机应走的步数以及方向					

void shoudong()
{
//	GetPCdata();
	P0=0xff;
	//timer0_l=10000;
	//timer1_r=10000;
	motorl_step=1000;
	motorr_step=1000;
	if(!P0_0)direction_l=1;
	if(!P0_1)direction_l=0;
	if(!P0_0||!P0_1)TR0=1;else TR0=0;

	if(!P0_2)direction_r=0;
	if(!P0_3)direction_r=1;
	if(!P0_2||!P0_3)TR1=1;else TR1=0;
}

float dis;
displayxy()
{
	while(state)
		if(!(num0%10)||!(num0)%7)
		{
			dis=(pt1_x+(pt2_x-pt1_x)*num0/motorl_step);
			xystr[0]=dis/10+48;
			xystr[1]=(int)dis%10+48;
			xystr[2]='\0';
			lcd_cls();
			lcd_string(0,"\r\nX: ");
			lcd_string(0,xystr);
			lcd_string(0," cm");
			dis=(pt1_y+(pt2_y-pt1_y)*num0/motorl_step);
			xystr[0]=dis/10+48;
			xystr[1]=(int)dis%10+48;
			xystr[2]='\0';
			lcd_string(0,"\r\nY: ");
			lcd_string(0,xystr);
			lcd_string(0," cm");
		}
//		shoudong();
}







void line()
{
//	temp=0;
	

	motorr_step=
					(sqrt((95-pt2_x)*(95-pt2_x)+
					(115-pt2_y)*(115-pt2_y))-
					sqrt((95-pt1_x)*(95-pt1_x)+
					(115-pt1_y)*(115-pt1_y))-
					(pt2_x-40)*0.001)
					/one_step;//右电机应走的步数

	motorl_step=(sqrt((pt2_x+15)*(pt2_x+15)+(115-pt2_y)*(115-pt2_y))
  -sqrt((pt1_x+15)*(pt1_x+15)+(115-pt1_y)*(115-pt1_y))-
					(pt2_x-40)*0.001)/one_step;//左电机应走的步数
	if(motorl_step<0)
	 direction_l=zheng;
	else
	 direction_l=fan;	
	if(motorr_step<0)
		direction_r=zheng;
	else
		direction_r=fan;
	motorl_step=abs(motorl_step);
	motorr_step=abs(motorr_step);
	temp=motorl_step/motorr_step;
	l_xishu=1;
	r_xishu=temp;
	TR0=1;
	TR1=1;
	state=1;
}


void timer0_init()
{
  timer0_l=time_count*l_xishu;
	TMOD=0x01;   //设定定时器的工作方式//左电机
	TH0=(65536-timer0_l)/256;
  TL0=(65536-timer0_l)%256;
	ET0=1;
	EA=1;
}
void timer1_init()//定时1毫秒
{
  timer1_l=time_count*r_xishu;
	TMOD=0x11;   //设定定时器的工作方式//右电机
	TH1=(65536-timer1_l)/256;
  TL1=(65536-timer1_l)%256;
	ET1=1;
	EA=1;
	//IE复位后的状态 0X0000B
}
void time0_1ms() interrupt 1//左电机定时
{
	uint data timer0_l=time_count*l_xishu;
	TH0=(65536-timer0_l)/256;
  TL0=(65536-timer0_l)%256;
	if(direction_l==zheng)
		step0_z(num0%4);
	else
		step0_f(num0%4);
	if(num0>=motorl_step)
		{
			TR0=0;
			num0=0;
			state=0;
		}
	else
	{
		num0++;
	}
}
void time1_1ms() interrupt 3//右电机定时
{
	timer1_r=time_count*r_xishu;
	TH1=(65536-timer1_r)/256;
  TL1=(65536-timer1_r)%256;

	if(direction_r==zheng)
		step1_z(num1%4);
	else
		step1_f(num1%4);
	
	if(num1>=motorr_step)
		{
			TR1=0;
			num1=0;
			state=0;
		}
	else
		{
			num1++;
		}

}
//**********************
uchar data KeyFuncIndex = 0;//当前状态
//状态函数开始
void start1()
{
	lcd_cls();
	lcd_string(1,"定点\r\n");//背光显示
	lcd_string(0,"矩形\r\n");
	lcd_string(0,"三角\r\n");
	lcd_string(0,"圆形\r\n");
	lcd_string(0,"循迹\r\n");
}
void start2()
{
	lcd_cls();
	lcd_string(0,"定点\r\n");//背光显示
	lcd_string(1,"矩形\r\n");
	lcd_string(0,"三角\r\n");
	lcd_string(0,"圆形\r\n");
	lcd_string(0,"循迹\r\n");
}
void start3()
{
	lcd_cls();
	lcd_string(0,"定点\r\n");//背光显示
	lcd_string(0,"矩形\r\n");
	lcd_string(1,"三角\r\n");
	lcd_string(0,"圆形\r\n");
	lcd_string(0,"循迹\r\n");
}
//***************************
void start4()
{
	lcd_cls();
	lcd_string(0,"定点\r\n");//背光显示
	lcd_string(0,"矩形\r\n");
	lcd_string(0,"三角\r\n");
	lcd_string(1,"圆形\r\n");
	lcd_string(0,"循迹\r\n");
}
void start5()
{
	lcd_cls();
	lcd_string(0,"定点\r\n");//背光显示
	lcd_string(0,"矩形\r\n");
	lcd_string(0,"三角\r\n");
	lcd_string(0,"圆形\r\n");
	lcd_string(1,"循迹\r\n");
}
//********************************
void middle6()
{
	lcd_cls();	
	lcd_string(0,"★设置终点坐标★\r\n");
	shape=XIAN;
//	lcd_string(0,"\r\nX: ");
//	lcd_string(0,"\r\nY:   cm");

}
//******************************
void middle7()//矩形
{
//	lcd_cls();	
//	lcd_string(0,"  ★实时坐标显示★");
//	lcd_string(0,"\r\n\r\nX:   cm");
//	lcd_string(0,"\r\nY: k  cm");
/*
	pt1_x=0;
	pt1_y=0;
	pt2_x=50;
	pt2_y=30;
	line();
	while(state);
	pt1_x=50;
	pt1_y=30;
	pt2_x=50;
	pt2_y=70;
	line();*/
	
}
void middle8()//三角
{
	//lcd_cls();	
	//lcd_string(0,"  ★实时坐标显示★");
	//lcd_string(0,"\r\n\r\nX:   cm");
	//lcd_string(0,"\r\nY:  k cm");
	/*
	pt1_x=0;
	pt1_y=0;
	pt2_x=60;
	pt2_y=0;
	line();	
	displayxy();
//	while(state);
	pt1_x=60;
	pt1_y=0;
	pt2_x=0;
	pt2_y=60;
	line();
	displayxy();

//	while(state);
	pt1_x=0;
	pt1_y=60;
	pt2_x=0;
	pt2_y=0;
	line();
	displayxy();
*/
	pt1_x=0;
	pt1_y=0;
	pt2_x=24;
	pt2_y=38;
	line();	
	displayxy();
//	while(state);
	pt1_x=24;
	pt1_y=38;
	pt2_x=62;
	pt2_y=9;
	line();
	displayxy();

//	while(state);
	pt1_x=62;
	pt1_y=9;
	pt2_x=0;
	pt2_y=0;
	line();
	displayxy();
}
//**********************
uchar xdata yuanptcount _at_ 0x20cd;			
bit bdata yuanflag=1;
void middle9()
{	
	lcd_cls();
	lcd_string(0,"★设置圆心坐标★\r\n");

	//	
	//lcd_string(0," ★实时坐标显示★");
	//lcd_string(0,"\r\n\r\nX:   cm");
	//lcd_string(0,"\r\nY:   cm");
	shape=YUAN;

}
void middle10()
{
	//lcd_string(0,"\r\n\r\n      运行中...\r\n");
	lcd_cls();
	lcd_string(0,"★设置起点坐标★\r\n");
	shape=QUXIAN;
}

void gif()
{
	lcd_cls();
	lcd_string(0,"\r\n 悬挂运动控制系统\r\n");
	lcd_string(0,"\r\n    2005-9-13");
	lcd_string(0,"\r\n待机");
	return;
}
//**********************
typedef struct
{
	uchar	KeyStateIndex;	//当前状态索引号
	uchar	KeyDnState;	//按下"向下"键时状态索引号
	uchar	KeyUpState;	//按下"向上"键时状态索引号
	uchar	KeyCrState;	//按下"回车"键时状态索引号
	uchar	KeyCaState;	//按下"取消"键时状态索引号
	void  (*CurrentOperate)();	//当前状态应该执行的功能操作
} KbdTabStruct;

void	(*KeyFuncPtr)();	//按键功能函数指针

//************************
KbdTabStruct	code	KeyTab[]=
{//cur down up enter cancel curfunction 
	{0, 0, 0, 0, 0,(*gif)},	//开机画面

	{1, 2, 5, 6, 1, (*start1)},
	{2, 3, 1, 7, 2, (*start2)},
	{3, 4, 2, 8, 3, (*start3)},
	{4, 5, 3, 9, 4, (*start4)},
	{5, 1, 4, 10, 5, (*start5)},

	{6, 6, 6, 6, 1, (*middle6)},
	{7, 7, 7, 7, 2, (*middle7)},
	{8, 8, 8,8, 3, (*middle8)},
	{9, 9, 9, 9, 4, (*middle9)},
	{10, 10, 10, 10, 5,(*middle10)},

};
//状态函数结束

void yuan()
{
	for(yuanptcount=0;yuanptcount<72;yuanptcount++)
	{
			pt2_x=40*cos(0.08726646*yuanptcount)*1.05+xend;
			pt2_y=40*sin(0.08726646*yuanptcount)*0.95+yend;
			if(yuanflag)
			{
				pt1_x=pt2_x;
				pt1_y=pt2_y;
				yuanflag=0;
			}
			line();
			displayxy();
			pt1_x=pt2_x;
			pt1_y=pt2_y;
	}				
}
float qxtemp;
uchar qxcount;
bit bdata quxianflag=1;
void quxian()
{

	while(1)
	{
	qxtemp=0;
		if(quxianflag)
		{
			pt1_x=xend;
			pt1_y=yend;
			pt2_x=pt1_x;
			quxianflag=0;
		}	
		pt2_y=pt1_y+0.2;
		if(!P1_4)qxtemp=-1.4;//,lcd_string(0,"z0");
														//		else lcd_string(0,"z1");
		if(!P1_5)qxtemp=1.4;//,lcd_string(0,"y0");
												//else lcd_string(0,"y1");
		if(P1_6)qxcount++;//,lcd_string(0,"q1");
		else qxcount=0;//,lcd_string(0,"q0");
		if(qxcount>100)break;
//		if(!P1_4||!P1_5)
		pt2_x=pt1_x+qxtemp;
		line();
		displayxy();
		while(state);
		pt1_x=pt2_x;
		pt1_y=pt2_y;
	}	
}

void GetKeyInput(void)
{
	switch(key)
	{
			case 0x00:
				 return;
			case 0xda://回车键
					if(KeyFuncIndex==0)
					 return;
					if(count)
					{
						keystr[isy][count]='\0';
						count=0;
						if(!isy)
						{							
							xend=atoi(keystr[0]);
						}
						else 
						{
							yend=atoi(keystr[isy]);
							pt1_x=xstart;
							pt1_y=ystart;
							pt2_x=xend;
							pt2_y=yend;
							if(shape==XIAN)
							line();
							else if(shape==YUAN)
							yuan();
							else if(shape==QUXIAN)
							quxian();	
							displayxy();
							shape=0;
						}
							isy=!isy;
					}
				 KeyFuncIndex=KeyTab[KeyFuncIndex].KeyCrState;
				 break; 
			case 0xdc://开始循迹
					lcd_cls();
					lcd_string(0,"开始循迹");
					break;
			case 0xdb: //启动键
					if(KeyFuncIndex==0)
					KeyFuncIndex=1;
				 break;
			case 0xd2://取消键
				 if(KeyFuncIndex<=5)
				 return;
				 KeyFuncIndex=KeyTab[KeyFuncIndex].KeyCaState;
				 break;
			case 0xc2://向上键
				 if(KeyFuncIndex==0)
						return;
				 KeyFuncIndex=KeyTab[KeyFuncIndex].KeyUpState;
				 break; 
			case 0xca://向下键
				 if(KeyFuncIndex==0)
						return;
				 KeyFuncIndex=KeyTab[KeyFuncIndex].KeyDnState;
				 break; 
			case 0xdd:
					keystr[isy][count++]=48;
					key=0;
					lcd_string(0,"0");
					return;
			case 0xd5:
					keystr[isy][count++]=49;
					key=0;
					lcd_string(0,"1");
					return;					
			case 0xd4:
					keystr[isy][count++]=50;
					key=0;
					lcd_string(0,"2");
					return;
			case 0xd3:
					keystr[isy][count++]=51;
					key=0;
					lcd_string(0,"3");
					return;
			case 0xcd:
					keystr[isy][count++]=52;
					key=0;
					lcd_string(0,"4");
					return;
			case 0xcc:
					keystr[isy][count++]=53;
					key=0;
					lcd_string(0,"5");
  				return;
			case 0xcb:
					keystr[isy][count++]=54;
					key=0;
					lcd_string(0,"6");
					return;
			case 0xc5:
					keystr[isy][count++]=55;
					key=0;
					lcd_string(0,"7");
					return;
			case 0xc4:
					keystr[isy][count++]=56;
					key=0;
					lcd_string(0,"8");
					return;
			case 0xc3:
					keystr[isy][count++]=57;
					key=0;
					lcd_string(0,"9");
					return;
			default:	//按键错误的处理
					return;
	}

	KeyFuncPtr=KeyTab[KeyFuncIndex].CurrentOperate;
	(*KeyFuncPtr)();//执行当前按键的操作
	key=0;
}
//*************************
void init_main()
{
	serial_init();	
	init8279();
	timer0_init();
	timer1_init();
	KeyFuncPtr=KeyTab[0].CurrentOperate;//开机画面
	(*KeyFuncPtr)();//执行当前按键的操作
	
}

void main(void)
{
	isy=0;
	count=0;
	xstart=0,ystart=0;
	num0=0,num1=0;
	state=0;
	l_xishu=1;
	r_xishu=1;
	quxianflag=1;
	init_main();
	for(;;)
	{
		GetPCdata();
		shoudong();
		GetKeyInput();	
	}

}

⌨️ 快捷键说明

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