■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)
다시 활성화
'ARM Device' 카테고리의 다른 글
[ARM 디바이스 제어_Day6~10]Mini_project-무한의 계단 게임 (0) | 2018.11.23 |
---|---|
[ARM 디바이스 제어_Day4]DMA+Timer,DMA+Uart (0) | 2018.11.18 |
[ARM 디바이스 제어_Day3]DMA (0) | 2018.11.18 |
[ARM 디바이스 제어_Day2]key, Uart interrupt (0) | 2018.11.18 |
[ARM 디바이스 제어_Day1]Timer (0) | 2018.11.18 |