Touch Screen

#Touch.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "2450addr.h"
 
void Touch_Init(void);
 
 
void Touch_Init(void)
{
    rADCDLY = (50000); 
     /* TO DO : prescaler enable, prescaler value=39, Analog no input, 
      *         Normal operation mode, Disable start, No operation */
        rADCCON |= (0x1<<14);
        rADCCON |= (39<<6);
        rADCCON &= ~(0x1<<3);
        rADCCON &= ~(0x1<<2);
        rADCCON &= ~(0x1<<1);
        rADCCON &= ~(0x1);
 
      
     
     /* TO DO :  For Waiting Interrupt Mode rADCTSC=0xd3 */
        rADCTSC &= ~(0x1<<8);
        rADCTSC |= (0x1<<7);
        rADCTSC |= (0x1<<6);
        rADCTSC &= ~(0x1<<5);
        rADCTSC |= (0x1<<4);
        rADCTSC &= ~(0x1<<3);
        rADCTSC &= ~(0x1<<2);
        rADCTSC |= (0x1<<1);
        rADCTSC |= (0x1);
 
}
 
cs


#Main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "2450addr.h"
#include "option.h"
 
#define EXAMPLE 610
 
#if EXAMPLE == 610
//**ISR Declaration
void Touch_ISR(void) __attribute__ ((interrupt ("IRQ")));
 
volatile  int ADC_x, ADC_y;
volatile  int Touch_Pressed=0;
 
void Touch_ISR()
{
    /* 인터럽트 허용하지 않음 on Touch */
    rINTSUBMSK |= (0x1<<9);
    rINTMSK1 |= (0x1<<31);    
    
    /* TO DO: Pendng Clear on Touch */    
    rSUBSRCPND |= (0x1<<9);
    rSRCPND1 |= (0x1<<31);
    rINTPND1 |= (0x1<<31);
 
    if(rADCTSC & 0x100)
    {
        rADCTSC &= (0xff); 
        Touch_Pressed = 0;
        Uart_Send_String("Detect Stylus Up Interrupt Signal \n");
    }
    
    else
    {
        Uart_Send_String(" ISR 내부  \n");
        
        rADCTSC &=~(0x1<<8);                //detect stylus down
        rADCTSC &= ~(0x1<<7);                //set bit for x position measurement
        rADCTSC |= (0x1<<6);                //YM=Hi-z, YP=Hi-z
        rADCTSC |= (0x1<<5);        
        rADCTSC &= ~(0x1<<4);                //XM=VSS,XP=VDD
        rADCTSC &= ~(0x1<<3);                //pull-up EN
        rADCTSC &= ~(0x1<<2);                //Normal-ADC
        rADCTSC &= ~(0x3);
        rADCTSC |= (0x1);                    //X-position = 1
 
 
        /* TO DO : ENABLE_START */        
        rADCCON |= (0x1);
        
        /* wait until End of A/D Conversion */
        while(!(rADCCON & (1<<15)));
        rADCCON &= ~(0x1);                    //Stop Conversion
 
        /*Set ADCTSC reg for Y Conversion*/ 
        ADC_x = (rADCDAT0 & 0x3ff);            //Store X value
        
        rADCTSC |= (0x1<<7);                //YM=VSS, YP=VDD
        rADCTSC &= ~(0x1<<6);
        rADCTSC &= ~(0x1<<5);                //XM=Hi-z, XP=Hi-z
        rADCTSC |= (0x1<<4);
        /* clear and then set  ADCTSC [1:0] for Y Conversion*/
        rADCTSC &= ~(0x3);
        rADCTSC |= (0x2);
    
        rADCCON |= (0x1);                //StartConversion
        while(!(rADCCON & (1<<15)));    //wait untill End of A/D Conversion
 
        ADC_y = (rADCDAT1 & 0x3ff);        //Store y value
        
        Touch_Pressed = 1;
        
        /* TO DO : change to Waiting for interrupt mode 
         *           Stylus Up, YM_out Enable, YP_out Disable, XM_out Disable, XP_out disable
         */
        rADCTSC |= (0x1<<8);
        rADCTSC |= (0x1<<7);
        rADCTSC |= (0x1<<6);
        rADCTSC &= ~(0x1<<5);
        rADCTSC |= (0x1<<4);
        rADCTSC &= ~(0x1<<3);
        rADCTSC &= ~(0x1<<2);
        rADCTSC |= (0x1<<1);
        rADCTSC |= (0x1);
             
    }
    
    /* 인터럽트 다시 허용  on Touch */
    rINTSUBMSK &= ~(0x1<<9);
    rINTMSK1 &= ~(0x1<<31);
    
}
 
void Main(void)
{    
    Uart_Init(115200);
    Touch_Init();    
    
    Uart_Printf("*** Touch Test *** \n");
    
    /* TO DO : 인터럽트 벡터에 Touch_ISR 함수 등록 */
    pISR_ADC = (unsigned int)Touch_ISR;
    
    /* TO DO :  인터럽트 허용 on Touch */
    rINTSUBMSK &= ~(0x1<<9);
    rINTMSK1 &= ~(0x1<<31);    
    
    while(1)
    {
        if(Touch_Pressed)
        {
            Uart_Printf("X : %d, Y: %d \n", ADC_x, ADC_y);    
        }
    }
}
 
#endif 
cs



********************************Touch_Init***************************


ADCDLY : ADC 간격 딜레이를 설정 (5000)

=====================================================================

ECFLG[15] : A/D 변환이 끝났는지 확인하는 비트.

PRSCEN[14] : prescaler 활성화 비트.

PRSCVL[13:6] : A/D 변환기 클럭  prescaler  값. ADC 주파수는 PCLK의 1/5보다 적은 주파수로 할당되어야 한다. 

RESSEL[3] : conversion 되는 디지털 값을 선택(10bit/12bit)

STDBM[2] : Standby mode 선택 비트. Standby 모드가 활성화 되면 현재 진행중인 A/D변환은 멈추게 되고, ADCDAT0와 ADCDAT1은 변환 이전의 데이타를 가지게 된다.

READ_START[1] : A/D변환을 시작시키는 비트이며, 변환 데이터가 읽혀 졌을 때 자동으로 다음 변환을 시작한다. 

ENABLE_START[0] : A/D 변환시작 비트이며 시작 이후에는 클리어된다.  A/D변환 방법은 2가지 방법이 있는데,  만약 READ_START 비트를 사용할 경우에는 이 비트는 의미가 없게 된다. 

=====================================================================



prescaler(프리스케일러) 란?


prescaler는 타이머에 공급하는 입력 클럭의 속도를 조절하는 분주기이다.

분주기라는 말 자체가 의미하듯이 클럭을 쪼갠다는, 즉 속도를 느리게 한다는 말이다.

예를 들어 8MHz의 입력 클럭을 2분주 하면 4MHz가 된다.




==================ADCCON=====================


[14] prescaler (Enalbe) (1)

[13:6] prescaler value를 39 (39)

[3] 10bit resolution (0)

[2] no standby mode (0) //동작 가능

[1] A/D conversion start (0) 

[0] Enable_start no setting (0)


==============================================


==================ADCTSC=====================


[8] Stylus Down (0)

[7] Y- (ON) (1)

[6] Y+ (OFF) (1)

[5] X- (OFF) (0)

[4] X+ (OFF) (1)

[3] Pull-up (ON) (0) //누설전류 방지 ->sleep/stop mode->pull-up스위치 활성화

[2] AUTO_PST(OFF) (0) //ADC conversion 사용을위해 normal ADC conversion

[1:0] Waiting for interrupt mode (1,1)


==============================================




********************************Touch_ISR***************************

start.

rINTSUBMSK(TC)

rINTMSK1(ADC)

비활성화


1. ADCTSC[8]이 stylus up이면 실행 x ,Touch_Pressed =0 설정(출력 x)



2.아니면 stylus down(pen을 종이에 쓸준비)이면 

Y- (OFF) :연결 X

Y+ (OFF) :ADC에 연결

X- (ON) :GND에 연결

X+ (ON) :VCC에 연결


==>X_POSITION 측정


3.rADCCON 0번 bit로 start


4.rADCCON 15번 bit로 A/D 끝났는지 확인(폴링)


5.끝났으면 rADCCON 0번 bit로 stop

X의 position 값은 ADCDAT0에 저장되어 있으므로 변수에 저장


6.

Y- (ON)

Y+ (ON)

X- (OFF)

X+ (OFF)



==>Y_POSITION 측정


3.rADCCON 0번 bit로 start


8.rADCCON 15번 bit로 A/D 끝났는지 확인(폴링)



9.끝났으면 rADCCON 0번 bit로 stop

Y의 position 값은 ADCDAT1에 저장되어 있으므로 변수에 저장


10. Touch_Pressed =1 설정 (출력)


11.

stylus up(pen을 종이에서 땐다)설정

Y-값 측정(ON)

Y+ (OFF)

X- (OFF)

X+ (OFF)

PULL-UP (ON)

Waiting for interrupt mode로 전환


end.

rINTSUBMSK(TC)

rINTMSK1(ADC)

다시 활성화

+ Recent posts