本帖最后由 jialinx 于 2015-9-14 18:51 編輯
- /* 頭文件 touch.h */
- #ifndef TOUCH_H
- #define TOUCH_H
- /* 添加驅動文件 */
- //#include "Diver.h"
- typedef unsigned short int uint16_t ;
- typedef unsigned char uint8_t;
- typedef short int int16_t;
- /* 觸摸屏必要數據結構體 */
- typedef struct
- {
- /* 得到觸摸屏X通道AD數據的方法 */
- uint16_t (* const Get_XChannel)(void);
- /* 得到觸摸屏Y通道AD數據的方法 */
- uint16_t (* const Get_YChannel)(void);
- /* 延時函數 */
- void (*Delay_ms)(uint16_t);
- /* 查看觸摸屏是否被按下 返回0表示未按下 否則被按下 */
- uint8_t (*Get_StatusFlag)(void);
- void (*Clear_PendingBit)(void);
- /* 在液晶屏上顯示十字號函數 */
- void (*DispH)(uint16_t x ,uint16_t y);
- /* 液晶屏的X=觸摸屏的X*TP_Xk+TP_Xoffset Y坐標也同理*/
- float Xk;
- float Yk;
- float Xoffset;
- float Yoffset;
- }Tuch_TypeDef;
- /* 坐標結構體 */
- typedef struct
- {
- uint16_t TP_X;
- uint16_t TP_Y;
- }Touch_CoorDinate;
- #define Calibration_x1 50
- #define Calibration_y1 50
- #define Calibration_x2 50
- #define Calibration_y2 190
- #define Calibration_x3 270
- #define Calibration_y3 190
- #define Calibration_x4 270
- #define Calibration_y4 50
- /* 得到液晶屏的坐標 返回值0 坐標靠譜 否則不靠譜 */
- uint8_t Touch_GetCoordinate(Touch_CoorDinate *TP_COOR);
- /* 觸摸屏校準 返回0 校準成功 否則失敗 */
- uint8_t TP_Calibration(void);
- #endif // TOUCH_H_INCLUDED
復制代碼
- /* 源文件 touch.c */
- /*
- 名稱:電阻觸摸屏的校準程序V1.0版
- 作者:灼灼其華
- 移植的時候只要給 Touch_Structure 這個變量賦初值 就可以了
- Get_XChannel 得到X通道的數據的方法
- Get_YChannel 得到Y通道數據的方法
- Delay_ms 毫秒級延時函數
- Get_StatusFlag 檢測觸摸屏被按下的方法 0 沒有按下 1 已結按下了
- Clear_PendingBit 清除觸摸屏按下標志的方法
- DispH 在液晶屏上顯示十字號的方法
- 移植之前要先實現這幾個簡單的函數/方法
- */
- #include "touch.h"
- #define N 10
- /* 保存點擊一次觸摸屏 采集的數據 */
- static uint16_t TP_Coordinate[2][10];
- /* 給Touch_Structure 變量賦初值 */
- static Tuch_TypeDef Touch_Structure;
- #define R 50
- /* 觸摸屏數據濾波 */
- uint16_t TP_Data_Processing(uint16_t *pData,uint8_t Length)
- {
- uint8_t i,j,Cnt=0,Max=0;
- uint16_t Number,cc;
- for(i=0;i<Length;i++)
- {
- for(j=0;j<Length;j++)
- {
- if(i==j)
- continue;
- if(pData[i]>pData[j])
- cc=pData[i]-pData[j];
- else
- cc=pData[j]-pData[i];
- if(cc<R)
- {
- Cnt++;
- }
- }
- if(Cnt>Max)
- {
- Max=Cnt;
- Number=pData[i];
- }
- Cnt=0;
- }
- return Number;
- }
- /* 求二階行列式的值 */
- int16_t Get_Determinant_2(int16_t a11,int16_t a12,int16_t a21,int16_t a22)
- {
- return (a11*a22-a21*a12);
- }
- /* 解二元一次方程 前兩列保存的是系數 */
- uint8_t Solve_Equations_2(int16_t(*ptr)[3],float *k,float *off)
- {
- int16_t D,D1,D2;
- D=Get_Determinant_2(ptr[0][0],ptr[0][1],ptr[1][0],ptr[1][1]);
- if(D==0)
- return 1;
- D1=Get_Determinant_2(ptr[0][2],ptr[0][1],ptr[1][2],ptr[1][1]);
- D2=Get_Determinant_2(ptr[0][0],ptr[0][2],ptr[1][0],ptr[1][2]);
- *k=D1/(float)D;
- *off=D2/(float)D;
- return 0;
- }
- /* 求絕對值 */
- uint16_t Get_ABS(uint16_t x,uint16_t y)
- {
- if(x>y)
- return x-y;
- else
- return y-x;
- }
- // 允許的誤差 */
- #define CCMAX 50
- /* 得到觸摸屏的坐標 并且濾波 返回0 表示坐標靠譜 否則是不靠譜的 */
- uint8_t TP_GetCoorDinate(Touch_CoorDinate *TP_COOR)
- {
- uint8_t bit;
- uint16_t TP_XCoor_1,TP_YCoor_1;
- uint16_t TP_XCoor_2,TP_YCoor_2;
- /* 第一次采集數據 */
- for(bit=0;bit<N;bit++)
- {
- /* 采集10次 X 數據 */
- TP_Coordinate[0][bit]=Touch_Structure.Get_XChannel();
- /* 采集10次 Y 數據 */
- TP_Coordinate[1][bit]=Touch_Structure.Get_YChannel();
- }
- TP_XCoor_1=TP_Data_Processing(TP_Coordinate[0],N);
- TP_YCoor_1=TP_Data_Processing(TP_Coordinate[1],N);
- /* 第二次采集數據 */
- for(bit=0;bit<N;bit++)
- {
- /* 采集10次 X 數據 */
- TP_Coordinate[0][bit]=Touch_Structure.Get_XChannel();
- /* 采集10次 Y 數據 */
- TP_Coordinate[1][bit]=Touch_Structure.Get_YChannel();
- }
- TP_XCoor_2=TP_Data_Processing(TP_Coordinate[0],N);
- TP_YCoor_2=TP_Data_Processing(TP_Coordinate[1],N);
- /* 兩次采集的數據之差不能超過CCMAX 否則認為數據不靠譜 */
- if( Get_ABS(TP_XCoor_1 , TP_XCoor_2) >CCMAX )
- return 1;
- if( Get_ABS(TP_YCoor_1 , TP_YCoor_2) >CCMAX )
- return 1;
- /* 取兩次采集數據的平均值 */
- TP_COOR->TP_X=(TP_XCoor_1>>1)+(TP_XCoor_2>>1);
- TP_COOR->TP_Y=(TP_YCoor_1>>1)+(TP_YCoor_2>>1);
- }
- /* 校準誤差 */
- #define CCMA 100
- /* 觸摸屏校準 */
- uint8_t TP_Calibration(void)
- {
- Touch_CoorDinate TP_COOR[4];
- int16_t arr[2][3];
- uint16_t CC,CC1,CC2;
- /* 校準第一個點 */
- Touch_Structure.Delay_ms(500);
- Touch_Structure.DispH(Calibration_x1,Calibration_y1);
- Touch_Structure.Clear_PendingBit();
- while(1)
- {
- if(Touch_Structure.Get_StatusFlag())
- {
- Touch_Structure.Clear_PendingBit();
- if(TP_GetCoorDinate(TP_COOR))
- {
- /* 顯示重新點擊 */
- }
- else
- break;
- }
- }
- /* 校準第二個點 */
- Touch_Structure.Delay_ms(500);
- Touch_Structure.DispH(Calibration_x2,Calibration_y2);
- Touch_Structure.Clear_PendingBit();
- while(1)
- {
- if(Touch_Structure.Get_StatusFlag())
- {
- Touch_Structure.Clear_PendingBit();
- if(TP_GetCoorDinate(TP_COOR+1))
- {
- /* 顯示重新點擊 */
- }
- else
- break;
- }
- }
- /* 校準第三個點 */
- Touch_Structure.Delay_ms(500);
- Touch_Structure.DispH(Calibration_x3,Calibration_y3);
- Touch_Structure.Clear_PendingBit();
- while(1)
- {
- if(Touch_Structure.Get_StatusFlag())
- {
- Touch_Structure.Clear_PendingBit();
- if(TP_GetCoorDinate(TP_COOR+2))
- {
- /* 顯示重新點擊 */
- }
- else
- break;
- }
- }
- /* 校準第四個點 */
- Touch_Structure.Delay_ms(500);
- Touch_Structure.DispH(Calibration_x4,Calibration_y4);
- Touch_Structure.Clear_PendingBit();
- while(1)
- {
- if(Touch_Structure.Get_StatusFlag())
- {
- Touch_Structure.Clear_PendingBit();
- if(TP_GetCoorDinate(TP_COOR+3))
- {
- /* 顯示重新點擊 */
- }
- else
- break;
- }
- }
- /* 檢查數據是否準確 */
- CC1=Get_ABS(TP_COOR[0].TP_X , TP_COOR[3].TP_X);
- CC2=Get_ABS(TP_COOR[2].TP_X , TP_COOR[1].TP_X);
- CC=Get_ABS(CC1,CC2);
- if(CC>CCMA)
- return 1;
- CC1=Get_ABS(TP_COOR[0].TP_Y , TP_COOR[1].TP_Y);
- CC2=Get_ABS(TP_COOR[2].TP_Y , TP_COOR[3].TP_Y);
- CC=Get_ABS(CC1,CC2);
- if(CC>CCMA)
- return 1;
- /* 解方程求 TP_Xk TP_Yk TP_Xoffset TP_Yoffset */
- /* 觸摸屏坐標*K+offset =液晶屏坐標 */
- arr[0][0]=TP_COOR[0].TP_X; arr[0][1]=1; arr[0][2]=Calibration_x1;
- arr[1][0]=TP_COOR[2].TP_X; arr[1][1]=1; arr[1][2]=Calibration_x3;
- if(Solve_Equations_2(arr , &Touch_Structure.Xk , &Touch_Structure.Xoffset))
- {
- /* 顯示方程無解 數據錯誤 */
- return 1;
- }
- arr[0][0]=TP_COOR[1].TP_Y; arr[0][1]=1; arr[0][2]=Calibration_y2;
- arr[1][0]=TP_COOR[3].TP_Y; arr[1][1]=1; arr[1][2]=Calibration_y4;
- if(Solve_Equations_2(arr , &Touch_Structure.Yk , &Touch_Structure.Yoffset))
- {
- /* 顯示方程無解 數據錯誤 */
- return 1;
- }
- return 0;
- }
- /* 得到液晶屏的坐標 返回值0 坐標靠譜 否則不靠譜 */
- uint8_t Touch_GetCoordinate(Touch_CoorDinate *TP_COOR)
- {
- if(TP_GetCoorDinate(TP_COOR))
- return 1;
- /* 數據一般不會得到極值 */
- /*
- if(TP_COOR->TP_X==0||TP_COOR->TP_X==4095 ||TP_COOR->TP_Y==0 ||TP_COOR->TP_Y==4095)
- return 1;
- */
- TP_COOR->TP_X=TP_COOR->TP_X*Touch_Structure.Xk+Touch_Structure.Xoffset;
- TP_COOR->TP_Y=TP_COOR->TP_Y*Touch_Structure.Yk+Touch_Structure.Yoffset;
- return 0;
- }
復制代碼
|