- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
—————————————————————————————————————————————————————————
定时器里可以给触摸屏设置多种不同的状态,这里按照 Windows 的情况设置了 down,move
(原文件名:touch.jpg) 头文件:: #ifndef __TOUCH_H__ #define __TOUCH_H__ #include "stm32f10x_lib.h"
u16 Touch_AdjX(u16 ady) //320 { u16 sy=0; int r = ady - TouchXMin; r *= 320; sy=r/(TouchXMax - TouchXMin); if (sy>=320) return 0xFFFF;
第二种是软件滤波,程序读取了 10 次触摸屏的物理坐标,然后冒泡排序,最后去掉最前面的和最后面的,只保留中间 3 个,再对
xl = (xp-xpmin)*LCDXSIZE/(xpmax-xpmin) yl = (yp-ypmin)*LCDYSIZE/(ypmax-ypmin) 定位:
这里定位的作用是求处上面的 xpmin,xpmax,ypmin 和 ypmax,方法就是在屏幕上知道 2 点,求这两点所在直线上的一点(而且知 在屏上分别画出 4 个点,其实 3 个点足以,但是一般都用 4 个点,取得这四个点的物理坐标。假设分别为: | --x1,y1-------------------x2,y2---| --x3,y3-------------------x4,y4---| 对应的物理坐标为 cx1,cy1 利用比例关系 可以求出 xpmin,同样用比例关系 cx2,cy2, cx3,cy3 x1/(cx1-xpmin) x2/(cx2-xpmin) = | cx4,cy4 = x2/(cx2-xpmin) | |
这里按照控制芯片的时序使用管脚模拟 SPI 的方式读出来的,用过 STM32 的 SPI,也可以,不过习惯模拟,不用那么复杂的配置了 (程序见后面部分) 滤波:
这里使用了 2 种方式的滤波,一种是像按键一样,检测到控制芯片 INT 引脚变低之后,延时 20ms,然后如果在检测还是为低,则 (程序见后面部分) 转化: 这个很简单,在任何一个介绍触摸屏的文章估计都能见到。 xp——x 的物理坐标 yp——y 的物理坐标 xl—— x 的逻辑坐标 yl—— y 的逻辑坐标 LCDXSIZE ——LCD 的 x 方向做大值 LCDYSIZE ——LCD 的 y 方向最大值 xpmin —— 在 LCD(0,0)坐标处的 ypmin —— 在 LCD(0,0)坐标处的
最近几天研究了下触摸屏,发现也并不像感觉中的那么神秘。 本人用的触摸屏方案是 4 线电阻屏+xpt2046(这个和 ADS7843 完全一样)。 控制过程主要分一下几步: 1,读数——这里读出来的是触摸屏控制芯片的 AD 值,是屏的物理坐标 2,滤波——触摸屏类似按键,按下和放开时会有抖动 3,转化——把屏的物理坐标转化成逻辑坐标,这里的逻辑坐标在 LCD 的范围内对应 LCD 的像素点坐标。 4,定位——触摸屏的定位,这个其实应该放到最开始。 读数:
—————————————
LCDXSIZE/(xpmax-xpmin)———————————— 这里最好
可以求出 xpmax 然后用同样的方法求出 ypmin 和 ypmax
_____________________________________________________分割线______________________________________________________ 用中断读控制芯片的 INT 引脚还是用定时器读? 用中断比较节省资源,但是我在做一个画图板的时候,发现滑动坐标没办法求出来,于是就去想定时器读。 用定时器读有个好处:延时操作可以在定时器里设置一个标志字,然后如果有按下就置位这个标志,下次再去真正读取。 这样用定时器解决了一个消抖和滑动坐标检测的问题,我选择定时器。 无图无真相,无码无真相:下面是真相
enum { TOUCH_NONE=0, TOUCH_DOWN, TOUCH_MOVE, TOUCH_UP, }; //
#define TOUCH_CLK_LOW() #define TOUCH_CLK_HIGH() #define TOUCH_DOUT_LOW() #define TOUCH_DOUT_HIGH() #define TOUCH_READ_DIN() #define TOUCH_CS_LOW() #define TOUCH_CS_HIGH() #define TOUCH_READ_INT() #define TOUCH_READ_BUSY() #define TOUCH_CHX #define TOUCH_CHY 0x90 0xD0 10
C 文件:: #include "Touch.h" #include "systick.h" #include "Graphics.h"
Biblioteka Baidu
vu16 TouchX, TouchY; vu8 TouchPress=0, TouchState=TOUCH_NONE; //state 有 4 种状态,0 无按键,1 按下,2 抬起,3move u8 TouchCalibrated = 0; u16 TouchXMin, TouchXMax, TouchYMin, TouchYMax; /******************************** 初始化触摸屏需要的端口 芯片--TSC2046 ********************************/ void Touch_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; //EXTI_InitTypeDef EXTI_InitStructure; //NVIC_InitTypeDef NVIC_InitStructure; //SPI_InitTypeDef SPI_InitStructure;
#define TOUCH_GETTIMES
extern vu16 TouchX, TouchY; extern vu8 TouchPress,TouchState; extern u8 TouchCalibrated; void Touch_Init(void); u16 Touch_GetX(void); u16 Touch_GetY(void); void Touch_Calibrate(void); void Touch_GetState(void); #endif
/* Enable GPIOB, GPIOC and AFIO clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOG|RCC_APB2Periph_AFIO, ENABLE); //RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //SPI GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); //SPI_MISO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); /* CS pins configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); /*INI Pin*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOG, &GPIO_InitStructure); /* SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
//RCC_APB
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; SPI_Init(SPI2, &SPI_InitStructure); SPI_Cmd(SPI2,ENABLE); #if 0 EXTI_ClearITPendingBit(EXTI_Line7); GPIO_EXTILineConfig(GPIO_PortSourceGPIOG, GPIO_PinSource7); /* Configure Button EXTI line */ EXTI_InitStructure.EXTI_Line = EXTI_Line7; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); #endif } /*=====================================================================*/ u16 Touch_AdjY(u16 adx) //240 { u16 sx=0; int r = adx - TouchYMin; r *= 240; sx=r / (TouchYMax - TouchYMin); if (sx>=240) return 0xFFFF; return sx; } */ //时钟空闲为低 //上升沿所存
GPIO_ResetBits(GPIOB, GPIO_Pin_13) GPIO_SetBits(GPIOB, GPIO_Pin_13) GPIO_ResetBits(GPIOB, GPIO_Pin_15) GPIO_SetBits(GPIOB, GPIO_Pin_15) GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) GPIO_ResetBits(GPIOB, GPIO_Pin_12) GPIO_SetBits(GPIOB, GPIO_Pin_12) GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_7) GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_8) //差分方式读取