S3C6410裸机电阻屏驱动

发布者:bobojrt最新更新时间:2017-02-26 来源: eefocus关键字:S3C6410裸机  电阻屏驱动 手机看文章 扫描二维码
随时随地手机看文章

使用的是RVDS4.0编译的

大家主要是看看如何配置模式的

我之前一直使用自动X,Y采样,但是读取的都不准,最后采样分离的,才可以,需要注意的是使能ADC读开始后需要先读转换结果寄存器,但是此时读取的是上一次的转换结果,如果是连续读取需要等待转换完成,否则转换结果不准.

 

adc.c


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

  2.  * 文件名: ADC.c 

  3.  * 功能:      S3C6410 ADC底层驱动函数 

  4.  * 作者:      cp1300@139.com 

  5.  * 创建时间:    2012年3月12日21:05 

  6.  * 最后修改时间:2012年3月12日 

  7.  * 详细:      触摸屏驱动以及相关ADC驱动 

  8.  * 问题:      一直以来存在一个误区,一直以为使用了启动开始读操作,每次读DAT寄存器后就可以读取到转换后的数据,最终发现使用这个后读到的是上一次的数据, 

  9.  *          还是需要等到转换完成,否则连续转换的时候数据会非常乱. 

  10.  *          现在使用的是手动控制转换开始 

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

  12. #include "system.h"  

  13. #include "ADC.h"  

  14.   

  15.   

  16.   

  17.   

  18. //ADC的控制寄存器 ADCCON  

  19. #define ADCCON_RESSEL_12BIT         (1 << 16) //12bit模式  

  20. #define ADCCON_ECFLG                (0 << 15) //A/D转换结束标志只读;  

  21. #define ADCCON_PRSCEN               (1 << 14) //A/D转换器预分频器使能  

  22. #define ADCCON_PRSCVL               (32 << 6) //预分频值,1-255,分频值+1,至少为PCLK的1/5,此时PCLK = 66MHZ,在2.5MHZ时钟下转换最快  

  23. #define ADCCON_SEL_MUX              (0  << 3) //默认选择通道0  

  24. #define ADCCON_STDBM                (0  << 2) //正常模式  

  25. #define ADCCON_READ_START           (0  << 1) //关闭启动开始读操作  

  26. #define ADCCON_ENABLE_START         (0  << 0) //如果READ_START 启用,这个值是无效的。  

  27.   

  28.   

  29. //ADCDLY  

  30. #define ADCDLY_DELAY                500         //自动采样延时时间,  

  31.   

  32.   

  33.   

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

  35. *函数        :    void SetADC_Channel(u8 ch) 

  36. *功能        :    设置ADC输入通道 

  37. *参数        :    ch:通道号,0-7 

  38. *返回        :    无 

  39. *依赖        :    底层宏定义 

  40. *作者        :    cp1300@139.com 

  41. *时间        :    20120513 

  42. *最后修改时间:    20120513 

  43. *说明        :    ADC输入通道选择 

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

  45. void SetADC_Channel(u8 ch)  

  46. {  

  47.     ADC->CON &= ~(7 << 3);     //清除通道  

  48.     ADC->CON |= ch & (0x07); //设置通道号  

  49. }  

  50.   

  51.   

  52.   

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

  54. *函数        :    void ADC_Init(void) 

  55. *功能        :    ADC初始始化 

  56. *参数        :    无 

  57. *返回        :    无 

  58. *依赖        :    底层宏定义 

  59. *作者        :    cp1300@139.com 

  60. *时间        :    20120312 

  61. *最后修改时间:    20120313 

  62. *说明        :    ADC初始始化 

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

  64. void ADC_Init(void)  

  65. {  

  66.     //ADC的控制寄存器配置;12BIT模式  

  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;                             //设置自动间隔采样时间  

  69. }  

  70.   

  71.   

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

  73. *函数        :    void ADC_SetMode(u8 Mode) 

  74. *功能        :    设置ADC模式 

  75. *参数        :    无 

  76. *返回        :    无 

  77. *依赖        :    底层宏定义 

  78. *作者        :    cp1300@139.com 

  79. *时间        :    20120313 

  80. *最后修改时间:    20120313 

  81. *说明        :    设置ADC模式 

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

  83. void ADC_SetMode(u8 Mode)  

  84. {  

  85.     ADC->TSC &= (1 << 8);      //清除原先设置  

  86.     ADC->CON &= ~BIT2;           //退出待机模式  

  87.     XP_UP_DISABLE();            //XP上拉禁止  

  88.     Normal_ADC_Mode();          //普通ADC模式  

  89.     switch(Mode)  

  90.     {  

  91.         case COMMON_AD_MODER:   //普通ADC模式  

  92.             Normal_ADC_Mode();break;  

  93.         case ASUNDER_X_MODER:   //分离的X扫描模式  

  94.         {  

  95.             ADCTSC_XP_VDD();  

  96.             ADCTSC_XM_GND();  

  97.             ADCTSC_YP_HZ();  

  98.             ADCTSC_YM_HZ();  

  99.             X_PosMode();  

  100.         }break;     //XP=外部电源,XM=GND,YP=AIN5,YM=高阻  

  101.         case ASUNDER_Y_MODER:   //分离的Y扫描模式  

  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=高阻,YP=外部电源,YM=GND  

  109.         case AUTO_XY_MODER:     //自动XY扫描模式  

  110.         {  

  111.             AUTO_XYPosition();  

  112.         }break;  

  113.         case INT_AD_MODER:      //等待中断模式  

  114.         {  

  115.             ADCTSC_XP_HZ();  

  116.             ADCTSC_XM_HZ();  

  117.             ADCTSC_YP_HZ();  

  118.             ADCTSC_YM_GND();  

  119.             XP_UP_ENABLE();     //XP上拉使能              

  120.             INT_WaitingMode();  

  121.         }break;//XP上拉,XM=高阻,YP=AIN5,YM=GND  

  122.         case STANDBY_AD_MODER:  //掉电模式  

  123.             StandbyMode();break;  

  124.         default:break;  

  125.     }  

  126. }  

  127.   

  128.   

  129.   

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

  131. *函数        :    u16 ADC_ReadX(void) 

  132. *功能        :    读取X坐标 

  133. *参数        :    无 

  134. *返回        :    X坐标原始坐标值 

  135. *依赖        :    底层宏定义 

  136. *作者        :    cp1300@139.com 

  137. *时间        :    20121006 

  138. *最后修改时间:        20121006 

  139. *说明        :    读取的是ADC转换寄存器0 

  140. *               需要先设置ADC模式 

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

  142. u16 ADC_ReadX(void)  

  143. {  

  144.     ADC_Start();        //开始一次ADC转换  

  145.     ADC_Wait();         //等待转换完成  

  146.     return ADC_ReadData0();  

  147. }  

  148.   

  149.   

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

  151. *函数        :    u16 ADC_ReadY(void) 

  152. *功能        :    读取Y坐标 

  153. *参数        :    无 

  154. *返回        :    Y坐标原始坐标值 

  155. *依赖        :    底层宏定义 

  156. *作者        :    cp1300@139.com 

  157. *时间        :    20121006 

  158. *最后修改时间:        20121006 

  159. *说明        :    读取的是ADC转换寄存器1 

  160. *               需要先设置ADC模式 

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

  162. u16 ADC_ReadY(void)  

  163. {  

  164.     ADC_Start();        //开始一次ADC转换  

  165.     ADC_Wait();         //等待转换完成  

  166.     return ADC_ReadData1();  

  167. }  

  168.   

  169.   

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

  171. *函数        :    u8 Get_TouchState(void) 

  172. *功能        :    获取触摸状态 

  173. *参数        :    无 

  174. *返回        :    1:笔抬起;0:笔按下 

  175. *依赖        :    底层宏定义 

  176. *作者        :    cp1300@139.com 

  177. *时间        :    20120315 

  178. *最后修改时间:    20120315 

  179. *说明        :    通过读取ADCDAT1的BIT15来确定状态 

  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. //触摸屏中断服务函数  

  193. void __irq Isr_Touch(void)  

  194. {  

  195.     TOUCH_ClearInt();           //清除触摸屏中断标志  

  196.     VICInterruptEnd();          //中断结束  

  197. }  


adc.h


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

  2.  * 文件名: ADC.h 

  3.  * 功能:      S3C6410 触摸屏ADC底层驱动函数 

  4.  * 作者:      陈鹏 

  5.  * 创建时间:    2012年3月12日21:05 

  6.  * 最后修改时间:2012年3月12日 

  7.  * 详细:      触摸屏驱动以及相关ADC驱动 

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

  9.   

  10. #ifndef _ADC_H_  

  11. #define _ADC_H_  

  12.   

  13. //按键状态     

  14. #define TOUCH_DOWN 0  

  15. #define TOUCH_UP   1  

  16. #define TOUCH_Posedge 0x01//笔抬起事件  

  17. #define TOUCH_Negedge 0x02//笔按下事件  

  18.   

  19. //ADC采样模式  

  20. #define COMMON_AD_MODER     0   //普通的AD转换模式  

  21. #define ASUNDER_X_MODER     1   //分离的X采样模式  

  22. #define ASUNDER_Y_MODER     2   //分离的Y采样模式  

  23. #define AUTO_XY_MODER       3   //自动的X,Y采样模式//不知道为何不准,只能用分离的X,Y扫描模式  

  24. #define INT_AD_MODER        4   //等待中断的采样模式  

  25. #define STANDBY_AD_MODER    5   //掉电模式  

  26.   

  27.   

  28. //ADC通道选择  

  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. //读取转换寄存器0  

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

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

  42.   

  43. //相关函数  

  44. void ADC_Init(void);        //初始化ADC  

  45. void SetADC_Channel(u8 ch); //ADC通道选择  

  46. void ADC_SetMode(u8 Mode);  //ADC工作模式设置  

  47. u8 Get_TouchState(void);    //获取触摸笔状态  

  48. u16 ADC_ReadX(void);        //读取X坐标  

  49. u16 ADC_ReadY(void);        //读取Y坐标  

  50.   

  51.   

  52.   

  53. //使能笔抬起中断  

  54. __inline void ADCTSC_UD_SEN (u8 EN)  

  55. {  

  56.     ADC->TSC &= ~BIT8;           //笔向下中断  

  57.     if(EN == ENABLE)  

  58.         ADC->TSC |= BIT8;  

  59. }  

  60.   

  61.   

  62.   

  63. //YM接GMD无效,接HZ  

  64. __inline void ADCTSC_YM_HZ(void)  

  65. {  

  66.     ADC->TSC &= ~BIT7;         

  67. }  

  68.   

  69. //YM接GMD有效,接GND  

  70. __inline void ADCTSC_YM_GND(void)  

  71. {  

  72.     ADC->TSC |= BIT7;          

  73. }  

  74.   

  75.   

  76. //YP接VDD无效,接HZ  

  77. __inline void ADCTSC_YP_HZ(void)  

  78. {  

  79.     ADC->TSC |= BIT6;          

  80. }  

  81.   

  82. //YP接VDD有效,接VDDA  

  83. __inline void ADCTSC_YP_VDD(void)  

  84. {  

  85.     ADC->TSC &= ~BIT6;         

  86. }  

  87.   

  88.   

  89. //XM接GMD无效,接HZ  

  90. __inline void ADCTSC_XM_HZ(void)  

  91. {  

  92.     ADC->TSC &= ~BIT5;         

  93. }  

  94.   

  95. //XM接GMD有效,接GND  

  96. __inline void ADCTSC_XM_GND(void)  

  97. {  

  98.     ADC->TSC |= BIT5;          

  99. }  

  100.   

  101.   

  102. //XP接VDD无效,接HZ  

  103. __inline void ADCTSC_XP_HZ(void)  

  104. {  

  105.     ADC->TSC |= BIT4;          

  106. }  

  107.   

  108. //XP接VDD有效,接VDDA  

  109. __inline void ADCTSC_XP_VDD(void)  

  110. {  

  111.     ADC->TSC &= ~BIT4;         

  112. }  

  113.   

  114.   

  115. //正常ADC转换模式  

  116. __inline void Normal_ADC_Mode(void)  

  117. {  

  118.     ADC->TSC &= ~BIT2;   //正常的ADC转换  

  119. }  

  120.   

  121. //待机模式  

  122. __inline void StandbyMode(void)  

  123. {  

  124.     ADC->CON |= BIT2;      

  125. }  

  126.   

  127.   

  128. //自动X,Y转换  

  129. __inline void AUTO_XYPosition(void)  

  130. {  

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

  132.     ADC->TSC |= BIT2;    //自动X,Y转换  

  133. }  

  134.   

  135. //X,Y手动测量模式,没有运行模式  

  136. __inline void NO_OpeMode(void)  

  137. {  

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

  139. }  

  140.   

  141. //X,Y手动测量模式,X坐标转换模式  

  142. __inline void X_PosMode(void)  

  143. {  

  144.     NO_OpeMode();           //清除设置  

  145.     ADC->TSC |= 1;  

  146. }  

  147.   

  148. //X,Y手动测量模式,Y坐标转换模式  

  149. __inline void Y_PosMode(void)  

  150. {  

  151.     NO_OpeMode();           //清除设置  

  152.     ADC->TSC |= 2;  

  153. }  

  154.   

  155. //X,Y手动测量模式,等待中断模式  

  156. __inline void INT_WaitingMode(void)  

  157. {  

  158.     NO_OpeMode();           //清除设置  

  159.     ADC->TSC |= 3;  

  160. }  

  161.   

  162.   

  163. //XP上拉启动  

  164. __inline void XP_UP_ENABLE(void)  

  165. {  

  166.     ADC->TSC &= ~BIT3;  

  167. }  

  168.   

  169.   

  170. //XP上拉禁止  

  171. __inline void XP_UP_DISABLE(void)  

  172. {  

  173.     ADC->TSC |= BIT3;  

  174. }  

  175.   

  176.   

  177. //清除ADC唤醒中断  

  178. __inline void ADC_ClearInt(void)  

  179. {  

  180.     ADC->CLRINT = 0xffffffff;        //写入任何值清除中断标志  

  181. }  

  182.   

  183.   

  184. //清除触摸屏中断中断  

  185. __inline void TOUCH_ClearInt(void)  

  186. {  

  187.     ADC->UPDN = 0;                       //清除ADC的触摸屏UP-DOWN寄存器  

  188.     ADC->CLRINTPNDNUP = 0xffffffff;      //写入任何值清除中断标志  

  189. }  

  190.   

  191.   

  192. //开始一次ADC转换  

  193. __inline void ADC_Start(void)  

  194. {  

  195.     ADC->CON |= BIT0;    //开始ADC转换  

  196. }  

  197.   

  198.   

  199. //等待ADC转换完成  

  200. __inline void ADC_Wait(void)  

  201. {  

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

  203. }  

  204.   

  205.   

  206. #endif  


touch.c


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

  2.  * 文件名: Touch.c 

  3.  * 功能:      S3C6410 电阻触摸屏驱动 

  4.  * 作者:      cp1300@139.com 

  5.  * 创建时间:    2012年10月6日17:31 

  6.  * 最后修改时间:2012年10月6日 

  7.  * 详细:      需要底层的ADC支持 

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

  9. #include "system.h"  

  10. #include "adc.h"  

  11. #include "touch.h"  

  12.   

  13.   

  14. Pen_Holder Pen_Point;//定义笔实体  

  15.   

  16.   

  17.   

  18. //开启触摸屏校准,需要其它支持  

  19. #define _TOUCH_ADJUST 1  

  20.   

  21. #if _TOUCH_ADJUST  

  22.     void TOUCH_Adjust(void);    //触摸屏校准  

  23. #endif //_TOUCH_ADJUST  

  24.   

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

  26. *函数        :    void TOUCH_Init(FunctionalState EnableInt) 

  27. *功能        :    触摸屏初始始化 

  28. *参数        :    EnableInt:笔中断使能 

  29. *返回        :    无 

  30. *依赖        :    底层宏定义 

  31. *作者        :    cp1300@139.com 

  32. *时间        :    20120313 

  33. *最后修改时间:        20121006 

  34. *说明        :    触摸屏初始始化 

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

  36. void TOUCH_Init(FunctionalState EnableInt)  

  37. {  

  38.     ADC_Init();                 //初始化ADC  

  39.     TOUCH_ClearInt();           //清除触摸屏中断标志  

  40.     ADC_ClearInt();             //清除ADC中断  

  41.     ADC_SetMode(INT_AD_MODER);  //等待中断模式  

  42.     ADCTSC_UD_SEN(DISABLE);     //设置为按下中断  

  43.     if(EnableInt == ENABLE) //开启笔中断  

  44.     {  

  45.         //Set_IsrAddr(INT_PENDNUP,(u32)Isr_Touch);  //设置中断矢量入口  

  46.         //Set_IntEnable(INT_PENDNUP,ENABLE);            //开启触摸屏按下  

  47.     }  

  48. #if _TOUCH_ADJUST  

  49.     TOUCH_Adjust();             //触摸屏校准  

  50. #endif //_TOUCH_ADJUST  

  51. }  

  52.   

  53.   

  54.   

  55.   

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

  57. * 函数    :   u16 ADS_Read_XY(u16(*ADC_ReadXY)(void)) 

  58. * 功能    :   使用冒泡法读取一次坐标 

  59. * 参数    :   ADC_ReadXY:X或Y坐标读取函数 

  60. * 返回    :   转换结果 

  61. * 依赖    :   ADC 

  62. * 作者    :   cp1300@139.com 

  63. * 时间    :   20121006 

  64. * 最后修改时间 : 20121006 

  65. * 说明    :   连续读取READ_TIMES次数据,对这些数据升序排列, 

  66.             然后去掉最低和最高LOST_VAL个数,取平均值  

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

  68. #define READ_TIMES 15 //读取次数  

  69. #define LOST_VAL 5    //丢弃值  

  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 ++)//排序  

  82.     {  

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

  84.         {  

  85.             if(buff[i] > buff[j])//升序排列  

  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. * 函数    :   u8 Read_ADS(u16 *x,u16 *y) 

  104. * 功能    :   带滤波的读取X,Y坐标 

  105. * 参数    :   X,Y坐标值缓冲区指针 

  106. * 返回    :   1:转换结果有效;0:转换结果无效 

  107. * 依赖    :   XPT2046底层函数 

  108. * 作者    :   cp1300@139.com 

  109. * 时间    :   20120914 

  110. * 最后修改时间 : 20120914 

  111. * 说明    :   带滤波的坐标读取 

  112.             最小值不能少于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);   //设置ADC为分离的X采样模式  

  120.     xtemp = ADS_Read_XY(ADC_ReadX); //读取X坐标  

  121.     ADC_SetMode(ASUNDER_Y_MODER);   //设置ADC为分离的Y采样模式  

  122.     ytemp = ADS_Read_XY(ADC_ReadY); //读取Y坐标  

  123.     ADC_SetMode(INT_AD_MODER);      //设置ADC为等待中断模式  

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

  125.         return 0;//读数失败  

  126.     *x = xtemp;  

  127.     *y = ytemp;  

  128.   

  129.     return 1;//读数成功  

  130. }  

  131.   

  132.   

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

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

  135. * 功能    :   连续读取2次有效的AD值 

  136. * 参数    :   X,Y坐标值缓冲区指针 

  137. * 返回    :   1:转换结果有效;0:转换结果无效 

  138. * 依赖    :   u8 Read_ADS(u16 *x,u16 *y) 

  139. * 作者    :   cp1300@139.com 

  140. * 时间    :   20120914 

  141. * 最后修改时间 : 20120914 

  142. * 说明    :   连续读取2次有效的AD值,且这两次的偏差不能超过ERR_RANGE 

  143.             满足条件,则认为读数正确,否则读数错误.        

  144.             该函数能大大提高准确度 

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

  146. #define ERR_RANGE 50    //误差范围   

  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)))   //前后两次采样在+-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. * 函数    :   u8 TOUCH_ReadOneTP(void) 

  173. * 功能    :   读取一次原始坐标 

  174. * 参数    :   无 

  175. * 返回    :   1:转换结果有效;0:转换结果无效 

  176. * 依赖    :   u8 Read_ADS2(u16 *x,u16 *y)  

  177. * 作者    :   cp1300@139.com 

  178. * 时间    :   20120914 

  179. * 最后修改时间 : 20120914 

  180. * 说明    :   调用Read_ADS2函数进行读取,如果Read_ADS2读取失败,重复读取,最多读取MAX_READ_ADS次 

  181.             如果失败,将返回0,注意返回1代表结果有效 

  182.             转换的结果存放在结构体Pen_Holder,的x0,y0中 

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

  184. #define  MAX_READ_ADS   5   //最大重试次数  

  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;   //转换有效,存储结果  

  195.             Pen_Point.y0 = y;  

  196.             return 1;           //返回成功  

  197.         }  

  198.     }  

  199.   

  200.     return 0;       //返回失败  

  201. }  

  202.   

  203.   

  204.   

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

  206. * 函数    :   void TOUCH_ConvertPos(void) 

  207. * 功能    :   采集并转换触摸坐标 

  208. * 参数    :   无 

  209. * 返回    :   无 

  210. * 依赖    :   LCD.C,触摸屏ADC底层 

  211. * 作者    :   cp1300@139.com 

  212. * 时间    :   20120914 

  213. * 最后修改时间 : 20121006 

  214. * 说明    :   根据触摸屏的校准参数来决定转换后的结果,保存在x,y中 

  215. *           需要先进行触摸校准 

  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. //触摸屏校准相关  

  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. * 函数    :   void Drow_Touch_Point(u16 x,u16 y) 

  239. * 功能    :   画一个触摸点,用于校准 

  240. * 参数    :   x,y:触摸点中心位置 

  241. * 返回    :   无 

  242. * 依赖    :   LCD.C 

  243. * 作者    :   cp1300@139.com 

  244. * 时间    :   20120914 

  245. * 最后修改时间 : 20120914 

  246. * 说明    :   会调用LCD.C中的画圆,画线,画矩形等函数 

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

  248. void Drow_Touch_Point(u16 x,u16 y)  

  249. {  

  250.     Draw_Circle(x,y,10,0xf0f0);//画圆  

  251.     Draw_Circle(x,y,3,0xf0f0);//画圆  

  252.     LCD_DrawLine(x - 15, y, x + 15, y,0xf0f0);//画线  

  253.     LCD_DrawLine(x, y - 15, x, y + 15,0xf0f0);//画线    

  254.     LCD_DrawRectangle(x - 10,y - 10,x + 10,y + 10,0xf0f0);//画矩形  

  255. }  

  256.   

  257.   

  258.   

  259.   

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

  261. * 函数    :   void TOUCH_Adjust(void) 

  262. * 功能    :   进行触摸屏校准 

  263. * 参数    :   无 

  264. * 返回    :   无 

  265. * 依赖    :   LCD.C,触摸屏ADC底层 

  266. * 作者    :   cp1300@139.com 

  267. * 时间    :   20120914 

  268. * 最后修改时间 : 20120914 

  269. * 说明    :   得到四个校准值 

  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];//坐标缓存值  

  278.     u8  cnt=0;    

  279.     u16 d1,d2;  

  280.     u32 tem1,tem2;  

  281.     float fac;       

  282.     cnt=0;  

  283.                       

  284.   

  285.     LCD_ClearScreen(0xffff);//清屏     

  286.     Drow_Touch_Point(20,20);//画点1   

  287.     //Pen_Point.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误     

  288.     while(1)  

  289.     {  

  290.         if(GetPenStartus() == TOUCH_DOWN)//按键按下了  

  291.         {  

  292.             if(TOUCH_ReadOneTP())//得到单次按键值  

  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);   //等待按键抬起               

  299.             switch(cnt)  

  300.             {                

  301.                 case 1:  

  302.                     LCD_ClearScreen(0xffff);//清屏    

  303.                     Drow_Touch_Point(LCD_XSIZE-20,20);//画点2  

  304.                     break;  

  305.                 case 2:  

  306.                     LCD_ClearScreen(0xffff);//清屏    

  307.                     Drow_Touch_Point(20,LCD_YSIZE-20);//画点3  

  308.                     break;  

  309.                 case 3:  

  310.                     LCD_ClearScreen(0xffff);//清屏   

  311.                     Drow_Touch_Point(LCD_XSIZE-20,LCD_YSIZE-20);//画点4  

  312.                     break;  

  313.                 case 4:  //全部四个点已经得到  

  314.                     //对边相等  

  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);//得到1,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);//得到3,4的距离  

  326.                     fac=(float)d1/d2;  

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

  328.                     {  

  329.                         cnt=0;  

  330.                         LCD_ClearScreen(0xffff);//清屏    

  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);//得到1,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);//得到2,4的距离  

  345.                     fac=(float)d1/d2;  

  346.                     if(fac<0.95||fac>1.05)//不合格  

  347.                     {  

  348.                         cnt=0;  

  349.                         LCD_ClearScreen(0xffff);//清屏    

  350.                         Drow_Touch_Point(20,20);  

  351.                         continue;  

  352.                     }//正确了  

  353.                                      

  354.                     //对角线相等  

  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);//得到1,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);//得到2,3的距离  

  366.                     fac=(float)d1/d2;  

  367.                     if(fac<0.95||fac>1.05)//不合格  

  368.                     {  

  369.                         cnt=0;  

  370.                         LCD_ClearScreen(0xffff);//清屏    

  371.                         Drow_Touch_Point(20,20);  

  372.                         continue;  

  373.                     }//正确了  

  374.                     //计算结果  

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

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

  377.                             

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

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

  380.                     //Wire_Touch(); //存储校准结果  

  381.                     LCD_ClearScreen(0xffff);//清屏   

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

  383.                     Delay_MS(1000);  

  384.                     LCD_ClearScreen(0xffff);//清屏      

  385.                     return;//校正完成                  

  386.             }  

  387.         }  

  388.     }   

  389. }     

  390.   

  391.   

  392. #endif //_TOUCH_ADJUST  

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


touch.h

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

  2.  * 文件名: Touch.h 

  3.  * 功能:      S3C6410 电阻触摸屏驱动 

  4.  * 作者:      cp1300@139.com 

  5.  * 创建时间:    2012年10月6日17:31 

  6.  * 最后修改时间:2012年10月6日 

  7.  * 详细:      需要底层的ADC支持 

  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. //笔杆结构体  

  24. typedef struct   

  25. {  

  26.     u16 x0;//原始坐标  

  27.     u16 y0;  

  28.     u16 x; //最终/暂存坐标  

  29.     u16 y;                                

  30.     u8  Touch_Sta;//笔的状态                

  31. //触摸屏校准参数  

  32.     float xfac;  

  33.     float yfac;  

  34.     short xoff;  

  35.     short yoff;  

  36. }Pen_Holder;            

  37. extern Pen_Holder Pen_Point;//定义一个笔杆的结构变量  

  38.   

  39.   

  40.   

  41. void TOUCH_Init(FunctionalState EnableInt);         //触摸屏初始化函数  

  42. u8 TOUCH_ReadOneTP(void);                           //读取一次坐标  

  43. #define GetPenStartus()     Get_TouchState()        //获取触摸笔状态  

  44. void TOUCH_ConvertPos(void);                        //获取转换后的实际坐标  

  45.   

  46.   

  47.   

  48.   

  49. #endif /*TOUCH_H_*/  


主函数测试程序


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闪烁程序,在定时器0中断服务程序中闪烁,周期400MS  

  11. void LED1_flash(void)  

  12. {  

  13.     LED1_FLASH();  

  14. }  

  15.   

  16.   

  17.   

  18. int main(void)  

  19. {     

  20.     LCD_Init();                 //初始化LCD  

  21.     UART0_Init(DISABLE,115200); //初始化串口,失能中断接收,波特率115200  

  22.     LED_Init();                 //初始化LED  

  23.   

  24.     Timer1_Init(400000-1,ENABLE,LED1_flash);    //初始化定时器0,周期400ms  

  25.     TOUCH_Init(DISABLE);        //初始化触摸屏  

  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闪烁  

  33.         //Delay_US(600000);  

  34.         if(GetPenStartus() == TOUCH_DOWN)       //笔按下  

  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. }  


//补充ADC相关寄存器结构


  1. #define ADC_BASE    0x7E00B000  

  2.   

  3. //ADC 寄存器  

  4. typedef struct  

  5. {  

  6.     vu32    CON;            //ADC控制寄存器   

  7.     vu32    TSC;            //触摸屏控制寄存器  

  8.     vu32    DLY;            //ADC开始延迟寄存器  

  9.     vu32    DAT0;           //ADC数据寄存器0  

  10.     vu32    DAT1;           //ADC数据寄存器1  

  11.     vu32    UPDN;           //触摸屏UP-DOWN寄存器  

  12.     vu32    CLRINT;         //ADC中断清除寄存器  

  13.     u32     Reserved;  

  14.     vu32    CLRINTPNDNUP;   //触摸屏笔中断寄存器  

  15. }ADC_TypeDef;  

  16.   

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



关键字:S3C6410裸机  电阻屏驱动 引用地址:S3C6410裸机电阻屏驱动

上一篇:OK6410开发板裸机DS18B20驱动
下一篇:OK6410裸机简单的NAND FLASH驱动

小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved