S3C6410 bare metal resistive screen driver

Publisher:bobojrtLatest update time:2017-02-26 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Compiled using RVDS4.0

We mainly look at how to configure the mode

I have been using automatic X, Y sampling before, but the readings were not accurate. Finally, the sampling was separated and it worked. It should be noted that after enabling ADC reading, the conversion result register needs to be read first, but at this time, the last conversion result is read. If it is a continuous reading, it is necessary to wait for the conversion to complete, otherwise the conversion result will be inaccurate.

 

adc.c


  1. /****************************************************** *************************************************** ********** 

  2.  * File name: ADC.c 

  3.  * Function: S3C6410 ADC bottom-level driver function 

  4.  * Author: cp1300@139.com 

  5.  * Created: March 12, 2012 21:05 

  6.  * Last modified: March 12, 2012 

  7.  * Details: Touch screen driver and related ADC driver 

  8.  * Question: There has always been a misunderstanding. I always thought that after using the start read operation, I could read the converted data each time after reading the DAT register. Eventually, I found that after using this, I could only read the previous data. 

  9.  * You still need to wait until the conversion is complete, otherwise the data will be very messy when converting continuously. 

  10.  * Now use manual control to start the conversion 

  11. *************************************************** *************************************************** *********/  

  12. #include "system.h"  

  13. #include "ADC.h"  

  14.   

  15.   

  16.   

  17.   

  18. //ADC control register ADCCON  

  19. #define ADCCON_RESSEL_12BIT (1 << 16) //12-bit mode  

  20. #define ADCCON_ECFLG (0 << 15) //A/D conversion end flag read only;  

  21. #define ADCCON_PRSCEN (1 << 14) //A/D converter prescaler enable  

  22. #define ADCCON_PRSCVL (32 << 6) //Prescaler value, 1-255, scaler value + 1, at least 1/5 of PCLK, PCLK = 66MHZ, fastest conversion at 2.5MHZ clock  

  23. #define ADCCON_SEL_MUX (0 << 3) //Select channel 0 by default  

  24. #define ADCCON_STDBM (0 << 2) //Normal mode  

  25. #define ADCCON_READ_START (0 << 1) // Turn off the start of the read operation  

  26. #define ADCCON_ENABLE_START (0 << 0) //If READ_START is enabled, this value is invalid.  

  27.   

  28.   

  29. //ADCDLY  

  30. #define ADCDLY_DELAY 500 //Automatic sampling delay time,  

  31.   

  32.   

  33.   

  34. /****************************************************** *************************************************** ************************ 

  35. *Function: void SetADC_Channel(u8 ch) 

  36. *Function: Set ADC input channel 

  37. *Parameter: ch: channel number, 0-7 

  38. *Return: None 

  39. *Depends on: underlying macro definitions 

  40. *Author : cp1300@139.com 

  41. *Time : 20120513 

  42. *Last modified: 20120513 

  43. *Description: ADC input channel selection 

  44. *************************************************** *************************************************** *********************/  

  45. void SetADC_Channel(u8 ch)  

  46. {  

  47.     ADC->CON &= ~(7 << 3); //Clear channel  

  48.     ADC->CON |= ch & (0x07); //Set channel number  

  49. }  

  50.   

  51.   

  52.   

  53. /****************************************************** *************************************************** ************************ 

  54. *Function: void ADC_Init(void) 

  55. *Function: ADC initialization 

  56. *Parameters: None 

  57. *Return: None 

  58. *Depends on: underlying macro definitions 

  59. *Author : cp1300@139.com 

  60. *Time : 20120312 

  61. *Last modified: 20120313 

  62. *Description: ADC initialization 

  63. *************************************************** *************************************************** *********************/  

  64. void ADC_Init(void)  

  65. {  

  66.     //ADC control register configuration; 12BIT mode  

  67.     ADC->CON = ADCCON_RESSEL_12BIT + ADCCON_ECFLG + ADCCON_PRSCEN + ADCCON_PRSCVL + ADCCON_SEL_MUX + ADCCON_STDBM + ADCCON_READ_START + ADCCON_ENABLE_START;  

  68.     ADC->DLY = ADCDLY_DELAY; //Set automatic interval sampling time  

  69. }  

  70.   

  71.   

  72. /****************************************************** *************************************************** ************************ 

  73. *Function: void ADC_SetMode(u8 Mode) 

  74. *Function: Set ADC mode 

  75. *Parameters: None 

  76. *Return: None 

  77. *Depends on: underlying macro definitions 

  78. *Author : cp1300@139.com 

  79. *Time : 20120313 

  80. *Last modified: 20120313 

  81. *Description: Set ADC mode 

  82. *************************************************** *************************************************** *********************/  

  83. void ADC_SetMode(u8 Mode)  

  84. {  

  85.     ADC->TSC &= (1 << 8); // Clear the previous settings  

  86.     ADC->CON &= ~BIT2; //Exit standby mode  

  87.     XP_UP_DISABLE(); //XP pull-up disabled  

  88.     Normal_ADC_Mode(); //Normal ADC mode  

  89.     switch(Mode)  

  90.     {  

  91.         case COMMON_AD_MODER: //Common ADC mode  

  92.             Normal_ADC_Mode();break;  

  93.         case ASUNDER_X_MODER: //Separate X scan mode  

  94.         {  

  95.             ADCTSC_XP_VDD();  

  96.             ADCTSC_XM_GND();  

  97.             ADCTSC_YP_HZ();  

  98.             ADCTSC_YM_HZ();  

  99.             X_PosMode();  

  100.         }break; //XP=external power,XM=GND,YP=AIN5,YM=high impedance  

  101.         case ASUNDER_Y_MODER: //Separate Y scan mode  

  102.         {  

  103.             ADCTSC_XP_HZ();  

  104.             ADCTSC_XM_HZ();  

  105.             ADCTSC_YP_VDD();  

  106.             ADCTSC_YM_GND();  

  107.             Y_PosMode();  

  108.         }break; //XP=AIN7,XM=high impedance,YP=external power,YM=GND  

  109.         case AUTO_XY_MODER: //Automatic XY scanning mode  

  110.         {  

  111.             AUTO_XYPosition();  

  112.         }break;  

  113.         case INT_AD_MODER: //wait for interrupt mode  

  114.         {  

  115.             ADCTSC_XP_HZ();  

  116.             ADCTSC_XM_HZ();  

  117.             ADCTSC_YP_HZ();  

  118.             ADCTSC_YM_GND();  

  119.             XP_UP_ENABLE(); //XP pull-up enable              

  120.             INT_WaitingMode();  

  121.         }break; //XP pull-up, XM = high impedance, YP = AIN5, YM = GND  

  122.         case STANDBY_AD_MODER: //Power-down mode  

  123.             StandbyMode();break;  

  124.         default:break;  

  125.     }  

  126. }  

  127.   

  128.   

  129.   

  130. /****************************************************** *************************************************** ************************ 

  131. *Function: u16 ADC_ReadX(void) 

  132. *Function: Read X coordinate 

  133. *Parameters: None 

  134. *Return: Original X coordinate value 

  135. *Depends on: underlying macro definitions 

  136. *Author : cp1300@139.com 

  137. *Time: 20121006 

  138. *Last modified: 20121006 

  139. *Description: What is read is ADC conversion register 0 

  140. * Need to set ADC mode first 

  141. *************************************************** *************************************************** *********************/  

  142. u16 ADC_ReadX(void)  

  143. {  

  144.     ADC_Start(); //Start an ADC conversion  

  145.     ADC_Wait(); //Wait for conversion to complete  

  146.     return ADC_ReadData0();  

  147. }  

  148.   

  149.   

  150. /****************************************************** *************************************************** ************************ 

  151. *Function: u16 ADC_ReadY(void) 

  152. *Function: Read Y coordinate 

  153. *Parameters: None 

  154. *Return: Original Y coordinate value 

  155. *Depends on: underlying macro definitions 

  156. *Author : cp1300@139.com 

  157. *Time: 20121006 

  158. *Last modified: 20121006 

  159. *Description: Read ADC conversion register 1 

  160. * Need to set ADC mode first 

  161. *************************************************** *************************************************** *********************/  

  162. u16 ADC_ReadY(void)  

  163. {  

  164.     ADC_Start(); //Start an ADC conversion  

  165.     ADC_Wait(); //Wait for conversion to complete  

  166.     return ADC_ReadData1();  

  167. }  

  168.   

  169.   

  170. /****************************************************** *************************************************** ************************ 

  171. *Function: u8 Get_TouchState(void) 

  172. *Function: Get touch status 

  173. *Parameters: None 

  174. *Return: 1: pen lifted; 0: pen pressed 

  175. *Depends on: underlying macro definitions 

  176. *Author : cp1300@139.com 

  177. *Time: 20120315 

  178. *Last modified: 20120315 

  179. *Description: Determine the status by reading BIT15 of ADCDAT1 

  180. *************************************************** *************************************************** *********************/  

  181. u8 Get_TouchState(void)  

  182. {  

  183.     return((ADC->DAT1 & BIT15) ? TOUCH_UP : TOUCH_DOWN);  

  184. }  

  185.   

  186.   

  187.   

  188.   

  189.   

  190.   

  191.   

  192. //Touch screen interrupt service function  

  193. void __irq Isr_Touch(void)  

  194. {  

  195.     TOUCH_ClearInt(); //Clear the touch screen interrupt flag  

  196.     VICInterruptEnd(); //Interrupt ends  

  197. }  


adc.h


  1. /****************************************************** *************************************************** ********** 

  2.  * File name: ADC.h 

  3.  * Function: S3C6410 touch screen ADC bottom driver function 

  4.  * Author: Chen Peng 

  5.  * Created: March 12, 2012 21:05 

  6.  * Last modified: March 12, 2012 

  7.  * Details: Touch screen driver and related ADC driver 

  8. *************************************************** *************************************************** *********/  

  9.   

  10. #ifndef _ADC_H_  

  11. #define _ADC_H_  

  12.   

  13. //Button status     

  14. #define TOUCH_DOWN 0  

  15. #define TOUCH_UP 1  

  16. #define TOUCH_Posedge 0x01 //Pen lift event  

  17. #define TOUCH_Negedge 0x02 //Pen press event  

  18.   

  19. //ADC sampling mode  

  20. #define COMMON_AD_MODER 0 //Common AD conversion mode  

  21. #define ASUNDER_X_MODER 1 //Separate X sampling mode  

  22. #define ASUNDER_Y_MODER 2 //Separate Y sampling mode  

  23. #define AUTO_XY_MODER 3 //Automatic X,Y sampling mode //I don't know why it is inaccurate, only separate X,Y scanning mode can be used  

  24. #define INT_AD_MODER 4 //Sampling mode for waiting interrupt  

  25. #define STANDBY_AD_MODER 5 //Power-down mode  

  26.   

  27.   

  28. //ADC channel selection  

  29. #define ADC_CH_AIN0 0  

  30. #define ADC_CH_AIN1 1  

  31. #define ADC_CH_AIN2 2  

  32. #define ADC_CH_AIN3 3  

  33. #define ADC_CH_YM 4  

  34. #define ADC_CH_YP 5  

  35. #define ADC_CH_XM 6  

  36. #define ADC_CH_XP 7  

  37.   

  38.   

  39. //Read conversion register 0  

  40. #define ADC_ReadData0() (ADC->DAT0&0xfff)  

  41. #define ADC_ReadData1() (ADC->DAT1&0xfff)  

  42.   

  43. //related functions  

  44. void ADC_Init(void); //Initialize ADC  

  45. void SetADC_Channel(u8 ch); //ADC channel selection  

  46. void ADC_SetMode(u8 Mode); //ADC working mode setting  

  47. u8 Get_TouchState(void); //Get the touch pen status  

  48. u16 ADC_ReadX(void); //Read X coordinate  

  49. u16 ADC_ReadY(void); //Read Y coordinate  

  50.   

  51.   

  52.   

  53. //Enable pen lift interrupt  

  54. __inline void ADCTSC_UD_SEN (u8 EN)  

  55. {  

  56.     ADC->TSC &= ~BIT8; //pen down interrupt  

  57.     if(EN == ENABLE)  

  58.         ADC->TSC |= BIT8;  

  59. }  

  60.   

  61.   

  62.   

  63. //YM connected to GMD is invalid, connect to HZ  

  64. __inline void ADCTSC_YM_HZ(void)  

  65. {  

  66.     ADC->TSC &= ~BIT7;         

  67. }  

  68.   

  69. //YM connected to GMD is effective, connected to GND  

  70. __inline void ADCTSC_YM_GND(void)  

  71. {  

  72.     ADC->TSC |= BIT7;          

  73. }  

  74.   

  75.   

  76. //YP connected to VDD is invalid, connect to HZ  

  77. __inline void ADCTSC_YP_HZ(void)  

  78. {  

  79.     ADC->TSC |= BIT6;          

  80. }  

  81.   

  82. //YP is valid when connected to VDD, and VDDA  

  83. __inline void ADCTSC_YP_VDD(void)  

  84. {  

  85.     ADC->TSC &= ~BIT6;         

  86. }  

  87.   

  88.   

  89. //XM is invalid when connected to GMD, connect to HZ  

  90. __inline void ADCTSC_XM_HZ(void)  

  91. {  

  92.     ADC->TSC &= ~BIT5;         

  93. }  

  94.   

  95. //XM connected to GMD is effective, connected to GND  

  96. __inline void ADCTSC_XM_GND(void)  

  97. {  

  98.     ADC->TSC |= BIT5;          

  99. }  

  100.   

  101.   

  102. //Connecting XP to VDD is invalid, connect to HZ  

  103. __inline void ADCTSC_XP_HZ(void)  

  104. {  

  105.     ADC->TSC |= BIT4;          

  106. }  

  107.   

  108. //XP connected to VDD is effective, connected to VDDA  

  109. __inline void ADCTSC_XP_VDD(void)  

  110. {  

  111.     ADC->TSC &= ~BIT4;         

  112. }  

  113.   

  114.   

  115. //Normal ADC conversion mode  

  116. __inline void Normal_ADC_Mode(void)  

  117. {  

  118.     ADC->TSC &= ~BIT2; //Normal ADC conversion  

  119. }  

  120.   

  121. //Standby mode  

  122. __inline void StandbyMode(void)  

  123. {  

  124.     ADC->CON |= BIT2;      

  125. }  

  126.   

  127.   

  128. //Automatic X,Y conversion  

  129. __inline void AUTO_XYPosition(void)  

  130. {  

  131.     ADC->TSC &= ~(BIT0+BIT1);  

  132.     ADC->TSC |= BIT2; //Automatic X,Y conversion  

  133. }  

  134.   

  135. //X,Y manual measurement mode, no running mode  

  136. __inline void NO_OpeMode(void)  

  137. {  

  138.     ADC->TSC &= ~(BIT0+BIT1);  

  139. }  

  140.   

  141. //X,Y manual measurement mode, X coordinate conversion mode  

  142. __inline void X_PosMode(void)  

  143. {  

  144.     NO_OpeMode(); //Clear settings  

  145.     ADC->TSC |= 1;  

  146. }  

  147.   

  148. //X,Y manual measurement mode, Y coordinate conversion mode  

  149. __inline void Y_PosMode(void)  

  150. {  

  151.     NO_OpeMode(); //Clear settings  

  152.     ADC->TSC |= 2;  

  153. }  

  154.   

  155. //X,Y manual measurement mode, waiting for interrupt mode  

  156. __inline void INT_WaitingMode(void)  

  157. {  

  158.     NO_OpeMode(); //Clear settings  

  159.     ADC->TSC |= 3;  

  160. }  

  161.   

  162.   

  163. //XP pull-up start  

  164. __inline void XP_UP_ENABLE(void)  

  165. {  

  166.     ADC->TSC &= ~BIT3;  

  167. }  

  168.   

  169.   

  170. //XP pull-up disabled  

  171. __inline void XP_UP_DISABLE(void)  

  172. {  

  173.     ADC->TSC |= BIT3;  

  174. }  

  175.   

  176.   

  177. // Clear ADC wake-up interrupt  

  178. __inline void ADC_ClearInt(void)  

  179. {  

  180.     ADC->CLRINT = 0xffffffff; //Write any value to clear the interrupt flag  

  181. }  

  182.   

  183.   

  184. // Clear the touch screen interrupt  

  185. __inline void TOUCH_ClearInt(void)  

  186. {  

  187.     ADC->UPDN = 0; // Clear the ADC touch screen UP-DOWN register  

  188.     ADC->CLRINTPNDNUP = 0xffffffff; //Write any value to clear the interrupt flag  

  189. }  

  190.   

  191.   

  192. //Start an ADC conversion  

  193. __inline void ADC_Start(void)  

  194. {  

  195.     ADC->CON |= BIT0; //Start ADC conversion  

  196. }  

  197.   

  198.   

  199. //Wait for ADC conversion to complete  

  200. __inline void ADC_Wait(void)  

  201. {  

  202.     while(!(ADC->CON & BIT15));  

  203. }  

  204.   

  205.   

  206. #endif  


touch.c


  1. /****************************************************** *************************************************** ********** 

  2.  * File name: Touch.c 

  3.  * Function: S3C6410 resistive touch screen driver 

  4.  * Author: cp1300@139.com 

  5.  * Created: October 6, 2012 17:31 

  6.  * Last modified: October 6, 2012 

  7.  * Details: Requires underlying ADC support 

  8. *************************************************** *************************************************** *********/  

  9. #include "system.h"  

  10. #include "adc.h"  

  11. #include "touch.h"  

  12.   

  13.   

  14. Pen_Holder Pen_Point; //Define pen entity  

  15.   

  16.   

  17.   

  18. // Enable touch screen calibration, other support required  

  19. #define _TOUCH_ADJUST 1  

  20.   

  21. #if _TOUCH_ADJUST  

  22.     void TOUCH_Adjust(void); //touch screen calibration  

  23. #endif //_TOUCH_ADJUST  

  24.   

  25. /****************************************************** *************************************************** ************************ 

  26. *Function: void TOUCH_Init(FunctionalState EnableInt) 

  27. *Function: Touch screen initialization 

  28. *Parameter: EnableInt: pen interrupt enable 

  29. *Return: None 

  30. *Depends on: underlying macro definitions 

  31. *Author : cp1300@139.com 

  32. *Time : 20120313 

  33. *Last modified: 20121006 

  34. *Description: Touch screen initialization 

  35. *************************************************** *************************************************** *********************/  

  36. void TOUCH_Init(FunctionalState EnableInt)  

  37. {  

  38.     ADC_Init(); //Initialize ADC  

  39.     TOUCH_ClearInt(); //Clear the touch screen interrupt flag  

  40.     ADC_ClearInt(); //Clear ADC interrupt  

  41.     ADC_SetMode(INT_AD_MODER); //Wait for interrupt mode  

  42.     ADCTSC_UD_SEN(DISABLE); //Set to press interrupt  

  43.     if(EnableInt == ENABLE) // Enable pen interrupt  

  44.     {  

  45.         //Set_IsrAddr(INT_PENDNUP,(u32)Isr_Touch); //Set interrupt vector entry  

  46.         //Set_IntEnable(INT_PENDNUP,ENABLE); //Turn on the touch screen and press  

  47.     }  

  48. #if _TOUCH_ADJUST  

  49.     TOUCH_Adjust(); //Touch screen calibration  

  50. #endif //_TOUCH_ADJUST  

  51. }  

  52.   

  53.   

  54.   

  55.   

  56. /****************************************************** *************************************************** ************************ 

  57. * Function: u16 ADS_Read_XY(u16(*ADC_ReadXY)(void)) 

  58. * Function: Use the bubble method to read the coordinates once 

  59. * Parameter: ADC_ReadXY: X or Y coordinate reading function 

  60. * Return: conversion result 

  61. * Depends on: ADC 

  62. * Author : cp1300@139.com 

  63. * Date : 20121006 

  64. * Last modified: 20121006 

  65. * Description: Read READ_TIMES times of data continuously and sort them in ascending order. 

  66.             Then remove the lowest and highest LOST_VAL numbers and take the average  

  67. *************************************************** *************************************************** *********************/  

  68. #define READ_TIMES 15 //Read times  

  69. #define LOST_VAL 5 //discard value  

  70. u16 ADS_Read_XY(u16(*ADC_ReadXY)(void))  

  71. {  

  72.     u16 i, j;  

  73.     u16 buff[READ_TIMES];  

  74.     u16 sum=0;  

  75.     u16 temp;  

  76.   

  77.     for(i = 0;i < READ_TIMES;i ++)  

  78.     {                  

  79.         buff[i] = ADC_ReadXY();       

  80.     }                     

  81.     for(i = 0;i < READ_TIMES - 1;i ++)//Sort  

  82.     {  

  83.         for(j = i + 1;j < READ_TIMES;j++)  

  84.         {  

  85.             if(buff[i] > buff[j]) // sort in ascending order  

  86.             {  

  87.                 temp = buff[i];  

  88.                 buff[i] = buff[j];  

  89.                 buff[j] = temp;  

  90.             }  

  91.         }  

  92.     }       

  93.     sum = 0;  

  94.     for(i = LOST_VAL;i < READ_TIMES - LOST_VAL;i ++)  

  95.         sum += buff[i];  

  96.     temp = sum / (READ_TIMES - 2 * LOST_VAL);  

  97.   

  98.     return temp;     

  99. }   

  100.   

  101.   

  102. /****************************************************** *************************************************** ************************ 

  103. * Function: u8 Read_ADS(u16 *x,u16 *y) 

  104. * Function: Read X,Y coordinates with filtering 

  105. * Parameter: X,Y coordinate value buffer pointer 

  106. * Return: 1: conversion result is valid; 0: conversion result is invalid 

  107. * Dependency: XPT2046 underlying function 

  108. * Author : cp1300@139.com 

  109. * Date : 20120914 

  110. * Last modified: 20120914 

  111. * Description: Coordinate reading with filtering 

  112.             The minimum value cannot be less than MINI_ADC_DATA. 

  113. *************************************************** *************************************************** *********************/  

  114. #define MINI_ADC_DATA 100  

  115. u8 Read_ADS(u16 *x,u16 *y)  

  116. {  

  117.     u16 xtemp, ytemp;  

  118.       

  119.     ADC_SetMode(ASUNDER_X_MODER); //Set ADC to separate X sampling mode  

  120.     xtemp = ADS_Read_XY(ADC_ReadX); //Read X coordinate  

  121.     ADC_SetMode(ASUNDER_Y_MODER); //Set ADC to separate Y sampling mode  

  122.     ytemp = ADS_Read_XY(ADC_ReadY); //Read Y coordinate  

  123.     ADC_SetMode(INT_AD_MODER); //Set ADC to wait interrupt mode  

  124.     if(xtemp < MINI_ADC_DATA || ytemp < MINI_ADC_DATA)  

  125.         return 0; // reading failed  

  126.     *x = xtemp;  

  127.     *y = ytemp;  

  128.   

  129.     return 1; //Reading successful  

  130. }  

  131.   

  132.   

  133. /****************************************************** *************************************************** ************************ 

  134. * Function: u8 Read_ADS2(u16 *x,u16 *y)  

  135. * Function: Read 2 valid AD values ​​continuously 

  136. * Parameter: X,Y coordinate value buffer pointer 

  137. * Return: 1: conversion result is valid; 0: conversion result is invalid 

  138. * Depends on: u8 Read_ADS(u16 *x,u16 *y) 

  139. * Author : cp1300@139.com 

  140. * Date : 20120914 

  141. * Last modified: 20120914 

  142. * Description: Read valid AD values ​​2 times in succession, and the deviation between the two times cannot exceed ERR_RANGE 

  143.             If the conditions are met, the reading is considered correct, otherwise the reading is wrong.        

  144.             This function can greatly improve the accuracy 

  145. *************************************************** *************************************************** *********************/  

  146. #define ERR_RANGE 50 //Error range   

  147. u8 Read_ADS2(u16 *x,u16 *y)   

  148. {  

  149.     u16 x1,y1;  

  150.     u16 x2,y2;  

  151.     u8 flag;   

  152.          

  153.     flag = Read_ADS(&x1,&y1);     

  154.     if(flag == 0)  

  155.         return(0);  

  156.     flag = Read_ADS(&x2,&y2);        

  157.     if(flag == 0)  

  158.         return(0);     

  159.     if(((x2 <= x1 && x1 < x2 + ERR_RANGE) || (x1 <= x2 && x2 < x1 + ERR_RANGE))  

  160.          && ((y2 <= y1 && y1 < y2 + ERR_RANGE) || (y1 <= y2 && y2 < y1 + ERR_RANGE))) //The two samples are within +-ERR_RANGE  

  161.     {  

  162.         *x = (x1 + x2) / 2;  

  163.         *y = (y1 + y2) / 2;  

  164.         return 1;  

  165.     }  

  166.     else   

  167.         return 0;       

  168. }  

  169.   

  170.   

  171. /****************************************************** *************************************************** ************************ 

  172. * Function: u8 TOUCH_ReadOneTP(void) 

  173. * Function: Read the original coordinates once 

  174. * Parameters: None 

  175. * Return: 1: conversion result is valid; 0: conversion result is invalid 

  176. * Depends on: u8 Read_ADS2(u16 *x,u16 *y)  

  177. * Author : cp1300@139.com 

  178. * Date : 20120914 

  179. * Last modified: 20120914 

  180. * Description: Call Read_ADS2 function to read. If Read_ADS2 fails, repeat the reading. The maximum number of times to read is MAX_READ_ADS 

  181.             If it fails, it will return 0. Note that returning 1 means the result is valid. 

  182.             The result of the conversion is stored in x0, y0 of the structure Pen_Holder 

  183. *************************************************** *************************************************** *********************/  

  184. #define MAX_READ_ADS 5 //Maximum number of retries  

  185. u8 TOUCH_ReadOneTP(void)  

  186. {  

  187.     u8 i;  

  188.     u16 x,y;  

  189.   

  190.     for(i = MAX_READ_ADS;i != 0;i --)  

  191.     {  

  192.         if(Read_ADS2(&x,&y))  

  193.         {  

  194.             Pen_Point.x0 = x; //Conversion is valid, store the result  

  195.             Pen_Point.y0 = y;  

  196.             return 1; //Return success  

  197.         }  

  198.     }  

  199.   

  200.     return 0; //Return failure  

  201. }  

  202.   

  203.   

  204.   

  205. /****************************************************** *************************************************** ************************ 

  206. * Function: void TOUCH_ConvertPos(void) 

  207. * Function: Collect and convert touch coordinates 

  208. * Parameters: None 

  209. * Returns: None 

  210. * Depends on: LCD.C, touch screen ADC bottom layer 

  211. * Author : cp1300@139.com 

  212. * Date : 20120914 

  213. * Last modified: 20121006 

  214. * Description: The conversion result is determined according to the calibration parameters of the touch screen and saved in x, y 

  215. * Touch calibration is required first 

  216. *************************************************** *************************************************** *********************/  

  217. void TOUCH_ConvertPos(void)  

  218. {               

  219.     if(TOUCH_ReadOneTP())  

  220.     {  

  221.         Pen_Point.x = Pen_Point.xfac * Pen_Point.x0 + Pen_Point.xoff;  

  222.         Pen_Point.y = Pen_Point.yfac * Pen_Point.y0 + Pen_Point.yoff;    

  223.     }  

  224. }  

  225.   

  226.   

  227.   

  228.   

  229. //Touch screen calibration related  

  230. ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// /////////  

  231. #if _TOUCH_ADJUST  

  232. #include "TFT_LCD.h"  

  233. #include "stdlib.h"  

  234. #include "math.h"  

  235. #include "delay.h"  

  236.   

  237. /****************************************************** *************************************************** ************************ 

  238. * Function: void Drow_Touch_Point(u16 x,u16 y) 

  239. * Function: Draw a touch point for calibration 

  240. * Parameters: x, y: center position of touch point 

  241. * Returns: None 

  242. * Depends on : LCD.C 

  243. * Author : cp1300@139.com 

  244. * Date : 20120914 

  245. * Last modified: 20120914 

  246. * Description: It will call the circle, line, rectangle and other functions in LCD.C 

  247. *************************************************** *************************************************** *********************/  

  248. void Drow_Touch_Point(u16 x,u16 y)  

  249. {  

  250.     Draw_Circle(x,y,10,0xf0f0);//Draw a circle  

  251.     Draw_Circle(x,y,3,0xf0f0);//Draw a circle  

  252.     LCD_DrawLine(x - 15, y, x + 15, y,0xf0f0); //Draw line  

  253.     LCD_DrawLine(x, y - 15, x, y + 15,0xf0f0); //Draw line    

  254.     LCD_DrawRectangle(x - 10,y - 10,x + 10,y + 10,0xf0f0); //Draw rectangle  

  255. }  

  256.   

  257.   

  258.   

  259.   

  260. /****************************************************** *************************************************** ************************ 

  261. * Function: void TOUCH_Adjust(void) 

  262. * Function: Touch screen calibration 

  263. * Parameters: None 

  264. * Returns: None 

  265. * Depends on: LCD.C, touch screen ADC bottom layer 

  266. * Author : cp1300@139.com 

  267. * Date : 20120914 

  268. * Last modified: 20120914 

  269. * Description: Get four calibration values 

  270. * (20,20) (LCD_XSIZE-20,20) 

  271. *  

  272. *  

  273. * (20,LCD_YSIZE-20) (LCD_XSIZE-20,LCD_YSIZE-20) 

  274. *************************************************** *************************************************** *********************/  

  275. void TOUCH_Adjust(void)  

  276. {                                  

  277.     u16 pos_temp[4][2]; //coordinate cache value  

  278.     u8 cnt=0;    

  279.     u16 d1,d2;  

  280.     u32 tem1,tem2;  

  281.     float fac;       

  282.     cnt=0;  

  283.                       

  284.   

  285.     LCD_ClearScreen(0xffff);//Clear screen     

  286.     Drow_Touch_Point(20,20);//Draw point 1   

  287.     //Pen_Point.xfac=0; //xfac is used to mark whether it has been calibrated, so it must be cleared before calibration! To avoid errors     

  288.     while(1)  

  289.     {  

  290.         if(GetPenStartus() == TOUCH_DOWN) //The button is pressed  

  291.         {  

  292.             if(TOUCH_ReadOneTP()) //Get single key value  

  293.             {                                    

  294.                 pos_temp[cnt][0]=Pen_Point.x0;  

  295.                 pos_temp[cnt][1]=Pen_Point.y0;  

  296.                 cnt++;  

  297.             }  

  298.             while(GetPenStartus() == TOUCH_DOWN); //Wait for the key to be lifted               

  299.             switch(cnt)  

  300.             {                

  301.                 case 1:  

  302.                     LCD_ClearScreen(0xffff);//Clear screen    

  303.                     Drow_Touch_Point(LCD_XSIZE-20,20);//Draw point 2  

  304.                     break;  

  305.                 case 2:  

  306.                     LCD_ClearScreen(0xffff);//Clear screen    

  307.                     Drow_Touch_Point(20,LCD_YSIZE-20);//Draw point 3  

  308.                     break;  

  309.                 case 3:  

  310.                     LCD_ClearScreen(0xffff);//Clear screen   

  311.                     Drow_Touch_Point(LCD_XSIZE-20,LCD_YSIZE-20);//Draw point 4  

  312.                     break;  

  313.                 case 4: //All four points have been obtained  

  314.                     // Opposite sides are equal  

  315.                     tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2  

  316.                     tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2  

  317.                     tem1*=tem1;  

  318.                     tem2*=tem2;  

  319.                     d1=sqrt(tem1+tem2); //get the distance between 1 and 2  

  320.                       

  321.                     tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4  

  322.                     tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4  

  323.                     tem1*=tem1;  

  324.                     tem2*=tem2;  

  325.                     d2=sqrt(tem1+tem2); //get the distance between 3 and 4  

  326.                     fac=(float)d1/d2;  

  327.                     if(fac<0.95||fac>1.05||d1==0||d2==0)//Unqualified  

  328.                     {  

  329.                         cnt=0;  

  330.                         LCD_ClearScreen(0xffff);//Clear screen    

  331.                         Drow_Touch_Point(20,20);  

  332.                         continue;  

  333.                     }  

  334.                     tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3  

  335.                     tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3  

  336.                     tem1*=tem1;  

  337.                     tem2*=tem2;  

  338.                     d1=sqrt(tem1+tem2); //get the distance between 1 and 3  

  339.                       

  340.                     tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4  

  341.                     tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4  

  342.                     tem1*=tem1;  

  343.                     tem2*=tem2;  

  344.                     d2=sqrt(tem1+tem2); //get the distance between 2 and 4  

  345.                     fac=(float)d1/d2;  

  346.                     if(fac<0.95||fac>1.05)//failed  

  347.                     {  

  348.                         cnt=0;  

  349.                         LCD_ClearScreen(0xffff);//Clear screen    

  350.                         Drow_Touch_Point(20,20);  

  351.                         continue;  

  352.                     }//Correct  

  353.                                      

  354.                     //Diagonals are equal  

  355.                     tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3  

  356.                     tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3  

  357.                     tem1*=tem1;  

  358.                     tem2*=tem2;  

  359.                     d1=sqrt(tem1+tem2); //get the distance between 1 and 4  

  360.       

  361.                     tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4  

  362.                     tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4  

  363.                     tem1*=tem1;  

  364.                     tem2*=tem2;  

  365.                     d2=sqrt(tem1+tem2); //get the distance between 2 and 3  

  366.                     fac=(float)d1/d2;  

  367.                     if(fac<0.95||fac>1.05)//failed  

  368.                     {  

  369.                         cnt=0;  

  370.                         LCD_ClearScreen(0xffff);//Clear screen    

  371.                         Drow_Touch_Point(20,20);  

  372.                         continue;  

  373.                     }//Correct  

  374.                     //Calculation results  

  375.                     Pen_Point.xfac=(float)(LCD_XSIZE-40)/(pos_temp[1][0]-pos_temp[0][0]); //Get xfac          

  376.                     Pen_Point.xoff=(LCD_XSIZE-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2; //get xoff  

  377.                             

  378.                     Pen_Point.yfac=(float)(LCD_YSIZE-40)/(pos_temp[2][1]-pos_temp[0][1]); //get yfac  

  379.                     Pen_Point.yoff=(LCD_YSIZE-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//Get yoff    

  380.                     //Wire_Touch(); //Store calibration results  

  381.                     LCD_ClearScreen(0xffff);//Clear screen   

  382.                     Show_Char(35,LCD_YSIZE/2,"Touch Screen Adjust OK!",0xf800,0xffff,0x80);   

  383.                     Delay_MS(1000);  

  384.                     LCD_ClearScreen(0xffff);//Clear screen      

  385.                     return; //Calibration completed                  

  386.             }  

  387.         }  

  388.     }   

  389. }     

  390.   

  391.   

  392. #endif //_TOUCH_ADJUST  

  393. ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// ///////////  


touch.h

  1. /****************************************************** *************************************************** ********** 

  2.  * File name: Touch.h 

  3.  * Function: S3C6410 resistive touch screen driver 

  4.  * Author: cp1300@139.com 

  5.  * Created: October 6, 2012 17:31 

  6.  * Last modified: October 6, 2012 

  7.  * Details: Requires underlying ADC support 

  8. *************************************************** *************************************************** *********/  

  9. #ifndef TOUCH_H_  

  10. #define TOUCH_H_  

  11.   

  12. #include "adc.h"  

  13.   

  14. #ifndef TOUCH_DOWN  

  15.     #define TOUCH_DOWN 0  

  16. #endif //TOUCH_DOWN  

  17. #ifndef TOUCH_UP  

  18.     #define TOUCH_UP 1  

  19. #endif //TOUCH_UP  

  20.   

  21.   

  22.   

  23. //Pen handle structure  

  24. typedef struct   

  25. {  

  26.     u16 x0; //Original coordinates  

  27.     u16 y0;  

  28.     u16 x; //final/temporary coordinates  

  29.     u16 y;                                

  30.     u8 Touch_Sta; //Pen status                

  31. //Touch screen calibration parameters  

  32.     float xfac;  

  33.     float yfac;  

  34.     short xoff;  

  35.     short yoff;  

  36. }Pen_Holder;            

  37. extern Pen_Holder Pen_Point; //Define a structure variable of a pen holder  

  38.   

  39.   

  40.   

  41. void TOUCH_Init(FunctionalState EnableInt); //Touch screen initialization function  

  42. u8 TOUCH_ReadOneTP(void); //Read one coordinate  

  43. #define GetPenStartus() Get_TouchState() //Get the touch pen status  

  44. void TOUCH_ConvertPos(void); //Get the actual coordinates after conversion  

  45.   

  46.   

  47.   

  48.   

  49. #endif /*TOUCH_H_*/  


Main function test program


main.c


  1. #include "system.h"  

  2. #include "uart.h"  

  3. #include "tft_lcd.h"  

  4. #include "other.h"  

  5. #include "delay.h"  

  6. #include "timer.h"  

  7. #include "touch.h"  

  8.   

  9.   

  10. //LED1 flashing program, flashing in timer 0 interrupt service program, period 400MS  

  11. void LED1_flash(void)  

  12. {  

  13.     LED1_FLASH();  

  14. }  

  15.   

  16.   

  17.   

  18. int main(void)  

  19. {     

  20.     LCD_Init(); //Initialize LCD  

  21.     UART0_Init(DISABLE,115200); //Initialize the serial port, disable interrupt reception, baud rate 115200  

  22.     LED_Init(); //Initialize LED  

  23.   

  24.     Timer1_Init(400000-1,ENABLE,LED1_flash); //Initialize timer 0, period 400ms  

  25.     TOUCH_Init(DISABLE); //Initialize the touch screen  

  26.       

  27.     lcd_printf("Get_FCLK : %d Hz\n",Get_FCLK());      

  28.     lcd_printf("Get_PCLK : %d Hz\n",Get_PCLK());  

  29.       

  30.     while(1)  

  31.     {  

  32.         //LED2_FLASH(); //LED2 flashes  

  33.         //Delay_US(600000);  

  34.         if(GetPenStartus() == TOUCH_DOWN) //Pen is pressed  

  35.         {  

  36.             TOUCH_ConvertPos();  

  37.             //lcd_printf("X:%d; Y:%d\n",Pen_Point.x,Pen_Point.y);  

  38.             Draw_Big_Point(Pen_Point.x,Pen_Point.y,0xf800);  

  39.             Delay_MS(1);  

  40.         }  

  41.     }  

  42. }  


//Supplement ADC related register structure


  1. #define ADC_BASE 0x7E00B000  

  2.   

  3. //ADC register  

  4. typedef struct  

  5. {  

  6.     vu32 CON; //ADC control register   

  7.     vu32 TSC; //Touch screen control register  

  8.     vu32 DLY; //ADC start delay register  

  9.     vu32 DAT0; //ADC data register 0  

  10.     vu32 DAT1; //ADC data register 1  

  11.     vu32 UPDN; //Touch screen UP-DOWN register  

  12.     vu32 CLRINT; //ADC interrupt clear register  

  13.     u32 Reserved;  

  14.     vu32 CLRINTPNDNUP; //Touch screen pen interrupt register  

  15. }ADC_TypeDef;  

  16.   

  17. #define ADC ((ADC_TypeDef*)ADC_BASE)  



Reference address:S3C6410 bare metal resistive screen driver

Previous article:OK6410 development board bare metal DS18B20 driver
Next article:OK6410 bare metal simple NAND FLASH driver

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components
Guess you like

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号