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

📄 main.c

📁 参加05年全国_大学生_电子设计_大赛的程序 AVR ICC基于AVR单片机!
💻 C
📖 第 1 页 / 共 3 页
字号:
		CLRCS1();
	}
	for(i=0;i<8;i++)
	{
		setx(i);
		sety(0);
		SETDIF();
		for(j=0;j<64;j++)
		{
			do_x(0);
		}
	}
}
void clr_row(uint row,uint cs)/*清除一行,cs=0,全清,cs=1,清左,cs=2,清右*/
{
	uint i;
	SETCS1();
	SETCS2();
	if(cs==1)
	{
		CLRCS2();
	}
	if(cs==2)
	{
		CLRCS1();
	}
	setx(row);
	sety(0);
	SETDIF();
	for(i=0;i<64;i++)
	{
		do_x(0);
	}
}
/*i=0,表示清除一个点;i=1表示写一个点,默认是写去反后的点;x表示小行(8小行是一大行),y表示列,只用在第二屏幕*/
void write_p(uchar x,uchar y,uchar i)
{
	uchar c;
	/*read_x里面用的参数就是第二屏幕的,置操作第二屏幕*/
	c=read_x((uchar)(x>>3),y);
	if(i=='\0')
	{
		c&=~(1<<(x&7));
	}
	else if(i=='\1')
	{
		c|=(1<<(x&7));
	}
	else
	{
		c^=(1<<(x&7));
	}
	write_x((uchar)(x>>3),y,c);

}
/*在x行y列位置显示汉字p,y是从0-127的数值*/
void dis_hz(uint x,uint y,const uchar *hz)
{
	uint i,j;
	uchar c,tt[32];
	uchar *p;
	for(i=0;i<32;i++)
	{
		tt[i]=hz[i];
	}
	setyEx(y);
	setx(x);
	/*显示第一行*/
	SETDIF();
	CLRRWF();
	p=tt;	
	for(i=0;i<16;i++)
	{
		do_x(p[i]);
	}
	setyEx(y);
	setx(x+1);
	/*显示第二行*/
	SETDIF();
	CLRRWF();
	p+=16;
	for(i=0;i<16;i++)
	{
		do_x(p[i]);
	}
}
/*显示一行汉字,从y开始显示*/
void dis_hz_row(uint row,uint y,const char **hz)
{
	uint i,j;
	//setx(row);
	//sety(32);	/*为前面的箭头流出空间*/
	for(i=0;hz[i]!=NULL;i++)
	{
		dis_hz(row,i*16+y,hz[i]);
	}
}
/*画欢迎屏幕*/
void dis_welcome(void)
{
	const uchar *p1[]={hz_xuan,hz_gua,hz_yun,hz_dong,hz_kong,hz_zhi_,hz_xi,hz_tong,NULL};		/*悬挂运动系统控制*/
	const uchar *p2[]={hz_yan,hz_shan,hz_da,hz_xue,hz_xin_,hz_xi_,hz_xue,hz_yuan_,NULL};		/*燕山大学信息学院*/
	clrscr(0);
	dis_hz_row(2,0,p1);
	dis_hz_row(4,0,p2);
	dis_en_row(7,30,"Press OK to START.");delay_ms(2000);
	while(get_key()!=KEY_OK)	//等待按下OK键
	{
		;
	}
}
/*显示一个英文,返回所占列数*/
uint dis_en(uint x,uint y,uint c)
{
	uint i,j,tc;
	const uchar *p;
	/*取指针*/
	if(c>='A'&&c<='Z')
	{
		p=&A_Z[(c-'A')*5];
	}
	else if (c>='a' && c<='z')
	{
		p=&a_z[(c-'a')*5];
	}
	else if (c>='0' && c<='9')
	{
		p=&num0_9[(c-'0')*5];
	}
	else
	{
		switch (c)
		{
			case '.':p=x_p;break;
			case ':':p=x_mh;break;
			case '_':p=x_ds;break;
			case '^':p=x_shang;break;
			case '~':p=x_xia;break;
			default:p=space;break;
		}
	}
	/*开始操作*/
	setyEx(y);
	setx(x);
	SETDIF();
	for(i=0;(i<3)||(p[i]&&(i<5));i++)
	{
		tc=p[i];
		do_x(tc);
		y++;
		if(y==64)
		{
			setyEx(64);
			setx(x);
			SETDIF();
		}
		
	}
	do_x(0x00);
	return i+1;
}
//返回操作后的y(列)坐标值
uint dis_en_row(uint x,uint y,uchar *p)
{
	uint i,cnt=y,t;
	for(i=0;p[i]!=0;i++)
	{
		t=dis_en(x,cnt,p[i]);
		cnt+=t;
	}
	return cnt;
}
uint dis_num_row(uint x,uint y,uint d)
{
	uchar s[8],t;	//存放数字转换成的字符串
	uint cnt=d,i=0,j;
	/*
	while(cnt)
	{
		s[i++]='0'+cnt%10;
		cnt/=10;
	}
	s[i]=0;
	i--;
	
	for(j=0;j<i-j;j++)
	{
		t=s[i-j];
		s[i-j]=s[j];
		s[j]=t;
	}
	*/
	itoa(s,d,10);
	d=dis_en_row(x,y,s);
	return d;
}
void line(uint x1,uint y1,uint x2,uint y2)
{
	int xx,yy;/*表示差量和斜率*/
	uchar i,j;
	int dx=1,dy=1;
	double k,kk,t;/*斜率和反斜率*/
	if(x2<x1) dx=-1;
	if(y2<y1) dy=-1;
	if(x1==x2)
	{
		for(i=y1;i!=y2;i+=dy)
		{
			write_p(x1,i,1);
		}
		write_p(x2,y2,1);
	}
	else if(y1==y2)
	{
		for(i=x1;i!=x2;i+=dx)
		{
			write_p(i,y1,1);
		}
		write_p(x2,y2,1);
	}
	else
	{
		k=(double)(y2-y1)/(double)(x2-x1);
		kk=(double)(x2-x1)/(double)(y2-y1);
		if((k<=1.0)&&(k>=-1.0))
		{
			for(i=x1;i!=x2;i+=dx)
			{
				t=(double)y1+k*(double)(i-x1);
				write_p((uint)i,(uint)t,1);
			}
		}
		else
		{
			//for(i=y1;i!=y2;i+=dy)
			for(i=y1;i!=y2;i+=dy)
			{
			 	//t=(double)x1+kk*(double)(i-y1);
			 	//t=x1+(x2-x1)*(i-y1)/(y2-y1);
				//write_p((uchar)t,i,1);
				write_p(x1+(i-y1)*(x2-x1)/(y2-y1),i,1);
			}
		/*
		for(i=0;i<50;i++)
		{
			write_p(i/3,i,1);
		}
		*/		
		}
		write_p(x2+2,y2+2,1);
	}

}
//因为LCD上面的坐标和一般显示的xy是颠倒的,所以给倒国来,当然也可以用宏来实现
void line_x(uint x1,uint y1,uint x2,uint y2)
{
	line(y1,x1,y2,x2);
}

//下面的2个函数的相对坐标是显示的框架,可以在走马达的时候直接调用
void draw_point(uint x,uint y)	//画点
{
	uint xx,yy;
	xx=53-y/2;
	yy=12+x/2;
	write_p(xx,yy,1);
	//write_p(7+y/2,54-x/2,1);
}
void draw_line_x(uint x1,uint y1,uint x2,uint y2)
{
	line_x(54-x1/2,7+y1/2,54-x2/2,7+y2/2);
}
//有马达运动函数调用,参数是马达当前的坐标,需要用draw_point()函数
void c_point(uint x,uint y)
{
	draw_point(x,y);
	dis_num_row(7,8,x);
	dis_num_row(7,24,y);
}
/*显示本屏幕可以放下的菜单项目,一个屏幕4个,所以开头一定是4的倍数*/
/*菜单显示的项目:
0.定点
1.画线
2.画圆
3.找线
4.画图
5.定标
*/
void dis_menu(uint menu_index,uint menu_max)
{
	uint i,j;
	uchar g;
	uint page;	//当前页数
	uint p_index;	//在当前页的索引
	uint d_index;	//索引的差值
	const uchar *menu_hz_0[]={hz_ding,hz_dian,NULL};	//定点
	const uchar *menu_hz_1[]={hz_hua,hz_xian,NULL};		//画线
	const uchar *menu_hz_2[]={hz_hua,hz_yuan,NULL};		//画圆
	const uchar *menu_hz_3[]={hz_zhao,hz_xian,NULL};	//找线
	const uchar *menu_hz_4[]={hz_hua,hz_tu,NULL};		//画图
	const uchar *menu_hz_5[]={hz_ding,hz_biao,NULL};		//定标	

	
	clrscr(0);
	page=menu_index/4;
	p_index=menu_index%4;
	//d_index=menu_index-p_index;

	if(menu_index<4)
	{
		dis_hz_row(0,16,menu_hz_0);
		dis_hz_row(2,16,menu_hz_1);
		dis_hz_row(4,16,menu_hz_2);
		dis_hz_row(6,16,menu_hz_3);
	}
	else
	{
		dis_hz_row(0,16,menu_hz_4);
		dis_hz_row(2,16,menu_hz_5);
	}
	//显示箭头,包括指向箭头和上下翻页箭头
	//^和上箭头对应,~和下箭头对应
	dis_hz(p_index*2,0,hz_jiantou);
	for(i=16;i<48;i++)
	{
		g=read_x(p_index*2,i);
		g=~g;
		write_x(p_index*2,i,g);
	}
	for(i=16;i<48;i++)
	{
		g=read_x(p_index*2+1,i);
		g=~g;
		write_x(p_index*2+1,i,g);
	}
	if(menu_max>4)
	{
		if(menu_index>3)
		dis_en(0,57,'^');
		if((page+1)*4<menu_max)
		dis_en(7,57,'~');
	}
	
}
//画示意图的边界,图形是80*100的,在此显示为40*50,留的边是24和14
void dis_side(void)
{
	line_x(11,4,52,4);
	line_x(11,4,11,53);
	line_x(52,4,52,53);
	line_x(11,53,52,53);
}
void start_wait(void)	//在需要执行操作以前,显示"Press OK to start",等待按键,显示c_c:,c_y
{
	uint c,f=1;
	dis_en_row(7,0,"Press OK to start..  ");
	while(f)
	{
		c=get_key();
		if(c==KEY_OK)
		{
			f=0;
		}
	}
	clr_row(7,1);
	dis_en_row(7,0,"c_x:");
	dis_en_row(7,32,"c_y:");
	//strat_timer();
	t_cnt=0;
}
void stop_wait(void)	//操作结束后的函数
{
	uchar c,t,i;
	uint f=1;
	//stop_timer();
	t=t_cnt;
	//dis_time();
	clrscr(2);
	dis_en_row(2,64,"Use Time:");
	dis_num_row(4,90,t);
	clr_row(7,1);
	dis_en_row(7,0,"Press OK to return");
	
	while(f)
	{
		c=get_key();
		if(c==KEY_OK)
		f=0;
	}
}
int get_num(uint row,uint line)
{
	int num,dis_t,t,f=0;
	uchar c;
	dis_t=line;
	num=0;
	while(1)
	{
		c=get_key();
		if(c<10&&c>=0)
		{
			f=1;
			num=num*10+c;
			t=dis_en(row,dis_t,'0'+c);
			dis_t+=t;
		}
		if((c==KEY_OK)&&(f==1))
		{
			return num;
		}
		if(c==KEY_FUN)
		{
			return -2;
		}
	}
	
}
void m_dingdian(void)	//定点,也就是输入坐标,然后移动到定点
{
	uint dx,dy,cx,cy;//目的坐标和当前坐标
	uint dis_t;	//显示用的临时变量,表示当前行的列坐标
	uchar c;
	clrscr(0);	//清除所有屏幕
	dis_side();
	dis_hz(0,64,hz_ding);//delay_ms(1500);
	dis_hz(0,80,hz_dian);//delay_ms(1500);
	dis_hz(0,96,hz_zuo);//delay_ms(1500);
	dis_hz(0,112,hz_biao);//delay_ms(1500);	//定点坐标
	dis_t=dis_en_row(2,64,"X:_");
	dx=get_num(2,dis_t);	//get_num()里面调用get_key()获得一个数字,参数表示在lcd显示数字的位置
	dis_t=dis_en_row(3,64,"Y:_");
	dy=get_num(3,dis_t);
	//动态显示当前坐标位置,如果可以的话,调用start_timer函数计时
	draw_point(dx,dy);
	start_wait();
	//在下面调用控制步进电机走到设定点的函数,参数是dx,dy.
	x=0;y=0;
	draw_line_base(dx,dy);
	//for(c=0;c<50;c++)
	//draw_point(c,c);
	//结束
	stop_wait();
}
void m_huaxian(void)	//画线,输入线的起始坐标,然后画线
{
	uint dx1,dy1,dx2,dy2,cx,cy;	//目的地址1,2和当前地址
	uint dis_t;
	clrscr(0);
	dis_side();		//边框
	//点1坐标
	dis_hz(0,64,hz_dian);
	dis_hz(0,64+16,hz_yi);
	dis_hz(0,64+32,hz_zuo);
	dis_hz(0,64+48,hz_biao);	
	dis_t=dis_en_row(2,64,"X1:_");
	dx1=get_num(2,dis_t);		//x1
	dis_t=dis_en_row(3,64,"Y1:_");
	dy1=get_num(3,dis_t);		//y1
	//点2坐标
	dis_hz(4,64,hz_dian);
	dis_hz(4,64+16,hz_er);
	dis_hz(4,64+32,hz_zuo);
	dis_hz(4,64+48,hz_biao);
	dis_t=dis_en_row(6,64,"X1:_");
	dx2=get_num(6,dis_t);
	dis_t=dis_en_row(7,64,"Y1:_");
	dy2=get_num(7,dis_t);
	//
	draw_point(dx1,dy1);
	draw_point(dx2,dy2);
	start_wait();
	//在这里调用控制步进电机画直线的函数,参数是dx1,dy1,dx2,dy2
	x=dx1;y=dy1;
	draw_line(dx2,dy2);
	//结束
	stop_wait();
}
void m_huayuan(void)	//画圆,输入半径和圆心坐标,画圆
{
	uint r,dx,dy,dis_t;
	float rf;
	clrscr(0);
	dis_side();		//边框
	//圆心坐标
	dis_hz(0,64,hz_yuan);
	dis_hz(0,64+16,hz_xin);
	dis_hz(0,64+32,hz_zuo);
	dis_hz(0,64+48,hz_biao);	
	dis_t=dis_en_row(2,64,"X:_");
	dx=get_num(2,dis_t);		//x1
	dis_t=dis_en_row(3,64,"Y:_");
	dy=get_num(3,dis_t);		//y1
	dis_t=dis_en_row(4,64,"R:_");	//半径
	r=get_num(4,dis_t);
	draw_point(dx,dy);
	start_wait();
	//在这调用画圆函数,参数是dx,dy,r
	x=dx;y=dy;
	rf=(float)r;
	draw_cricle(rf);
	stop_wait();
}			
void m_zhaoxian(void)	//根据黑线走,先是连续的,后面是断的
{
	clrscr(0);
	dis_side();	//边框
	//点1坐标
	dis_hz(0,64,hz_zhao);
	dis_hz(0,64+16,hz_xian);
	
	start_wait();
	//在这里调用找线函数
	
	stop_wait();
}

void m_huatu(void)	//希望扩展的功能,用来作任意图形
{
	int dx[15],dy[15],dis_t,n,i,cnt;

	clrscr(0);
	dis_side();
	dis_hz(0,64,hz_dian);
	dis_hz(0,64+16,hz_shu);
	dis_t=dis_en_row(1,96,":");
	n=get_num(1,dis_t);
	
	for(i=0;i<n;i++)
	{
	 	clr_row(3,2);
		dis_t=dis_en_row(3,64,"X");
		dis_t+=dis_en(3,dis_t,'0'+i+1);
		dis_t=dis_en_row(3,dis_t,":_");
		dx[i+1]=get_num(3,dis_t);
		
		clr_row(5,2);

⌨️ 快捷键说明

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