平台         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中断(松开触摸屏)——>等待触摸屏中断模式(循环)

代码比较简单,不过前面加入了串口的程序用于调试和输出信息

  1. /*************************************************
  2. file name     Touchp
  3. function    Touch Screen test
  4. 硬件平台    mini2440开发板
  5.         索尼X-35触摸屏 3.5寸 240 * 320
  6. problem        串口显示用自己的程序第一个字符有问题,有时不能显示,用参考的
  7.             Uart_Send_String也不行,用可变参数的Uart_printf显示没问题
  8. finishtime    2011-08-11 19:38
  9. 作者        周茂夫
  10. 修改记录    暂无
  11. *************************************************/
  12. #define    GLOBAL_CLK        1

  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "def.h"
  16. #include "option.h"
  17. #include "2440addr.h"
  18. #include "2440lib.h"
  19. #include "mmu.h"

  20. #include <stdarg.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <ctype.h>

  25. #define baudrate 115200

  26. #define wait_down_int()    (rADCTSC = 0xd3)
  27. #define wait_up_int()    (rADCTSC = 0x1d3)
  28. #define mode_auto_xy()    (rADCTSC = 0x0c)
  29. #define Read_Adcdata0()    (int)(rADCDAT0 & 0x3ff)
  30. #define Read_Adcdata1()    (int)(rADCDAT1 & 0x3ff)
  31. #define PRSCVL(n)        ((n)<<6)

  32. static void delay(int times)
  33. {
  34.     int i = 1000 ;
  35.     while(times--)
  36.     {
  37.         for(; i>0; --i)
  38.             ;
  39.     }
  40. }

  41. /***********************************
  42. UART_int初始化led IO端口GPBCON5-8
  43. 初始化GPBHCON为串口通信
  44. 配置串口通信寄存器
  45. 配置中断寄存器
  46. ************************************/
  47. void UART_int_init(void)
  48. {
  49.     /********configuration LED IO port**********/
  50.     rGPBCON &= ~(0xff<<10) ;
  51.     rGPBCON |= 0x55<<10 ;
  52.     
  53.     /*******configuration GPHCON to UART*******/
  54.     rGPHCON &= ~(0xf<<4) ;
  55.     rGPHCON |= 0xa<<4 ;
  56.     
  57.     /****configuration UART0 communication register******/
  58.     rULCON0 = 0x03 ;                        //8-bits,1 stop bit, no parity
  59.     rUCON0 = 0x05 ;
  60.     rUBRDIV0= (int)(PCLK/baudrate/16) -1 ;    //configuration UART baudrate
  61.     
  62.     /*****clean interrupt bit clea RX_INT******/
  63.     rSUBSRCPND |= 0x1 ;
  64.     rSRCPND |= 1<<28 ;
  65.     rINTPND |= 1<<28 ;

  66.     /******open UART interrupt*********/
  67.     rINTSUBMSK &= ~(0x1) ;
  68.     rINTMSK &= ~(0x1<<28) ;    
  69. }

  70. //UART send byte
  71. void UART_send_byte(char Tx_data)
  72. {
  73.     while(!(rUTRSTAT0&0x2)) ;//wait Tx empty
  74.     if(Tx_data == '\n')        //Tx '\n'
  75.     {
  76.         rUTXH0 = 0x0d ;
  77.         while(!(rUTRSTAT0&0x2)) ;
  78.         rUTXH0 = 0x0a ;
  79.     }
  80.     else
  81.     {
  82.         rUTXH0 = Tx_data ;
  83.     }
  84. }
  85. //UART send string
  86. void UART_send_string(const char *str)
  87. {
  88.     while(*str)
  89.     {
  90.         UART_send_byte(*str) ;
  91.         str++ ;
  92.     }
  93. }
  94. //UART receive byte
  95. void UART_receive_byte(void)
  96. {
  97.     char temp ;
  98.     
  99.     while(!(rUTRSTAT0&0x1)) ;    //wait RX ready
  100.     
  101.     temp = rURXH0 ;
  102.     UART_send_byte(temp) ;
  103.     
  104. }

  105. /*******************************************
  106. 中断处理函数
  107. 置1清除中断,注意顺序,先子中断后父中断
  108. 点亮led灯
  109. ********************************************/
  110. void __irq UART0_interrupt(void)
  111. {
  112.     /******clean interrupt bit*************/
  113.     rSUBSRCPND |= 0x1 ;
  114.     rSRCPND |= 1<<28 ;
  115.     rINTPND |= 1<<28 ;
  116.     
  117.     //rGPBDAT &= ~(0xf<<5) ;    //lighten led
  118.     UART_receive_byte();
  119.     /*
  120.     if(temp=='s'||temp=='S')
  121.     {
  122.         ***********Close interrupt*************
  123.         rINTSUBMSK     |= (BIT_SUB_TC) ;
  124.         rINTSUBMSK     |= (BIT_SUB_ADC) ;
  125.         rINTMSK     |= (BIT_ADC) ;
  126.         Uart_Printf("Touch Screen Test is Finished!!!\n") ;
  127.     }    
  128.     */
  129. }

  130. /**************【Touch Screen】****************/
  131. static void Ts_Init(void)
  132. {
  133.     //使能预分频功能 设置A/D时钟 = PCLK/(49+1)
  134.     rADCCON        = (1<<14)|PRSCVL(49);
  135.     rADCDLY        = 50000 ;
  136.     rADCUPDN    = 0x3 ;    //按下 松开 都产生TC中断
  137.         
  138.     /******clean interrupt bit*******/
  139.      rSUBSRCPND    |= BIT_SUB_ADC ;
  140.      rSUBSRCPND    |= BIT_SUB_TC ;
  141.      rSRCPND     |= BIT_ADC ;
  142.     rINTPND     |= BIT_ADC ;

  143.     /***********Open ADC TC interrupt*********/
  144.     rINTSUBMSK     &= ~(BIT_SUB_TC) ;
  145.     rINTSUBMSK     &= ~(BIT_SUB_ADC) ;
  146.     rINTMSK     &= ~(BIT_ADC) ;

  147. }

  148. static void interrupt_Tc(void)
  149. {
  150.     if(rADCDAT0 & 0x8000)
  151.     {
  152.         Uart_Printf("Stylus Up \n\r") ;
  153.         wait_down_int() ;    //wait interrupt mode
  154.     }
  155.     else
  156.     {
  157.         Uart_Printf("Stylus Down: ") ;
  158.         mode_auto_xy() ;     //进入自动转换xy模式
  159.          
  160.          rADCCON |= 1 ;    //start ADC
  161.      }
  162.      /******clean interrupt bit*************/
  163.      rSUBSRCPND    |= BIT_SUB_TC ;
  164.      rSRCPND     |= BIT_ADC ;
  165.     rINTPND     |= BIT_ADC ;
  166. }

  167. static void interrupt_Adc(void)
  168. {
  169.     Uart_Printf("xdata = %4d, ydata = %4d\r\n", Read_Adcdata0(), Read_Adcdata1()) ;    
  170.     
  171.     wait_up_int() ;    //wait 松开触摸屏 中断模式
  172.      
  173.      /******clean interrupt bit*************/
  174.      rSUBSRCPND    |= BIT_SUB_ADC ;
  175.      rSRCPND     |= BIT_ADC ;
  176.     rINTPND     |= BIT_ADC ;    
  177. }

  178. void __irq AdcTsinttrupt(void)
  179. {
  180.     rGPBDAT &= ~(0xf<<5) ;    //lighten led
  181.     
  182.     if(rSUBSRCPND & BIT_SUB_TC)
  183.     {    
  184.         UART_send_string("Tc interrupt\n") ;
  185.         interrupt_Tc() ;    
  186.     }

  187.     if(rSUBSRCPND & BIT_SUB_ADC)
  188.     {        
  189.         UART_send_string("Adc interrupt\n") ;
  190.         interrupt_Adc() ;
  191.     }    
  192. }

  193. static void Ts_test(void)
  194. {
  195.     Ts_Init() ;
  196.     pISR_ADC    = (U32)AdcTsinttrupt ;
  197.     wait_down_int() ;    //wait interrupt mode
  198.     Uart_Printf("Touch Screen test,Please send 's'/'S' stop test\n") ;    
  199. }
  200. /*******************************************************************
  201. 串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。
  202. 首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的
  203. 分频比,确定好PCLK时钟。
  204. ********************************************************************/
  205. int Main(void)
  206. {
  207.     MMU_Init();
  208.     ChangeMPllValue(127,2,1);        //405MHZ
  209.     ChangeClockDivider(13,12); //1:3:6    
  210.     
  211.     UART_int_init() ;
  212.     pISR_UART0 = (U32)UART0_interrupt ;
  213.     //delay(5000) ;
  214.     Uart_SendString("\nUart initial finish!!\n") ;
  215.     Ts_test();
  216.     Uart_Printf("Touch Screen initial finish\n") ;
  217.     while(1)
  218.     {
  219.         
  220.     }
  221.     return 0 ;
  222. }

2011-09-04 11:47

12-30 11:24