打印

大家一起来探讨stm32触摸屏控制

[复制链接]
8843|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
na239152605|  楼主 | 2012-4-7 18:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
触摸屏驱动有用中断与不用中断之分,校准步骤,校准精度及误差来源,软件实现计算法优化等等。欢迎大家一起讨论讨论啊!
沙发
na239152605|  楼主 | 2012-4-7 19:01 | 只看该作者
先抛个砖吧。软件提供的功能完成以下这些步骤:
1. 配置控制器硬件
2. 判断屏幕是否被触摸
3. 获得稳定的、去抖动的位置测量数据
4. 校准触摸屏
5. 将触摸状态和位置变化信息发送给更高层的图形软件

使用特权

评论回复
板凳
na239152605|  楼主 | 2012-4-7 19:52 | 只看该作者
大家帮帮忙嘛!顶起嘛!每人聊一点自己感悟嘛!拜托了!!!!!!!!!!!

使用特权

评论回复
地板
na239152605|  楼主 | 2012-4-7 19:58 | 只看该作者
触摸屏算法.pdf (118.94 KB)

使用特权

评论回复
5
tcc8073| | 2012-4-7 20:13 | 只看该作者
都有例子的,仔细体会例子精神,能力上去了再改

使用特权

评论回复
6
na239152605|  楼主 | 2012-4-7 21:09 | 只看该作者
5# tcc8073 大家交流哈多好啊!交流才有进步嘛!

使用特权

评论回复
7
logokfu| | 2012-4-7 23:12 | 只看该作者
帮顶!

使用特权

评论回复
8
shj106| | 2012-4-8 08:43 | 只看该作者
学习

使用特权

评论回复
9
na239152605|  楼主 | 2012-4-10 16:52 | 只看该作者
哎没什么人响应啊!我把我的触摸屏程序上传吧!
#include"touch.h"
#include"spi.h"
#include"lcd.h"
#include "systickdelay.h"
#include "stm32f10x_sdio.h"
#include "math.h"

uint8_t  cnt=0;
/**********************************************************
* @brief  Touch_Init             初始化触摸屏需要的端口
* @param  None                 
* @retval None            芯片--TSC2046
*********************************************************/
void Touch_IO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
     
    /********* Enable  GPIOC and AFIO clock *************/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);  

    /********SPI_MOSI(TDIN),CLK,CS *********************/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_3|GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    /********SPI_MISO(DOUT),PEN *********************/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

        /********初始化变量 EXTI_InitStructure *********/
          EXTI_StructInit(&EXTI_InitStructure);
        /********将EXIT线1连接到PC1 *****************/
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);
        /********配置EXTI线1上出现下降沿,则产生中断 ******/
        EXTI_InitStructure.EXTI_Line=EXTI_Line1;
        EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
        EXTI_InitStructure.EXTI_LineCmd=ENABLE;
        EXTI_Init(&EXTI_InitStructure);

//        /**********设置优先级分组:先占优先级2位,从优先级2位****/
//        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);       
           /********** Enable EXTI1 *****************/
           NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;
           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
           NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
           NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
           NVIC_Init(&NVIC_InitStructure);

}
/**********************************************************
* @brief  EXTI_OPEN   开中断   
* @param  None                 
* @retval None            
*********************************************************/
void EXTI_OPEN(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;

        EXTI_InitStructure.EXTI_Line=EXTI_Line1;
        EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
        EXTI_InitStructure.EXTI_LineCmd=ENABLE;
        EXTI_Init(&EXTI_InitStructure);
//        EXTI->IMR|=1<<1;
}

/**********************************************************
* @brief  EXTI_CLOSE   关中断   
* @param  None                 
* @retval None            
*********************************************************/
void EXTI_CLOSE(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;

        EXTI_InitStructure.EXTI_Line=EXTI_Line1;
        EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
        EXTI_InitStructure.EXTI_LineCmd=DISABLE;
        EXTI_Init(&EXTI_InitStructure);
//        EXTI->IMR&=~(1<<1);
}

/**********************************************************
* @brief  Drow_Touch_Point    画一个触摸点,用来校准用的
* @param  x : 横坐标
*         y :纵坐标                 
* @retval None            
*********************************************************/
void Drow_Touch_Point(uint8_t x,uint16_t y)
{
        LCD_DrawLine(x-12,y,x+13,y);//横线
        LCD_DrawLine(x,y-12,x,y+13);//竖线
        LCD_DrawPoint(x+1,y+1);
        LCD_DrawPoint(x-1,y+1);
        LCD_DrawPoint(x+1,y-1);
        LCD_DrawPoint(x-1,y-1);
        Draw_Circle(x,y,6);//画中心圈
}

/**********************************************************
* @brief  Draw_Big_Point     画一个大点  2*2的点
* @param  None                 
* @retval None            
*********************************************************/                  
void Draw_Big_Point(uint8_t x,uint16_t y)
{            
        LCD_DrawPoint(x,y);//中心点
        LCD_DrawPoint(x+1,y);
        LCD_DrawPoint(x,y+1);
        LCD_DrawPoint(x+1,y+1);                          
}

/**********************************************************
* @brief  Convert_Pos     转换结果像素坐标        
* @param  None    根据触摸屏的校准参数来决定转换后的结果,保存在X0,Y0中            
* @retval None            
*********************************************************/
void Convert_Pos(void)
{                           
        Pen_Point.X0=240-(Pen_Point.xfac*Pen_Point.X+Pen_Point.xoff);
        Pen_Point.Y0=320-(Pen_Point.yfac*Pen_Point.Y+Pen_Point.yoff);  
}         
/**********************************************************
* @brief  Touch_Adjust      触摸屏校准代码      
* @param  None                 
* @retval None            
*********************************************************/
void Touch_Adjust(void)
{
        uint16_t pos_temp[4][2];//坐标缓存值       
        float d1,d2,fac;
        uint32_t tem1,tem2;                                          
//        POINT_COLOR=BLUE;
        BACK_COLOR =WHITE;
        LCD_Clear(WHITE);//清屏   
        POINT_COLOR=RED;//红色
//        LCD_Clear(WHITE);//清屏
        Drow_Touch_Point(20,20); //画点1
        //用来标记是否校准过,所以校准之前必须清掉!以免错误
        Pen_Point.xfac=0;         
        Pen_Point.yfac=0;
        Pen_Point.xoff=0;
        Pen_Point.yoff=0;
        while(cnt!=5)
        {                                                                           
                pos_temp[cnt][0]=Pen_Point.X;
                pos_temp[cnt][1]=Pen_Point.Y;                 
                switch(cnt)
                {                          
                        case 1:
                                LCD_Clear(WHITE);//清屏
                                Drow_Touch_Point(220,20);//画点2
                                break;
                        case 2:
                                LCD_Clear(WHITE);//清屏
                                Drow_Touch_Point(20,300);//画点3
                                break;
                        case 3:
                                LCD_Clear(WHITE);//清屏
                                Drow_Touch_Point(220,300);//画点4
                                break;
                        case 4:         //全部四个点已经得到
                        //对边相等
                                tem1=fabs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2
                                tem2=fabs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2
                                tem1*=tem1;
                                tem2*=tem2;
                                d1=sqrt(tem1+tem2);//得到1,2的距离
                               
                                tem1=fabs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4
                                tem2=fabs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4
                                tem1*=tem1;
                                tem2*=tem2;
                                d2=sqrt(tem1+tem2);//得到3,4的距离
                                fac=(float)d1/d2;
                                if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格
                                {
                                        cnt=0;
                                        LCD_Clear(WHITE);//清屏
                                        Drow_Touch_Point(20,20);
                                        continue;
                                }
                                tem1=fabs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3
                                tem2=fabs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3
                                tem1*=tem1;
                                tem2*=tem2;
                                d1=sqrt(tem1+tem2);//得到1,3的距离
                               
                                tem1=fabs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4
                                tem2=fabs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4
                                tem1*=tem1;
                                tem2*=tem2;
                                d2=sqrt(tem1+tem2);//得到2,4的距离
                                fac=(float)d1/d2;
                                if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格
                                {
                                        cnt=0;
                                        LCD_Clear(WHITE);//清屏
                                        Drow_Touch_Point(20,20);
                                        continue;
                                }//正确了                                                  
                                //对角线相等
                                tem1=fabs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3
                                tem2=fabs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3
                                tem1*=tem1;
                                tem2*=tem2;
                                d1=sqrt(tem1+tem2);//得到1,4的距离

                                tem1=fabs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4
                                tem2=fabs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4
                                tem1*=tem1;
                                tem2*=tem2;
                                d2=sqrt(tem1+tem2);//得到2,3的距离
                                fac=(float)d1/d2;
                                if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格
                                {
                                        cnt=0;
                                        LCD_Clear(WHITE);//清屏
                                        Drow_Touch_Point(20,20);
                                        continue;
                                }//正确了
                                //计算结果
                                Pen_Point.xfac=(float)200/(pos_temp[1][0]-pos_temp[0][0]);//得到xfac                 
                                Pen_Point.xoff=(240-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff
                                          
                                Pen_Point.yfac=(float)280/(pos_temp[2][1]-pos_temp[0][1]);//得到yfac
                                Pen_Point.yoff=(320-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff  

                                POINT_COLOR=BLUE;
                                LCD_Clear(WHITE);//清屏
                                LCD_ShowString(35,110,"Touch Screen Adjust OK!");//校正完成
                                delay_ms(500);
                                LCD_Clear(WHITE);//清屏   
                                return;//校正完成                                 
                }
        }
}
/**********************************************************
* @brief  Load_Drow_Dialog   显示清屏区域      
* @param  None                 
* @retval None            
*********************************************************/
void Load_Drow_Dialog(void)
{
        LCD_Clear(WHITE);//清屏   
        POINT_COLOR=BLUE;//设置字体为蓝色
        LCD_ShowString(216,0,"RST");//显示清屏区域
          POINT_COLOR=RED;//设置画笔蓝色
}





#ifndef _TOUCH_H
#define _TOUCH_H

#include"stm32f10x.h"


/*********笔杆结构体  **********************/
typedef struct
{
        uint16_t X0;//原始坐标
        uint16_t Y0;
        uint16_t X; //最终/暂存坐标 即 物理坐标
        uint16_t Y;                                                               
                                  
        float xfac;          //触摸屏校准参数
        float yfac;
        short xoff;
        short yoff;
}Pen_Holder;
extern Pen_Holder Pen_Point;

/********* 初始化触摸屏需要的端口 *************/
void Touch_IO_Init(void);
/********* 画一个触摸点,用来校准用的 *************/
void Drow_Touch_Point(uint8_t x,uint16_t y);
/********* 触摸屏校准代码 **********************/
void Touch_Adjust(void);
/********* 关外部中断 **********************/
void EXTI_CLOSE(void);
/********* 开外部中断  **********************/
void EXTI_OPEN(void);
/*********转换结果像素坐标 **********************/
void Convert_Pos(void);
/*********显示清屏区域  **********************/
void Load_Drow_Dialog(void);
/*********画一个大点  2*2的点  **********************/
void Draw_Big_Point(uint8_t x,uint16_t y);

#endif

触摸屏基础知识大全.pdf

1.19 MB

使用特权

评论回复
10
wang1987| | 2012-10-23 23:10 | 只看该作者
学习了,最近正在用这个!

使用特权

评论回复
11
dfsa| | 2012-10-24 07:31 | 只看该作者
鼓励多交流

使用特权

评论回复
12
秋天落叶| | 2012-10-24 07:42 | 只看该作者
LZ可以多分享一些有关stm32触摸屏控制的经验

使用特权

评论回复
13
hsbjb| | 2012-10-24 07:51 | 只看该作者
最近也在做这方面的开发,多讨论

使用特权

评论回复
14
yzmvv| | 2013-1-9 22:21 | 只看该作者
感谢楼主的基础知识大全,刚刚接触,了解后一定来参与讨论

使用特权

评论回复
15
dfsa| | 2013-1-9 22:37 | 只看该作者
可以共享一下相关的开发经验

使用特权

评论回复
16
yybj| | 2013-1-9 23:08 | 只看该作者
响应的人还是太少

使用特权

评论回复
17
xiloujushi| | 2013-3-7 09:13 | 只看该作者
mark

使用特权

评论回复
18
Lin-811| | 2013-4-26 22:28 | 只看该作者
最近被触摸搞的头破血流啊。。。

使用特权

评论回复
19
yybj| | 2013-4-26 23:10 | 只看该作者
鼓励多讨论

使用特权

评论回复
20
jiayongli| | 2013-6-5 16:05 | 只看该作者
我这几天也是被触摸搞的头破血流啊。。。可恨的TSC2046

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

212

帖子

1

粉丝