找回密码
 立即注册

QQ登录

只需一步,快速开始

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

电阻触摸屏的校准程序V1.0版--灼灼其华

[复制链接]
跳转到指定楼层
楼主
ID:90014 发表于 2015-9-14 18:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 jialinx 于 2015-9-14 18:51 编辑
  1. /* 头文件 touch.h */

  2. #ifndef TOUCH_H
  3. #define TOUCH_H

  4. /* 添加驱动文件 */
  5. //#include "Diver.h"

  6. typedef unsigned short int uint16_t ;

  7. typedef unsigned char uint8_t;

  8. typedef short int int16_t;

  9. /* 触摸屏必要数据结构体 */
  10. typedef struct
  11. {
  12.     /* 得到触摸屏X通道AD数据的方法 */
  13.     uint16_t (* const Get_XChannel)(void);

  14.     /* 得到触摸屏Y通道AD数据的方法 */
  15.     uint16_t (* const Get_YChannel)(void);

  16.     /* 延时函数 */
  17.     void (*Delay_ms)(uint16_t);

  18.     /* 查看触摸屏是否被按下  返回0表示未按下 否则被按下 */
  19.     uint8_t (*Get_StatusFlag)(void);

  20.     void (*Clear_PendingBit)(void);

  21.     /* 在液晶屏上显示十字号函数 */
  22.     void (*DispH)(uint16_t x ,uint16_t y);

  23.     /* 液晶屏的X=触摸屏的X*TP_Xk+TP_Xoffset Y坐标也同理*/
  24.     float Xk;

  25.     float Yk;

  26.     float Xoffset;

  27.     float Yoffset;

  28. }Tuch_TypeDef;

  29. /* 坐标结构体 */
  30. typedef struct
  31. {
  32.     uint16_t TP_X;

  33.     uint16_t TP_Y;

  34. }Touch_CoorDinate;


  35. #define Calibration_x1  50
  36. #define Calibration_y1  50

  37. #define Calibration_x2  50
  38. #define Calibration_y2  190

  39. #define Calibration_x3  270
  40. #define Calibration_y3  190

  41. #define Calibration_x4  270
  42. #define Calibration_y4  50


  43. /* 得到液晶屏的坐标 返回值0 坐标靠谱 否则不靠谱 */
  44. uint8_t Touch_GetCoordinate(Touch_CoorDinate *TP_COOR);

  45. /* 触摸屏校准 返回0 校准成功  否则失败 */
  46. uint8_t TP_Calibration(void);



  47. #endif // TOUCH_H_INCLUDED
复制代码



  1. /* 源文件 touch.c */

  2. /*
  3.     名称:电阻触摸屏的校准程序V1.0版
  4.     作者:灼灼其华

  5.     移植的时候只要给 Touch_Structure 这个变量赋初值 就可以了

  6.     Get_XChannel        得到X通道的数据的方法

  7.     Get_YChannel        得到Y通道数据的方法

  8.     Delay_ms            毫秒级延时函数

  9.     Get_StatusFlag      检测触摸屏被按下的方法 0 没有按下  1 已结按下了

  10.     Clear_PendingBit    清除触摸屏按下标志的方法

  11.     DispH               在液晶屏上显示十字号的方法

  12.     移植之前要先实现这几个简单的函数/方法
  13. */

  14. #include "touch.h"

  15. #define N   10
  16. /* 保存点击一次触摸屏 采集的数据 */
  17. static uint16_t TP_Coordinate[2][10];

  18. /* 给Touch_Structure 变量赋初值 */
  19. static Tuch_TypeDef     Touch_Structure;


  20. #define R   50
  21. /* 触摸屏数据滤波 */
  22. uint16_t TP_Data_Processing(uint16_t *pData,uint8_t Length)
  23. {
  24.     uint8_t i,j,Cnt=0,Max=0;

  25.     uint16_t Number,cc;

  26.     for(i=0;i<Length;i++)
  27.     {
  28.         for(j=0;j<Length;j++)
  29.         {
  30.             if(i==j)
  31.                 continue;

  32.             if(pData[i]>pData[j])
  33.                 cc=pData[i]-pData[j];
  34.             else
  35.                 cc=pData[j]-pData[i];

  36.             if(cc<R)
  37.             {
  38.                 Cnt++;
  39.             }
  40.         }

  41.         if(Cnt>Max)
  42.         {
  43.             Max=Cnt;
  44.             Number=pData[i];
  45.         }
  46.         Cnt=0;
  47.     }

  48.     return Number;
  49. }

  50. /* 求二阶行列式的值 */
  51. int16_t Get_Determinant_2(int16_t a11,int16_t a12,int16_t a21,int16_t a22)
  52. {
  53.     return (a11*a22-a21*a12);
  54. }

  55. /* 解二元一次方程 前两列保存的是系数 */
  56. uint8_t Solve_Equations_2(int16_t(*ptr)[3],float *k,float *off)
  57. {
  58.     int16_t D,D1,D2;

  59.     D=Get_Determinant_2(ptr[0][0],ptr[0][1],ptr[1][0],ptr[1][1]);

  60.     if(D==0)
  61.         return 1;

  62.     D1=Get_Determinant_2(ptr[0][2],ptr[0][1],ptr[1][2],ptr[1][1]);

  63.     D2=Get_Determinant_2(ptr[0][0],ptr[0][2],ptr[1][0],ptr[1][2]);

  64.     *k=D1/(float)D;

  65.     *off=D2/(float)D;

  66.     return 0;
  67. }

  68. /* 求绝对值 */
  69. uint16_t Get_ABS(uint16_t x,uint16_t y)
  70. {
  71.     if(x>y)
  72.         return x-y;
  73.     else
  74.         return y-x;
  75. }


  76. // 允许的误差 */
  77. #define CCMAX   50

  78. /* 得到触摸屏的坐标 并且滤波 返回0 表示坐标靠谱   否则是不靠谱的 */
  79. uint8_t TP_GetCoorDinate(Touch_CoorDinate *TP_COOR)
  80. {
  81.     uint8_t bit;

  82.     uint16_t TP_XCoor_1,TP_YCoor_1;
  83.     uint16_t TP_XCoor_2,TP_YCoor_2;
  84.     /* 第一次采集数据 */
  85.     for(bit=0;bit<N;bit++)
  86.     {
  87.         /* 采集10次 X 数据 */
  88.         TP_Coordinate[0][bit]=Touch_Structure.Get_XChannel();

  89.         /* 采集10次 Y 数据 */
  90.         TP_Coordinate[1][bit]=Touch_Structure.Get_YChannel();
  91.     }

  92.     TP_XCoor_1=TP_Data_Processing(TP_Coordinate[0],N);

  93.     TP_YCoor_1=TP_Data_Processing(TP_Coordinate[1],N);

  94.     /* 第二次采集数据 */
  95.     for(bit=0;bit<N;bit++)
  96.     {
  97.         /* 采集10次 X 数据 */
  98.         TP_Coordinate[0][bit]=Touch_Structure.Get_XChannel();

  99.         /* 采集10次 Y 数据 */
  100.         TP_Coordinate[1][bit]=Touch_Structure.Get_YChannel();
  101.     }

  102.     TP_XCoor_2=TP_Data_Processing(TP_Coordinate[0],N);

  103.     TP_YCoor_2=TP_Data_Processing(TP_Coordinate[1],N);

  104.     /* 两次采集的数据之差不能超过CCMAX 否则认为数据不靠谱 */

  105.     if( Get_ABS(TP_XCoor_1 , TP_XCoor_2) >CCMAX )
  106.         return 1;

  107.     if( Get_ABS(TP_YCoor_1 , TP_YCoor_2) >CCMAX )
  108.         return 1;

  109.     /* 取两次采集数据的平均值 */
  110.     TP_COOR->TP_X=(TP_XCoor_1>>1)+(TP_XCoor_2>>1);

  111.     TP_COOR->TP_Y=(TP_YCoor_1>>1)+(TP_YCoor_2>>1);
  112. }

  113. /* 校准误差 */
  114. #define CCMA        100

  115. /* 触摸屏校准 */
  116. uint8_t TP_Calibration(void)
  117. {
  118.         Touch_CoorDinate TP_COOR[4];

  119.     int16_t arr[2][3];

  120.     uint16_t CC,CC1,CC2;

  121.     /* 校准第一个点 */
  122.     Touch_Structure.Delay_ms(500);

  123.     Touch_Structure.DispH(Calibration_x1,Calibration_y1);

  124.     Touch_Structure.Clear_PendingBit();

  125.     while(1)
  126.     {
  127.         if(Touch_Structure.Get_StatusFlag())
  128.         {
  129.             Touch_Structure.Clear_PendingBit();

  130.             if(TP_GetCoorDinate(TP_COOR))
  131.             {
  132.                 /* 显示重新点击 */
  133.             }
  134.             else
  135.                 break;
  136.         }
  137.     }


  138.     /* 校准第二个点 */
  139.     Touch_Structure.Delay_ms(500);

  140.     Touch_Structure.DispH(Calibration_x2,Calibration_y2);

  141.     Touch_Structure.Clear_PendingBit();

  142.     while(1)
  143.     {
  144.         if(Touch_Structure.Get_StatusFlag())
  145.         {
  146.             Touch_Structure.Clear_PendingBit();

  147.             if(TP_GetCoorDinate(TP_COOR+1))
  148.             {
  149.                 /* 显示重新点击 */
  150.             }
  151.             else
  152.                 break;
  153.         }
  154.     }


  155.     /* 校准第三个点 */
  156.     Touch_Structure.Delay_ms(500);

  157.     Touch_Structure.DispH(Calibration_x3,Calibration_y3);

  158.     Touch_Structure.Clear_PendingBit();

  159.     while(1)
  160.     {
  161.         if(Touch_Structure.Get_StatusFlag())
  162.         {
  163.             Touch_Structure.Clear_PendingBit();

  164.             if(TP_GetCoorDinate(TP_COOR+2))
  165.             {
  166.                 /* 显示重新点击 */
  167.             }
  168.             else
  169.                 break;
  170.         }
  171.     }


  172.      /* 校准第四个点 */
  173.     Touch_Structure.Delay_ms(500);

  174.     Touch_Structure.DispH(Calibration_x4,Calibration_y4);

  175.     Touch_Structure.Clear_PendingBit();

  176.     while(1)
  177.     {
  178.         if(Touch_Structure.Get_StatusFlag())
  179.         {
  180.             Touch_Structure.Clear_PendingBit();

  181.             if(TP_GetCoorDinate(TP_COOR+3))
  182.             {
  183.                 /* 显示重新点击 */
  184.             }
  185.             else
  186.                 break;
  187.         }
  188.     }

  189.     /* 检查数据是否准确 */

  190.     CC1=Get_ABS(TP_COOR[0].TP_X , TP_COOR[3].TP_X);

  191.     CC2=Get_ABS(TP_COOR[2].TP_X , TP_COOR[1].TP_X);

  192.     CC=Get_ABS(CC1,CC2);

  193.     if(CC>CCMA)
  194.         return 1;

  195.     CC1=Get_ABS(TP_COOR[0].TP_Y , TP_COOR[1].TP_Y);

  196.     CC2=Get_ABS(TP_COOR[2].TP_Y , TP_COOR[3].TP_Y);

  197.     CC=Get_ABS(CC1,CC2);

  198.     if(CC>CCMA)
  199.         return 1;

  200.     /* 解方程求 TP_Xk TP_Yk TP_Xoffset TP_Yoffset */
  201.     /* 触摸屏坐标*K+offset =液晶屏坐标 */
  202.     arr[0][0]=TP_COOR[0].TP_X; arr[0][1]=1; arr[0][2]=Calibration_x1;

  203.     arr[1][0]=TP_COOR[2].TP_X; arr[1][1]=1; arr[1][2]=Calibration_x3;

  204.     if(Solve_Equations_2(arr , &Touch_Structure.Xk , &Touch_Structure.Xoffset))
  205.     {
  206.         /* 显示方程无解 数据错误 */

  207.         return 1;
  208.     }

  209.     arr[0][0]=TP_COOR[1].TP_Y; arr[0][1]=1; arr[0][2]=Calibration_y2;

  210.     arr[1][0]=TP_COOR[3].TP_Y; arr[1][1]=1; arr[1][2]=Calibration_y4;

  211.     if(Solve_Equations_2(arr , &Touch_Structure.Yk , &Touch_Structure.Yoffset))
  212.     {
  213.         /* 显示方程无解 数据错误 */

  214.         return 1;
  215.     }

  216.         return 0;
  217. }

  218. /* 得到液晶屏的坐标 返回值0 坐标靠谱 否则不靠谱 */
  219. uint8_t Touch_GetCoordinate(Touch_CoorDinate *TP_COOR)
  220. {
  221.     if(TP_GetCoorDinate(TP_COOR))
  222.         return 1;

  223.     /* 数据一般不会得到极值 */
  224.     /*
  225.     if(TP_COOR->TP_X==0||TP_COOR->TP_X==4095 ||TP_COOR->TP_Y==0 ||TP_COOR->TP_Y==4095)
  226.         return 1;
  227.     */

  228.     TP_COOR->TP_X=TP_COOR->TP_X*Touch_Structure.Xk+Touch_Structure.Xoffset;

  229.     TP_COOR->TP_Y=TP_COOR->TP_Y*Touch_Structure.Yk+Touch_Structure.Yoffset;

  230.     return 0;
  231. }
复制代码



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

使用道具 举报

沙发
ID:83422 发表于 2015-9-15 13:13 | 只看该作者
挺不错的呀。。。
回复

使用道具 举报

板凳
ID:64765 发表于 2017-5-16 20:13 | 只看该作者
好资料,下载学习,谢谢分享。
回复

使用道具 举报

地板
ID:64765 发表于 2017-5-16 20:29 | 只看该作者
学习了,谢谢分享。
回复

使用道具 举报

5#
ID:201854 发表于 2017-5-17 16:46 | 只看该作者
谢谢分享。!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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