基于32F1的电阻屏模式选择菜单

由于电赛的任务调度需求,我写了这个模式选择菜单,测试基于正点原子的战舰V3开发板,3.5寸电阻屏,对正点原子LCD封装库进行扩展,可自选1到12模式数量,自排版并在触屏时输出模式序号。

LCD_Menu.c

#include "LCD_Menu.h"
#include "key.h"
#include "led.h"

//给模式选项画一个框
//width,height 框左上角起始位置
//H,L 设置框的高,宽
void MODE_Draw_Frame(unsigned int width,unsigned int height,unsigned int H,unsigned int L,unsigned int color)
{
	POINT_COLOR=color;
	LCD_DrawLine(width, height, width + L, height);
	LCD_DrawLine(width, height, width , height + H);
	LCD_DrawLine(width, height + H, width + L, height + H);
	LCD_DrawLine(width + L, height + H, width + L, height);
}

void MODE_Draw_Name(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p,u8 num)
{         
	u8 x0=x;
	width+=x;
	height+=y;
    while((*p<='~')&&(*p>=' '))//判断是不是非法字符
    {       
        if(x>=width){x=x0;y+=size;}
        if(y>=height)break;//退出
        LCD_ShowChar(x,y,*p,size,0);
        x+=size/2;
        p++;
    }
		if(num<10)//用于显示模式序号
		{
			LCD_ShowChar(x,y,num+0x30,size,0);
			x+=size/2;
		}
		else if(num<100)
		{
			LCD_ShowChar(x,y,num/10+0x30,size,0);
			x+=size/2;
			LCD_ShowChar(x,y,num%10+0x30,size,0);
			x+=size/2;
		}
}

//显示模式选择界面
//num:模式数量选择
//colorr:方框颜色选择
//color:字体颜色选择
//name:模式名称 最好为四个字符
void MODE_Draw_ChousePage(unsigned char num,unsigned int colorr,unsigned int color,unsigned char* name)
{
	unsigned char i;
	if(num<=2)
	{
		for(i=0;i<num;i++)
		{
			MODE_Draw_Frame(lcddev.width/2-50,(i+1)*lcddev.height/(num+1+num/3),40,100,colorr);
			POINT_COLOR=color;
			MODE_Draw_Name(lcddev.width/2-27,(i+1)*lcddev.height/(num+1+num/3)+8,80,24,24,name,i+1);
		}
	}
	else	if(num<=6)
	{
		for(i=0;i<num;i++)
		{
			MODE_Draw_Frame(lcddev.width/2-50,(i+1)*lcddev.height/(num+num/3),40,100,colorr);
			POINT_COLOR=color;
			MODE_Draw_Name(lcddev.width/2-27,(i+1)*lcddev.height/(num+num/3)+8,80,24,24,name,i+1);
		}
	}
	else if(num<=12)
	{
		for(i=0;i<num;i++)
		{
			if(i%2==0)
			{				
				MODE_Draw_Frame(lcddev.width/4-50,(i/2+1)*lcddev.height/(num/2+num%2+num/6),40,100,colorr);
				POINT_COLOR=color;
				MODE_Draw_Name(lcddev.width/4-27,(i/2+1)*lcddev.height/(num/2+num%2+num/6)+8,80,24,24,name,i+1);
			}
			if(i%2==1)
			{				
				MODE_Draw_Frame(3*lcddev.width/4-50,(i/2+1)*lcddev.height/(num/2+num%2+num/6),40,100,colorr);
				POINT_COLOR=color;
				MODE_Draw_Name(3*lcddev.width/4-27,(i/2+1)*lcddev.height/(num/2+num%2+num/6)+8,80,24,24,name,i+1);
			}
		}
	}
}

//触摸模式选择函数
//num  模式数量
//num 最大数量为12
char MODE_Chouse(unsigned char num)
{
	u8 key;
	u8 a=0,i=0;	  
	while(1)
	{
	 	key=KEY_Scan(0);
		tp_dev.scan(0); 		 
		if(tp_dev.sta&TP_PRES_DOWN)			//´触摸屏被按下
		{
			if(num<=2)
			{
				for(i=0;i<num;i++)
					if((lcddev.width/2-50)<tp_dev.x[0]
						&&tp_dev.x[0]<(lcddev.width/2+50)
						&&(i+1)*lcddev.height/(num+1+num/3)<tp_dev.y[0]
						&&tp_dev.y[0]<((i+1)*lcddev.height/(num+1+num/3)+40))
					return i+1;
			}else
			if(num<=6)
			{
				for(i=0;i<num;i++)
					if((lcddev.width/2-50)<tp_dev.x[0]
						&&tp_dev.x[0]<(lcddev.width/2+50)
						&&(i+1)*lcddev.height/(num+num/3)<tp_dev.y[0]
						&&tp_dev.y[0]<((i+1)*lcddev.height/(num+num/3)+40))
					return i+1;
			}else
			if(num<=12)
			{
				for(i=0;i<num;i++)
				{
					if(i%2==0)
					{		
						if((lcddev.width/4-50)<tp_dev.x[0]
							&&tp_dev.x[0]<(lcddev.width/4+50)
							&&(i/2+1)*lcddev.height/(num/2+num%2+num/6)<tp_dev.y[0]
							&&tp_dev.y[0]<((i/2+1)*lcddev.height/(num/2+num%2+num/6)+40))
						return i+1;
					}
					else if(i%2==1)
					{
						if((3*lcddev.width/4-50)<tp_dev.x[0]
							&&tp_dev.x[0]<(3*lcddev.width/4+50)
							&&(i/2+1)*lcddev.height/(num/2+num%2+num/6)<tp_dev.y[0]
							&&tp_dev.y[0]<((i/2+1)*lcddev.height/(num/2+num%2+num/6)+40))
						return i+1;
					}
				}
			}
			else delay_ms(10);	//没有按键按下的时候   
			if(key==KEY0_PRES)	//KEY0按下	,则执行校准程序
			{
				LCD_Clear(WHITE);//清屏
				TP_Adjust();  	//屏幕校准
				MODE_Draw_ChousePage(num,RED,BLUE,"mode");
			}
			a++;
			if(a%20==0)LED0=!LED0;
		}
	}
}

//集成执行函数
void MODE_IN(unsigned char num)
{
	unsigned char MODE=0;
	while(1)
	{
		MODE_Draw_ChousePage(num,RED,BLUE,"mode");
		MODE = MODE_Chouse(num);
		LCD_Clear(WHITE);
		MODE_Draw_Name(lcddev.width/2,lcddev.height/2,210,24,24," ",MODE);
		LCD_ShowString(0,lcddev.height-25,210,24,24,"back");
		while(1)
		{
			tp_dev.scan(0); 		 
			if(tp_dev.sta&TP_PRES_DOWN)			//´触摸屏被按下
			{	
				if(tp_dev.x[0]<lcddev.width&&tp_dev.y[0]<lcddev.height)
				{	
					if(tp_dev.x[0]<210&&tp_dev.y[0]>lcddev.height-24)
					{
						LCD_Clear(WHITE);
						break;
					}
				}
			}
		}
	}
}

main.c

#include "24cxx.h"
#include "w25qxx.h"
#include "touch.h"
#include "LCD_Menu.h"

int main(void)
{	 		    
	delay_init();	    
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	uart_init(115200);	 
 
	LED_Init();			  
	LCD_Init();	
	KEY_Init();	 	
	tp_dev.init();

	MODE_IN(4);	 
}

LCD_Menu.h

#ifndef _LCD_Menu_H_
#define _LCD_Menu_H_

#include "lcd.h"
#include "touch.h"

void MODE_Draw_Frame(unsigned int width,unsigned int height,unsigned int H,unsigned int L,unsigned int color);
void MODE_Draw_Name(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p,u8 num);
void MODE_Draw_ChousePage(unsigned char num,unsigned int colorr,unsigned int color,unsigned char* name);
char MODE_Chouse(unsigned char num);
void MODE_IN(unsigned char num);

#endif

暂定为第一版本,较为简陋,后续会添加背景,优化名称、排序、数量显示,题目分类选项等。
经测试,模式开始界面启动速度快,对触屏感应灵敏且准确,返回时切换速度快,在执行任务时不会造成影响。
使用时清更改集成函数,为方便调试,集成函数内为无法跳出的死循环,读出子函数返回值后进行模式选择判断即可。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值