平台 mini2440
触摸屏 索尼x-35 3.5寸触摸屏
1.0、触摸屏与lcd
触摸屏与lcd是俩个独立的屏在lcd中已经讲过了,但是这里在提一下,主要是涉及到一个触摸屏校正的问题,我以前一直很是不解我手指点的什么东西电脑是怎么知道的,直到我弄触摸屏的时候在明白,原来是因为lcd与触摸屏分开但是他们之间有对应关系,简单的说就是一个触摸屏的坐标点对应lcd的一个像素点,这样当我们按下触摸屏后,系统通过计算得到该地方的坐标,然后通过对应关系找到相应位置的lcd显示的内容。因为触摸屏和lcd是独立的,总是因为一些物理的原因会有一些位置上的改变,所以这种对应关系不是不变的,我们可以通过开机的时候的校验来确定这种关系,比如(下面是引用赵老师的)
LCD上每个点PD的坐标为[XD,YD],触摸屏上每个点PT的坐标为[XT,YT]。要实现触摸屏上的坐标转换为LCD上的坐标,需要下列公式进行转换:
XD=A×XT+B×YT+C
YD=D×XT+E×YT+F
这样我们只有确定了ABCDEF六个参数我们就可以确定这种对应关系了,其他的点就都可以对应了。这就是触摸屏校验的原理,因为我没有去弄,所以就不多说了。2.0、电阻触摸屏的原理
这个的话说简单就简单说复杂就复杂,简单的说的话通过X方向和Y方向的分开的电阻线,当你按下触摸屏的时候XY就有一个触点,然后通过计算在XY方向的分压值,在把电压值经过AD转换后即可得到xy的坐标。复杂的话这个就说不清啦,就我知道的这点东西,呵呵,不过很多东西都不需要我们自己去算了,2440触摸屏有这些功能了只有我们去设置寄存器就可以了,像设置思想哦那个x/y坐标转换模式后,系统就自动转换出触点的xy坐标值了。
3.0、触摸屏的流程
触摸屏的流程我觉得是整个触摸屏比较重要的地方,其他的设置好寄存器之后读数据就可以了。流程中比较重要的是俩个中断,触摸屏中断和ADC中断,其中触摸屏中断包括触摸屏按下中断和触摸屏松开中断。
初始化中断和寄存器——>等待触摸屏中断模式——>TC中断(触摸屏按下中断)——>(进入xy自动转换模式)——>(ADC转换完成后)ADC中断——>(松开触摸屏)——>TC中断(松开触摸屏)——>等待触摸屏中断模式(循环)
代码比较简单,不过前面加入了串口的程序用于调试和输出信息
- /*************************************************
- file name Touchp
- function Touch Screen test
- 硬件平台 mini2440开发板
- 索尼X-35触摸屏 3.5寸 240 * 320
- problem 串口显示用自己的程序第一个字符有问题,有时不能显示,用参考的
- Uart_Send_String也不行,用可变参数的Uart_printf显示没问题
- finishtime 2011-08-11 19:38
- 作者 周茂夫
- 修改记录 暂无
- *************************************************/
- #define GLOBAL_CLK 1
- #include <stdlib.h>
- #include <string.h>
- #include "def.h"
- #include "option.h"
- #include "2440addr.h"
- #include "2440lib.h"
- #include "mmu.h"
- #include <stdarg.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #define baudrate 115200
- #define wait_down_int() (rADCTSC = 0xd3)
- #define wait_up_int() (rADCTSC = 0x1d3)
- #define mode_auto_xy() (rADCTSC = 0x0c)
- #define Read_Adcdata0() (int)(rADCDAT0 & 0x3ff)
- #define Read_Adcdata1() (int)(rADCDAT1 & 0x3ff)
- #define PRSCVL(n) ((n)<<6)
- static void delay(int times)
- {
- int i = 1000 ;
- while(times--)
- {
- for(; i>0; --i)
- ;
- }
- }
- /***********************************
- UART_int初始化led IO端口GPBCON5-8
- 初始化GPBHCON为串口通信
- 配置串口通信寄存器
- 配置中断寄存器
- ************************************/
- void UART_int_init(void)
- {
- /********configuration LED IO port**********/
- rGPBCON &= ~(0xff<<10) ;
- rGPBCON |= 0x55<<10 ;
-
- /*******configuration GPHCON to UART*******/
- rGPHCON &= ~(0xf<<4) ;
- rGPHCON |= 0xa<<4 ;
-
- /****configuration UART0 communication register******/
- rULCON0 = 0x03 ; //8-bits,1 stop bit, no parity
- rUCON0 = 0x05 ;
- rUBRDIV0= (int)(PCLK/baudrate/16) -1 ; //configuration UART baudrate
-
- /*****clean interrupt bit clea RX_INT******/
- rSUBSRCPND |= 0x1 ;
- rSRCPND |= 1<<28 ;
- rINTPND |= 1<<28 ;
- /******open UART interrupt*********/
- rINTSUBMSK &= ~(0x1) ;
- rINTMSK &= ~(0x1<<28) ;
- }
- //UART send byte
- void UART_send_byte(char Tx_data)
- {
- while(!(rUTRSTAT0&0x2)) ;//wait Tx empty
- if(Tx_data == '\n') //Tx '\n'
- {
- rUTXH0 = 0x0d ;
- while(!(rUTRSTAT0&0x2)) ;
- rUTXH0 = 0x0a ;
- }
- else
- {
- rUTXH0 = Tx_data ;
- }
- }
- //UART send string
- void UART_send_string(const char *str)
- {
- while(*str)
- {
- UART_send_byte(*str) ;
- str++ ;
- }
- }
- //UART receive byte
- void UART_receive_byte(void)
- {
- char temp ;
-
- while(!(rUTRSTAT0&0x1)) ; //wait RX ready
-
- temp = rURXH0 ;
- UART_send_byte(temp) ;
-
- }
- /*******************************************
- 中断处理函数
- 置1清除中断,注意顺序,先子中断后父中断
- 点亮led灯
- ********************************************/
- void __irq UART0_interrupt(void)
- {
- /******clean interrupt bit*************/
- rSUBSRCPND |= 0x1 ;
- rSRCPND |= 1<<28 ;
- rINTPND |= 1<<28 ;
-
- //rGPBDAT &= ~(0xf<<5) ; //lighten led
- UART_receive_byte();
- /*
- if(temp=='s'||temp=='S')
- {
- ***********Close interrupt*************
- rINTSUBMSK |= (BIT_SUB_TC) ;
- rINTSUBMSK |= (BIT_SUB_ADC) ;
- rINTMSK |= (BIT_ADC) ;
- Uart_Printf("Touch Screen Test is Finished!!!\n") ;
- }
- */
- }
- /**************【Touch Screen】****************/
- static void Ts_Init(void)
- {
- //使能预分频功能 设置A/D时钟 = PCLK/(49+1)
- rADCCON = (1<<14)|PRSCVL(49);
- rADCDLY = 50000 ;
- rADCUPDN = 0x3 ; //按下 松开 都产生TC中断
-
- /******clean interrupt bit*******/
- rSUBSRCPND |= BIT_SUB_ADC ;
- rSUBSRCPND |= BIT_SUB_TC ;
- rSRCPND |= BIT_ADC ;
- rINTPND |= BIT_ADC ;
- /***********Open ADC TC interrupt*********/
- rINTSUBMSK &= ~(BIT_SUB_TC) ;
- rINTSUBMSK &= ~(BIT_SUB_ADC) ;
- rINTMSK &= ~(BIT_ADC) ;
- }
- static void interrupt_Tc(void)
- {
- if(rADCDAT0 & 0x8000)
- {
- Uart_Printf("Stylus Up \n\r") ;
- wait_down_int() ; //wait interrupt mode
- }
- else
- {
- Uart_Printf("Stylus Down: ") ;
- mode_auto_xy() ; //进入自动转换xy模式
-
- rADCCON |= 1 ; //start ADC
- }
- /******clean interrupt bit*************/
- rSUBSRCPND |= BIT_SUB_TC ;
- rSRCPND |= BIT_ADC ;
- rINTPND |= BIT_ADC ;
- }
- static void interrupt_Adc(void)
- {
- Uart_Printf("xdata = %4d, ydata = %4d\r\n", Read_Adcdata0(), Read_Adcdata1()) ;
-
- wait_up_int() ; //wait 松开触摸屏 中断模式
-
- /******clean interrupt bit*************/
- rSUBSRCPND |= BIT_SUB_ADC ;
- rSRCPND |= BIT_ADC ;
- rINTPND |= BIT_ADC ;
- }
- void __irq AdcTsinttrupt(void)
- {
- rGPBDAT &= ~(0xf<<5) ; //lighten led
-
- if(rSUBSRCPND & BIT_SUB_TC)
- {
- UART_send_string("Tc interrupt\n") ;
- interrupt_Tc() ;
- }
- if(rSUBSRCPND & BIT_SUB_ADC)
- {
- UART_send_string("Adc interrupt\n") ;
- interrupt_Adc() ;
- }
- }
- static void Ts_test(void)
- {
- Ts_Init() ;
- pISR_ADC = (U32)AdcTsinttrupt ;
- wait_down_int() ; //wait interrupt mode
- Uart_Printf("Touch Screen test,Please send 's'/'S' stop test\n") ;
- }
- /*******************************************************************
- 串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。
- 首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的
- 分频比,确定好PCLK时钟。
- ********************************************************************/
- int Main(void)
- {
- MMU_Init();
- ChangeMPllValue(127,2,1); //405MHZ
- ChangeClockDivider(13,12); //1:3:6
-
- UART_int_init() ;
- pISR_UART0 = (U32)UART0_interrupt ;
- //delay(5000) ;
- Uart_SendString("\nUart initial finish!!\n") ;
- Ts_test();
- Uart_Printf("Touch Screen initial finish\n") ;
- while(1)
- {
-
- }
- return 0 ;
- }
2011-09-04 11:47