找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8465|回复: 12
打印 上一主题 下一主题
收起左侧

xpt2046.h和.c头文件 电阻触摸屏驱动下载

  [复制链接]
跳转到指定楼层
楼主

附件两个代码为xpt2046.c和xpt2046.h,是常用的电阻触摸屏驱动
所有资料51hei提供下载:
xpt2046.zip (4.65 KB, 下载次数: 195)


单片机源程序如下:
  1. #include "xpt2046.h"
  2. #include "ili93xx.h"
  3. #include "stdlib.h"
  4. #include "math.h"

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

  6. void delay_us(u32 us)
  7. {
  8.     u32 time=100*us/7;   
  9.     while(--time);   
  10. }


  11. //SPI写数据
  12. //向7846/7843/XPT2046/UH7843/UH7846写入1byte数据   
  13. void ADS_Write_Byte(u8 num)   
  14. {  
  15.         u8 count=0;   
  16.         for(count=0;count<8;count++)  
  17.         {           
  18.                 if(num&0x80)
  19.                         Set_TOUCH_TDIN
  20.                 else
  21.                         Clr_TOUCH_TDIN;   
  22.                 num<<=1;   
  23.                 Clr_TOUCH_TCLK;//上升沿有效                    
  24.                 Set_TOUCH_TCLK;      
  25.         }                             
  26. }                  

  27. //SPI读数据
  28. //从7846/7843/XPT2046/UH7843/UH7846读取adc值          
  29. u16 ADS_Read_AD(u8 CMD)          
  30. {          
  31.         u8 count=0;           
  32.         u16 Num=0;
  33.        
  34.         Clr_TOUCH_TCLK;//先拉低时钟          
  35.         Clr_TOUCH_TCS; //选中ADS7843         
  36.         ADS_Write_Byte(CMD);//发送命令字
  37.         delay_us(6);//ADS7846的转换时间最长为6us
  38.         Set_TOUCH_TCLK;//给1个时钟,清除BUSY               
  39.         Clr_TOUCH_TCLK;          
  40.        
  41.         for(count=0;count<16;count++)  
  42.         {                                   
  43.                 Num<<=1;          
  44.                 Clr_TOUCH_TCLK;//下降沿有效                        
  45.                 Set_TOUCH_TCLK;
  46.                 if(TOUCH_DOUT)
  47.                 Num++;                  
  48.         }         
  49.        
  50.         Num>>=4;   //只有高12位有效.
  51.         Set_TOUCH_TCS;//释放ADS7843         
  52.         return(Num);   
  53. }


  54. //读取一个坐标值
  55. //连续读取READ_TIMES次数据,对这些数据升序排列,
  56. //然后去掉最低和最高LOST_VAL个数,取平均值
  57. #define READ_TIMES 15 //读取次数
  58. #define LOST_VAL 5          //丢弃值
  59. u16 ADS_Read_XY(u8 xy)
  60. {
  61.         u16 i, j;
  62.         u16 buf[READ_TIMES];
  63.         u16 sum=0;
  64.         u16 temp;
  65.        
  66.         for(i=0;i<READ_TIMES;i++)
  67.         {                                 
  68.                 buf[i]=ADS_Read_AD(xy);            
  69.         }                                    
  70.         for(i=0;i<READ_TIMES-1; i++)//排序
  71.         {
  72.                 for(j=i+1;j<READ_TIMES;j++)
  73.                 {
  74.                         if(buf[i]>buf[j])//升序排列
  75.                         {
  76.                                 temp=buf[i];
  77.                                 buf[i]=buf[j];
  78.                                 buf[j]=temp;
  79.                         }
  80.                 }
  81.         }          
  82.         sum=0;
  83.         for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++)sum+=buf[i];
  84.         temp=sum/(READ_TIMES-2*LOST_VAL);
  85.         return temp;   
  86. }


  87. //带滤波的坐标读取
  88. //最小值不能少于100.
  89. u8 Read_ADS(u16 *x,u16 *y)
  90. {
  91.         u16 xtemp,ytemp;                                                    
  92.         xtemp=ADS_Read_XY(CMD_RDX);
  93.         ytemp=ADS_Read_XY(CMD_RDY);                                                                                                            
  94.         if(xtemp<100||ytemp<100)return 0;//读数失败
  95.         *x=xtemp;
  96.         *y=ytemp;
  97.         return 1;//读数成功
  98. }       


  99. //2次读取ADS7846,连续读取2次有效的AD值,且这两次的偏差不能超过
  100. //50,满足条件,则认为读数正确,否则读数错误.          
  101. //该函数能大大提高准确度
  102. #define ERR_RANGE 50 //误差范围
  103. u8 Read_ADS2(u16 *x,u16 *y)
  104. {
  105.         u16 x1,y1;
  106.         u16 x2,y2;
  107.         u8 flag;   
  108.     flag=Read_ADS(&x1,&y1);   
  109.     if(flag==0)return(0);
  110.     flag=Read_ADS(&x2,&y2);          
  111.     if(flag==0)return(0);   
  112.     if(((x2<=x1&&x1<x2+ERR_RANGE)||(x1<=x2&&x2<x1+ERR_RANGE))//前后两次采样在+-50内
  113.     &&((y2<=y1&&y1<y2+ERR_RANGE)||(y1<=y2&&y2<y1+ERR_RANGE)))
  114.     {
  115.         *x=(x1+x2)/2;
  116.         *y=(y1+y2)/2;
  117.         return 1;
  118.     }else{
  119.                 return 0;          
  120.         }       
  121. }


  122. //读取一次坐标值       
  123. //仅仅读取一次,知道PEN松开才返回!                                          
  124. u8 Read_TP_Once(void)
  125. {
  126.         u8 t=0;            
  127.         Pen_Int_Set(0);//关闭中断
  128.         Pen_Point.Key_Sta=Key_Up;
  129.         Read_ADS2(&Pen_Point.X,&Pen_Point.Y);
  130.         while(TOUCH_PEN==0&&t<=250)
  131.         {
  132.                 t++;
  133.                 delay_us(10000);
  134.         };
  135.         Pen_Int_Set(1);//开启中断                 
  136.         if(t>=250)
  137.                 return 0;//按下2.5s 认为无效
  138.         else
  139.                 return 1;       
  140. }


  141. /**************************************与LCD部分有关的函数****************************************/

  142. //画一个触摸点
  143. //用来校准用的
  144. void Drow_Touch_Point(u8 x,u16 y)
  145. {
  146.         LCD_DrawLine(x-12,y,x+13,y);//横线
  147.         LCD_DrawLine(x,y-12,x,y+13);//竖线
  148.         LCD_DrawPoint(x+1,y+1);
  149.         LCD_DrawPoint(x-1,y+1);
  150.         LCD_DrawPoint(x+1,y-1);
  151.         LCD_DrawPoint(x-1,y-1);
  152.         Draw_Circle(x,y,6);//画中心圈
  153. }          
  154. //画一个大点
  155. //2*2的点                          
  156. void Draw_Big_Point(u8 x,u16 y)
  157. {            
  158.         LCD_DrawPoint(x,y);//中心点
  159.         LCD_DrawPoint(x+1,y);
  160.         LCD_DrawPoint(x,y+1);
  161.         LCD_DrawPoint(x+1,y+1);                          
  162. }

  163. /***************************************************************************************************/


  164. //转换结果
  165. //根据触摸屏的校准参数来决定转换后的结果,保存在X0,Y0中
  166. void Convert_Pos(void)
  167. {                           
  168.         if(Read_ADS2(&Pen_Point.X,&Pen_Point.Y))
  169.         {
  170.                 Pen_Point.X0=Pen_Point.xfac*Pen_Point.X+Pen_Point.xoff;
  171.                 Pen_Point.Y0=Pen_Point.yfac*Pen_Point.Y+Pen_Point.yoff;  
  172.         }
  173. }          



  174. //PEN中断设置
  175. //启用一个外部中断当触摸屏被按下后出发外部中断
  176. //外部中断函数:
  177. //        检测PEN脚的一个下降沿
  178. //        void EXTI1_IRQHandler(void)
  179. //        {                                             
  180. //                Pen_Point.Key_Sta=Key_Down;//按键按下
  181. //            EXTI_ClearFlag(EXTI_Line1);//清除LINE1上的中断标志位                                            
  182. //        }          
  183. void Pen_Int_Set(u8 en)
  184. {
  185.         EXTI_InitTypeDef EXTI_InitStructure;

  186.         if(en)
  187.         {                         
  188.                 EXTI_InitStructure.EXTI_Line = EXTI_Line1;        //外部线路EXIT1
  189.                 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                        //设外外部中断模式:EXTI线路为中断请求
  190.                 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  //外部中断触发沿选择:设置输入线路下降沿为中断请求
  191.                 EXTI_InitStructure.EXTI_LineCmd = ENABLE;                //使能外部中断新状态
  192.                 EXTI_Init(&EXTI_InitStructure);                //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器       

  193.         }else{        

  194.                 EXTI_InitStructure.EXTI_Line = EXTI_Line1;        //外部线路EXIT1
  195.                 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;                        //设外外部中断模式:EXTI线路为中断请求
  196.                 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  //外部中断触发沿选择:设置输入线路下降沿为中断请求
  197.                 EXTI_InitStructure.EXTI_LineCmd = DISABLE;                //关闭外部中断新状态
  198.                 EXTI_Init(&EXTI_InitStructure);                //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器          

  199.         }
  200.                
  201. }          


  202. //触摸屏校准代码
  203. //得到四个校准参数
  204. void Touch_Adjust(void)
  205. {                                                                 
  206.         u16 pos_temp[4][2];//坐标缓存值
  207.         u8  cnt=0;       
  208.         u16 d1,d2;
  209.         u32 tem1,tem2;
  210.         float fac;           
  211.         cnt=0;                               
  212.         POINT_COLOR=BLUE;
  213.         BACK_COLOR =WHITE;
  214.         LCD_Clear(WHITE);//清屏   
  215.         POINT_COLOR=RED;//红色
  216.         LCD_Clear(WHITE);//清屏
  217.         Drow_Touch_Point(20,20);//画点1
  218.         Pen_Point.Key_Sta=Key_Up;//消除触发信号
  219.         Pen_Point.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误         
  220.         while(1)
  221.         {
  222.                 if(Pen_Point.Key_Sta==Key_Down)//按键按下了
  223.                 {
  224.                         if(Read_TP_Once())//得到单次按键值
  225.                         {                                                                    
  226.                                 pos_temp[cnt][0]=Pen_Point.X;
  227.                                 pos_temp[cnt][1]=Pen_Point.Y;
  228.                                 cnt++;
  229.                         }                         
  230.                         switch(cnt)
  231.                         {                          
  232.                                 case 1:
  233.                                         LCD_Clear(WHITE);//清屏
  234.                                         Drow_Touch_Point(220,20);//画点2
  235.                                         break;
  236.                                 case 2:
  237.                                         LCD_Clear(WHITE);//清屏
  238.                                         Drow_Touch_Point(20,300);//画点3
  239.                                         break;
  240.                                 case 3:
  241.                                         LCD_Clear(WHITE);//清屏
  242.                                         Drow_Touch_Point(220,300);//画点4
  243.                                         break;
  244.                                 case 4:         //全部四个点已经得到
  245.                                 //对边相等
  246.                                         tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2
  247.                                         tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2
  248.                                         tem1*=tem1;
  249.                                         tem2*=tem2;
  250.                                         d1=sqrt(tem1+tem2);//得到1,2的距离
  251.                                        
  252.                                         tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4
  253.                                         tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4
  254.                                         tem1*=tem1;
  255.                                         tem2*=tem2;
  256.                                         d2=sqrt(tem1+tem2);//得到3,4的距离
  257.                                         fac=(float)d1/d2;
  258.                                         if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格
  259.                                         {
  260.                                                 cnt=0;
  261.                                                 LCD_Clear(WHITE);//清屏
  262.                                                 Drow_Touch_Point(20,20);
  263.                                                 continue;
  264.                                         }
  265.                                         tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3
  266.                                         tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3
  267.                                         tem1*=tem1;
  268.                                         tem2*=tem2;
  269.                                         d1=sqrt(tem1+tem2);//得到1,3的距离
  270.                                        
  271.                                         tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4
  272.                                         tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4
  273.                                         tem1*=tem1;
  274.                                         tem2*=tem2;
  275.                                         d2=sqrt(tem1+tem2);//得到2,4的距离
  276.                                         fac=(float)d1/d2;
  277.                                         if(fac<0.95||fac>1.05)//不合格
  278.                                         {
  279.                                                 cnt=0;
  280.                                                 LCD_Clear(WHITE);//清屏
  281.                                                 Drow_Touch_Point(20,20);
  282.                                                 continue;
  283.                                         }//正确了
  284.                                                                   
  285.                                         //对角线相等
  286.                                         tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3
  287.                                         tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3
  288.                                         tem1*=tem1;
  289.                                         tem2*=tem2;
  290.                                         d1=sqrt(tem1+tem2);//得到1,4的距离
  291.        
  292.                                         tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4
  293.                                         tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4
  294.                                         tem1*=tem1;
  295.                                         tem2*=tem2;
  296.                                         d2=sqrt(tem1+tem2);//得到2,3的距离
  297.                                         fac=(float)d1/d2;
  298.                                         if(fac<0.95||fac>1.05)//不合格
  299. ……………………

  300. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:20672 发表于 2018-8-14 10:51 | 只看该作者
谢谢分享~~~
回复

使用道具 举报

板凳
ID:428798 发表于 2018-11-18 18:20 | 只看该作者
谢谢分享~~~~
回复

使用道具 举报

地板
ID:65961 发表于 2019-3-6 09:49 | 只看该作者

谢谢分享~~~~
回复

使用道具 举报

5#
ID:65961 发表于 2019-3-7 09:57 | 只看该作者
谢谢分享~~~~但要5黑币呀
回复

使用道具 举报

6#
ID:323481 发表于 2019-4-26 22:12 | 只看该作者
谢谢分享~~~~
回复

使用道具 举报

7#
ID:282542 发表于 2019-10-10 20:46 | 只看该作者
谢谢
回复

使用道具 举报

8#
ID:641168 发表于 2019-11-13 14:43 | 只看该作者
谢谢分享~
回复

使用道具 举报

9#
ID:282431 发表于 2019-11-13 15:38 | 只看该作者
触摸屏驱动好资料,谢谢分享
回复

使用道具 举报

10#
ID:653605 发表于 2019-12-1 16:33 | 只看该作者
谢谢分享~~~
回复

使用道具 举报

11#
ID:834304 发表于 2020-10-25 14:23 | 只看该作者
谢谢楼主分享~先留言,黑币够了来下载一下
回复

使用道具 举报

12#
ID:705471 发表于 2020-12-5 10:22 | 只看该作者
芯片比较早了,但基础知识多了解才能扎实,谢谢。
回复

使用道具 举报

13#
ID:854455 发表于 2020-12-15 15:36 | 只看该作者
虽然芯片比较老了,但好多行业还是会用到我想多了解一下基础知道。谢谢楼主了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表