304 lines
5.3 KiB
C
304 lines
5.3 KiB
C
/*
|
||
* touch.c
|
||
*
|
||
* Created on: 2021年8月7日
|
||
* Author: wuwenfeng
|
||
*/
|
||
|
||
#include "touch.h"
|
||
#include "LCD.h"
|
||
//默认为touchtype=0的数据.
|
||
#define CMD_RDX 0X90
|
||
#define CMD_RDY 0XD0
|
||
|
||
|
||
//SPI写数据
|
||
//向触摸屏IC写入1byte数据
|
||
//num:要写入的数据
|
||
void TP_Write_Byte(char num)
|
||
{
|
||
for(uint8_t count=0;count<8;count++)
|
||
{
|
||
if(num&0x80){TDIN(1);}
|
||
else {TDIN(0);}
|
||
num<<=1;
|
||
TCLK(0);
|
||
TCLK(1); //上升沿有效
|
||
}
|
||
}
|
||
|
||
//SPI读数据
|
||
//从触摸屏IC读取adc值
|
||
//CMD:指令
|
||
//返回值:读到的数据
|
||
uint16_t TP_Read_AD(char CMD)
|
||
{
|
||
uint16_t Num=0;
|
||
TCLK(0); //先拉低时钟
|
||
TDIN(0); //拉低数据线
|
||
TCS(0); //选中触摸屏IC
|
||
TP_Write_Byte(CMD);//发送命令字
|
||
HAL_GetTick();
|
||
HAL_GetTick();
|
||
HAL_GetTick();
|
||
HAL_GetTick();
|
||
HAL_GetTick();
|
||
HAL_GetTick();
|
||
TCLK(1); //给1个时钟,清除BUSY
|
||
TCLK(0);
|
||
for(uint8_t count=0;count<16;count++)//读出16位数据,只有高12位有效
|
||
{
|
||
Num<<=1;
|
||
TCLK(0); //下降沿有效
|
||
TCLK(1);;
|
||
if(TDOUT){Num++;}
|
||
}
|
||
Num>>=4; //只有高12位有效.
|
||
TCS(1); //释放片选
|
||
return(Num);
|
||
}
|
||
|
||
//读取一个坐标值(x或者y)
|
||
//连续读取READ_TIMES次数据,对这些数据升序排列,
|
||
//然后去掉最低和最高LOST_VAL个数,取平均值
|
||
//xy:指令(CMD_RDX/CMD_RDY)
|
||
//返回值:读到的数据
|
||
#define READ_TIMES 5 //读取次数
|
||
#define LOST_VAL 1 //丢弃值
|
||
uint16_t TP_Read_XOY(uint8_t xy)
|
||
{
|
||
uint16_t i, j;
|
||
uint16_t buf[READ_TIMES];
|
||
uint16_t sum=0;
|
||
uint16_t temp;
|
||
for(i=0;i<READ_TIMES;i++)buf[i]=TP_Read_AD(xy);
|
||
for(i=0;i<READ_TIMES-1; i++)//排序
|
||
{
|
||
for(j=i+1;j<READ_TIMES;j++)
|
||
{
|
||
if(buf[i]>buf[j])//升序排列
|
||
{
|
||
temp=buf[i];
|
||
buf[i]=buf[j];
|
||
buf[j]=temp;
|
||
}
|
||
}
|
||
}
|
||
sum=0;
|
||
for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++)sum+=buf[i];
|
||
temp=sum/(READ_TIMES-2*LOST_VAL);
|
||
return temp;
|
||
}
|
||
|
||
//读取x,y坐标
|
||
//x,y:读取到的坐标ADC值
|
||
void TP_Read_XY_ADC(int16_t *x,int16_t *y)
|
||
{
|
||
int16_t xtemp,ytemp;
|
||
xtemp=TP_Read_XOY(CMD_RDX);
|
||
ytemp=TP_Read_XOY(CMD_RDY);
|
||
*x=xtemp;
|
||
*y=ytemp;
|
||
}
|
||
//连续2次读取触摸屏IC,且这两次的偏差不能超过
|
||
//ERR_RANGE,满足条件,则认为读数正确,否则读数错误.
|
||
//该函数能大大提高准确度
|
||
//x,y:读取到的坐标值
|
||
//返回值:0,失败;1,成功。
|
||
#define ERR_RANGE 10 //误差范围
|
||
uint8_t TP_Read_XY2(int16_t *x,int16_t *y)
|
||
{
|
||
int16_t x1,y1;
|
||
int16_t x2,y2;
|
||
|
||
TP_Read_XY_ADC(&x1,&y1);
|
||
|
||
TP_Read_XY_ADC(&x2,&y2);
|
||
|
||
if(((x2<=x1&&x1<x2+ERR_RANGE)||(x1<=x2&&x2<x1+ERR_RANGE))//前后两次采样在+-50内
|
||
&&((y2<=y1&&y1<y2+ERR_RANGE)||(y1<=y2&&y2<y1+ERR_RANGE)))
|
||
{
|
||
*x=(x1+x2)/2;
|
||
*y=(y1+y2)/2;
|
||
return 1;
|
||
}else return 0;
|
||
}
|
||
touch_device t0;// t0 yyds~
|
||
touch_config tconfig;
|
||
//触摸更新服务
|
||
void TP_Server()
|
||
{
|
||
if(TPEN==0)
|
||
{
|
||
TP_Read_XY2(&t0.adc_x,&t0.adc_y);
|
||
t0.pix_x=(t0.adc_x/tconfig.x_acc)-tconfig.x_offset;
|
||
t0.pix_y=(t0.adc_y/tconfig.y_acc)-tconfig.y_offset;
|
||
|
||
}
|
||
}
|
||
|
||
void TP_DrwaTrage(int x,int y,int r)
|
||
{
|
||
Draw_Circle(x,y,r+1,GRAY);
|
||
Draw_Circle(x,y,r,RED);
|
||
LCD_DrawLine(x,y,x+10,y,RED);
|
||
LCD_DrawLine(x,y,x,y+10,RED);
|
||
LCD_DrawLine(x,y,x-10,y,RED);
|
||
LCD_DrawLine(x,y,x,y-10,RED);
|
||
}
|
||
|
||
void TP_adjustment()
|
||
{
|
||
char str[64];
|
||
uint16_t y_adc,x_adc,step=0,r=10;
|
||
uint16_t y1,y2,y3,y4,x1,x2,x3,x4;
|
||
int y5,x5,xd,xl,yd,yl;
|
||
float acc_x,acc_y;
|
||
int offset_x,offset_y;
|
||
uint32_t wait=HAL_GetTick()+50000,ms100=0;
|
||
LCD_Clear(GRAY);
|
||
LCD_ShowString(0,50,"Calibrate the touch screen",16,RED,RED);
|
||
//TP_DrwaTrage(30,30,10);
|
||
while(HAL_GetTick()<wait)
|
||
{
|
||
if(TPEN==0)
|
||
{
|
||
wait=HAL_GetTick()+50000;
|
||
|
||
TP_Read_XY2(&x_adc,&y_adc);
|
||
sprintf(str,"ADC_X:%04d",x_adc);
|
||
LCD_ShowString(100, 0, str, 16, RED, GRAY);
|
||
sprintf(str,"ADC_Y:%04d",y_adc);
|
||
LCD_ShowString(100, 16, str, 16, RED, GRAY);
|
||
|
||
if(HAL_GetTick()>ms100)
|
||
{
|
||
ms100=HAL_GetTick()+100;
|
||
if(r>0){r--;}
|
||
}
|
||
}
|
||
|
||
if(step==0)
|
||
{
|
||
TP_DrwaTrage(30,30,r);
|
||
if(r==0)
|
||
{
|
||
step+=1;
|
||
y1=y_adc;
|
||
x1=x_adc;
|
||
sprintf(str,"point_1 x:%d y:%d",x1,y1);
|
||
LCD_ShowString(0,66,str,16,RED,RED);
|
||
}
|
||
}
|
||
if(step==1)
|
||
{
|
||
if(TPEN==1)
|
||
{
|
||
step+=1;
|
||
r=10;
|
||
}
|
||
|
||
}
|
||
if(step==2)
|
||
{
|
||
TP_DrwaTrage(290,30,r);
|
||
if(r==0)
|
||
{
|
||
step+=1;
|
||
y2=y_adc;
|
||
x2=x_adc;
|
||
sprintf(str,"point_2 x:%d y:%d",x2,y2);
|
||
LCD_ShowString(0,66+16,str,16,RED,RED);
|
||
}
|
||
}
|
||
if(step==3)
|
||
{
|
||
if(TPEN==1)
|
||
{
|
||
step+=1;
|
||
r=10;
|
||
}
|
||
|
||
}
|
||
if(step==4)
|
||
{
|
||
TP_DrwaTrage(30,210,r);
|
||
if(r==0)
|
||
{
|
||
step+=1;
|
||
y3=y_adc;
|
||
x3=x_adc;
|
||
sprintf(str,"point_3 x:%d y:%d",x3,y3);
|
||
LCD_ShowString(0,66+16+16,str,16,RED,RED);
|
||
}
|
||
}
|
||
if(step==5)
|
||
{
|
||
if(TPEN==1)
|
||
{
|
||
step+=1;
|
||
r=10;
|
||
}
|
||
|
||
}
|
||
if(step==6)
|
||
{
|
||
TP_DrwaTrage(290,210,r);
|
||
if(r==0)
|
||
{
|
||
step+=1;
|
||
y4=y_adc;
|
||
x4=x_adc;
|
||
sprintf(str,"point_4 x:%d y:%d",x4,y4);
|
||
LCD_ShowString(0,66+16+16+16,str,16,RED,RED);
|
||
}
|
||
}
|
||
if(step==7)
|
||
{
|
||
if(TPEN==1)
|
||
{
|
||
step+=1;
|
||
r=10;
|
||
}
|
||
}
|
||
if(step==8)
|
||
{
|
||
xd=((x1+x3)/2);
|
||
xl=((x2+x4)/2);
|
||
yd=((y1+y2)/2);
|
||
yl=((y3+y4)/2);
|
||
x5=xl-xd;
|
||
y5=yl-yd;
|
||
if(x5<0||y5<0)
|
||
{
|
||
sprintf(str,"ERROR");
|
||
LCD_ShowString(0,66+16+16+16+16,str,16,RED, GRAY);
|
||
}else
|
||
{
|
||
acc_x=x5/260.0;
|
||
acc_y=y5/180.0;
|
||
|
||
offset_x=(((xd/acc_x)-30)+((xl/acc_x)-290))/2;
|
||
offset_y=(((yd/acc_y)-30)+((yl/acc_y)-210))/2;
|
||
|
||
tconfig.x_acc=acc_x;
|
||
tconfig.x_offset=offset_x;
|
||
tconfig.y_acc=acc_y;
|
||
tconfig.y_offset=offset_y;
|
||
|
||
sprintf(str,"x_acc=%f y_acc=%f",acc_x,acc_y);
|
||
LCD_ShowString(0,66+16+16+16+16,str,16,RED,RED);
|
||
sprintf(str,"x_offset=%d y_offset=%d",offset_x,offset_y);
|
||
LCD_ShowString(0,66+16+16+16+16+16,str,16,RED,RED);
|
||
|
||
}
|
||
|
||
HAL_Delay(1000);
|
||
return;
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|