C语言驱动之配置触摸屏(基于S3C2440开发板)

这是tsc.c文件

#include"s3c2440.h"
#include"tsc.h"
#include"lcd.h"
#include"irq.h"
#include "graphics.h"
#include "type.h"
#include <math.h>


#define TSC_WAIT_DOWN    (0xd3)//等待按下中断
#define    TSC_WAIT_UP        (0x1d3)//等待抬起中断
#define TSC_AUTO_XY        (0xc)    //自动X Y轴采样

//设置常见的寄存器参数
#define PRSCVL        (49<<6)    //预分频值,ADCCLK = PCLK/(PRSCVL+1)<2.5M,现在设置为1MHZ
#define PRSCEN        (1<<14)    //预分频使能位
#define ADCCON_VAL    (PRSCVL | PRSCEN)  //其他位不设置

//设置消除抖动延时
//X-Tal = 3.6864MHZ,实际工作的时候
#define DELAY1    (36864)    //默认消除抖动延时10ms,所以 DELAY1=10ms*X-Tal=10/1000 * 3.6864MHZ

//采样转换延时,采用PCLK,同时等待时间 > 5个周期的ADCCLK 也就是时间>1/1MHZ*5*2=10us
//在实际的测量环境中,长一点测量的值比较稳定,但是过长会导致出现抬起的时候被采样到,所以一般设置值 100us-5ms
//这边设置成1ms左右
#define DELAY2       (4000)//这个可以调整的

#define Y_BEGIN (165)
#define X_BEGIN (947)    //变大往右,变小往左

#define Y_END (878)
#define X_END (80)    //变大往右,变小往左


#define    TSP_SAMPLE_NUM    8    //采样点数
#define    TSP_INVALIDLIMIT    10    //有效分布范围
#define    TSP_CHANGE            20    //前后点有效具体范围

#define PLENGTH(x1,y1,x2,y2) sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))

int touch_optimize(int x[],int y[],int *px,int *py)
{
    int dx,dy;
    int j,k,temp;

    //------------------------------------------------
    // if mask it ,very tremble work not well
    for(j=0;j < TSP_SAMPLE_NUM-1;++j)
    {
        for(k=j+1;k < TSP_SAMPLE_NUM;++k)
        {
            if(x[j]>x[k])
            {
                temp = x[j];
                x[j] = x[k];
                x[k] = temp;
            }
            if(y[j]>y[k])
            {
                temp = y[j];
                y[j] = y[k];
                y[k] = temp;    
            }
        }
    }
    //概率分布权重法
    *px = (x[2] + ((x[3]+x[4])<<1) + (x[3]+x[4]) + x[5]);
    *py = (y[2] + ((y[3]+y[4])<<1) + (y[3]+y[4]) + y[5]);

    if((*px & 0x7) > 3)
        *px = (*px >> 3)+1;
    else
        *px = (*px >> 3);

    if((*py & 0x7) > 3)
        *py = (*py >> 3)+1;
    else
        *py = (*py >> 3);

    dx = x[5] - x[2];
    dy = y[5] - y[2];

    return ((dx > TSP_INVALIDLIMIT || dy > TSP_INVALIDLIMIT) ? 0 : 1);
}


void tsc2pos(pos_t *pPos)
{
    pPos->x = min(pPos->x,X_BEGIN);
    pPos->x = max(pPos->x,X_END);

    pPos->y = min(pPos->y,Y_END);//注意    X和Y 不同
    pPos->y = max(pPos->y,Y_BEGIN);

    //坐标转换
    pPos->x = (LCD_WIDTH-1)*(X_BEGIN - pPos->x) / (X_BEGIN - X_END);
    pPos->y = (LCD_HIGH-1)*(pPos->y - Y_BEGIN) / (Y_END - Y_BEGIN);
}


int tsc_adc(pos_t *pPos)
{
    int x[TSP_SAMPLE_NUM],y[TSP_SAMPLE_NUM];
    int i,px,py;
    static pos_t old;

    if(!(ADCDAT0 & (1<<15)))
    {
        for(i=0;i<TSP_SAMPLE_NUM;i++)
        {
            //1 设置AUT0 XY采样模式
            ADCTSC =  TSC_AUTO_XY;
            
            //2 设置采样的延时时间
            ADCDLY = DELAY2;
        
            //3 开启采样开关
            ADCCON |= (1 << 0);
        
            //4 等待采样结束
            while(ADCCON & 0X1);
            while(!(ADCCON & (1 << 15)));//等待采样结束
        
            //5 存储数据,拿来计算  
            x[i] = (ADCDAT1 & 0x3ff);
            y[i] = (ADCDAT0 & 0x3ff);
        }
        
        //6    恢复抬起中断模式
        ADCTSC = TSC_WAIT_UP;
        
        //采样转换优化,采用概率分布校准
        if(touch_optimize(x,y,&px,&py))
        {
            pPos->x = px;
            pPos->y = py;
            tsc2pos(pPos);
            if(old.x == 0 && old.y ==0)
            {
                old = *pPos;
                return 1;
            }
            else if(PLENGTH(old.x,old.y,pPos->x,pPos->y)< TSP_CHANGE)
            {
                old = *pPos;
                return 1;
            }
        }

    }        
    else
    {
        old.x = 0;
        old.y = 0;
    }
    return 0;    
}

static void tsc_updn_irq(void)
{
    
    if(ADCDAT0 & (1<<15))//抬起状态
    {
           ADCTSC =  TSC_WAIT_DOWN;
     //      lcd_clean(0,0,480,272,GREEN);
    }
    else//按下状态
    {
        ADCTSC = TSC_WAIT_UP;
//        lcd_clean(0,0,480,272,GREEN);
    }
}

void tsc_init(void)
{
    //1 设置ADCCON,设置转换器的AD频率
    ADCCON = ADCCON_VAL;

    //2 设置触摸屏为等待按下中断模式
    ADCTSC = TSC_WAIT_DOWN;

    //3 设置消除抖动延时
    ADCDLY =  DELAY1;
    
    //4 安装触摸屏中断
    irq_install(IRQ_SUB_TC,tsc_updn_irq); 
}

--------------------------------------------------------------华丽的分割线----------------------------------------------------------------------

这是tsc.h文件

#ifndef _TOUCH_H_
#define _TOUCH_H_

#include "snake.h"

void tsc_init(void);
int tsc_adc(pos_t *pPos);

#endif

猜你喜欢

转载自blog.csdn.net/Gaodes/article/details/81775993