添加了触屏驱动,加入了触屏校准功能

This commit is contained in:
2021-08-07 17:05:35 +08:00
parent 11e983ef98
commit 4e864ed558
18 changed files with 12649 additions and 9122 deletions
+303
View File
@@ -0,0 +1,303 @@
/*
* 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;
}
}
}
+42
View File
@@ -0,0 +1,42 @@
/*
* touch.h
*
* Created on: 2021Äê8ÔÂ7ÈÕ
* Author: wuwenfeng
*/
#ifndef TOUCH_H_
#define TOUCH_H_
#include "main.h"
#define TCLK(x) HAL_GPIO_WritePin(TCLK_GPIO_Port,TCLK_Pin,x)
#define TCS(x) HAL_GPIO_WritePin(TCS_GPIO_Port,TCS_Pin,x)
#define TDIN(x) HAL_GPIO_WritePin(TDIN_GPIO_Port,TDIN_Pin,x)
#define TDOUT HAL_GPIO_ReadPin(TDOUT_GPIO_Port,TDOUT_Pin)
#define TPEN HAL_GPIO_ReadPin(TPEN_GPIO_Port,TPEN_Pin)
typedef struct
{
char begin;
float x_acc;
float y_acc;
int x_offset;
int y_offset;
char end;
}touch_config;
typedef struct
{
uint16_t adc_x;
uint16_t adc_y;
int pix_x;
int pix_y;
char move_flag;
}touch_device;
void TP_Server();
void TP_adjustment();
#endif /* TOUCH_H_ */