stm32触摸屏识别

我用的型号

我用的是正点的开发板精英板,F103ZET6,电阻屏

准备

正点有一个例程,是触摸屏,注意是触摸屏不是手写识别,我们把它下载下来,烧进去发现是手写的轨迹,就是校准(电容屏忽略)以后手按到哪就显示哪里的线条。
利用这个程序的函数,我们更改,最后目标是规定几个区域,按下去以后可以识别出来,也就是把触摸屏当做软按键来用,老式手机不是都像这样嘛哈哈

开始

分析例程

代码很长,反正能免费下载,我就不复制来了,只捡要说的来说。
在main最下面有一段:

if(tp_dev.touchtype&0X80)
		ctp_test();	//电容屏测试
	else rtp_test(); 						//电阻屏测试

这里的测试就是跟踪手写轨迹,啥用都没有,这个函数进去以后就是一直循环,不会自己跳出来的,所以先把它注释,后面可以删掉。
为什么现在不删,因为需要到这个函数定义里面去看看。
右击,go to definition

//电阻触摸屏测试函数
void rtp_test(void)
{
	u8 key;
	u8 i=0;	  
	while(1)
	{
	 	key=KEY_Scan(0);
		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]>(lcddev.width-24)&&tp_dev.y[0]<16)Load_Drow_Dialog();//清除
				else TP_Draw_Big_Point(tp_dev.x[0],tp_dev.y[0],RED);		//画图	  			   
			}
		}else delay_ms(10);	//没有按键按下的时候 	    
		if(key==KEY0_PRES)	//KEY0按下,则执行校准程序
		{
			LCD_Clear(WHITE);//清屏
		    TP_Adjust();  	//屏幕校准  
			Load_Drow_Dialog();
		}
		i++;
		if(i%20==0)LED0=!LED0;
	}
}

注释很清楚了,先扫描按键,然后扫描屏幕,接下来一个大大的if,如果按下怎样怎样,不按下怎样怎样。
我们先看如果屏幕如果按下了要干什么。

if(tp_dev.x[0]<lcddev.width&&tp_dev.y[0]<lcddev.height)
{
	if(tp_dev.x[0]>(lcddev.width-24)&&tp_dev.y[0]<16)
		Load_Drow_Dialog();//清除
	else 
		TP_Draw_Big_Point(tp_dev.x[0],tp_dev.y[0],RED);		//画图	  			   
}

tp_dev.x[0]<lcddev.width&&tp_dev.y[0]<lcddev.height这个条件只是为了更加严谨,它范围就是整个屏幕。
tp_dev.x[0]>(lcddev.width-24)&&tp_dev.y[0]<16)意思是如果按下了右上方24*16这一小块的地方,就清楚整个屏幕。
如果没有按下去,TP_Draw_Big_Point(tp_dev.x[0],tp_dev.y[0],RED); 注释是画图,而且是红色线条画图。
这个好像就是我们需要的函数了。
再来看看如果屏幕没有按下去会怎样:delay_ms(10);延迟10毫秒。
下面还有几句

if(key==KEY0_PRES)	//KEY0按下,则执行校准程序
{
	LCD_Clear(WHITE);//清屏
    TP_Adjust();  	//屏幕校准  
	Load_Drow_Dialog();
}

这个函数很好,能够很方便的随时调用屏幕校准。其中 TP_Adjust(); 这个子函数可以看看,里面用到了电阻屏校准的原理,在touch.c里面,很长很长,没时间的话这一段完全不需要看,反正调用以后能校准就OK,需要自己改动的可能性极小。

开始修改

既然例程已经看好了,那就自己改动呗。
我需要的是,在屏幕里面显示八行信息,点其中一个就能返回特定的值,即使是1~8也行,反正只要有返回就代表人机交互成功了。
这是显示八行信息的程序,用到了lcd.c(废话当然用到,这个不用到的话显示屏都显示不出来还触摸什么)

Show_Str(20,70,200,16,"选择需要查看的监测点序号:",16,0);
Show_Str(20,100,200,16,"测试点1",16,0);
Show_Str(20,130,200,16,"测试点2",16,0);
Show_Str(20,160,200,16,"测试点3",16,0);
Show_Str(20,190,200,16,"测试点4",16,0);
Show_Str(20,220,200,16,"测试点5",16,0);
Show_Str(20,250,200,16,"测试点6",16,0);
Show_Str(20,280,200,16,"测试点7",16,0);
Show_Str(20,310,200,16,"测试点8",16,0);

然后扫描以下屏幕哪里被触摸了:

tp_dev.scan(0);

再根据每行的像素位置来编触摸的有效位置,触摸到了以后给一个u8的返回值:

u8 chosedot(void)
{
	if(tp_dev.sta&TP_PRES_DOWN)			
	{
		if(tp_dev.x[0]>20&&tp_dev.x[0]<100&&tp_dev.y[0]>100&&tp_dev.y[0]<120)
		{
			return 1;
		}
		else
		{
			if(tp_dev.x[0]>20&&tp_dev.x[0]<100&&tp_dev.y[0]>130&&tp_dev.y[0]<150)
			{
				return 2;
			}
			else
			{
				if(tp_dev.x[0]>20&&tp_dev.x[0]<100&&tp_dev.y[0]>160&&tp_dev.y[0]<180)
				{
					return 3;
				}
				else
				{
					if(tp_dev.x[0]>20&&tp_dev.x[0]<100&&tp_dev.y[0]>190&&tp_dev.y[0]<210)
					{
						return 4;
					}
					else
					{
						if(tp_dev.x[0]>20&&tp_dev.x[0]<100&&tp_dev.y[0]>220&&tp_dev.y[0]<240)
						{
							return 5;
						}
						else
						{
							if(tp_dev.x[0]>20&&tp_dev.x[0]<100&&tp_dev.y[0]>250&&tp_dev.y[0]<270)
							{
								return 6;
							}
							else
							{
								if(tp_dev.x[0]>20&&tp_dev.x[0]<100&&tp_dev.y[0]>280&&tp_dev.y[0]<300)
								{
								return 7;
								}
								else
								{
									if(tp_dev.x[0]>20&&tp_dev.x[0]<100&&tp_dev.y[0]>310&&tp_dev.y[0]<330)
									{
										return 8;
									}
									else
										return 0;
								}
							}
						}
					}
				}
			}
		}
	}
}

烧进去看看,好像有问题,屏幕闪烁,程序是不是缺了什么?
缺了延迟,在按下屏幕前一次一次的循环,那加延迟行不行了?也不行,有了延迟扫描频率就降下来了。
我的解决方法是在哪个返回u8的子函数前面加了一直监测触摸信息的循环:

while(!(tp_dev.sta&TP_PRES_DOWN))
	tp_dev.scan(0);

如果没有屏幕按下去的信息,那就一直检测被,什么时候有了什么时候去判断。
这个while和后面最大的if也可以合二为一。

结语

测试以后效果很好,电阻屏其实也有它的优点,价格方面就不说了,它的精确度很高啊,虽然定义的每个区域范围并不大,但是误触的概率还是很小的(根据程序,如果误触到没有定义的地方,返回值为0)。
因为时间问题,例程里面还有检测是否校准,如果没有校准还能自动调用校准函数的代码,我直接把它舍弃了,如果需要校准直接按按钮也行,手动强制调出来。
我也是今天上午才把这个带进去调试出来,如果文章有地方写错了欢迎指正。私信或Email:evandjiang@qq.com

  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Evand J

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值