/* * touch.c * * Created on: 2021年8月7日 * Author: wuwenfeng */ #include "touch.h" #include "LCD.h" #include "eeprom.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(); //稍微延时,ad转换需要时间 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;ibuf[j])//升序排列 { temp=buf[i]; buf[i]=buf[j]; buf[j]=temp; } } } sum=0; for(i=LOST_VAL;ims100) { ms100=HAL_GetTick()+100; if(r>0){r--;} } } //步骤0,将点画在(30,30)此时半径为10 if(step==0) { TP_DrwaTrage(30,30,r); if(r==0)//当半径收缩为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); } } //步骤1,等待屏幕被松开,进入下一个步骤,重置半径 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; } } //当4个点读取完,开始计算关系 if(step==8) { //其实只需要两个点就能校准,通过取平均值获得xy的长边和短边 xd=((x1+x3)/2); xl=((x2+x4)/2); yd=((y1+y2)/2); yl=((y3+y4)/2); //长边减去短边可以再获得一个点 x5=xl-xd; y5=yl-yd; //这个点如果是负数,肯定有错,可能是xy搞反了 if(x5<0||y5<0) { //显示error sprintf(str,"ERROR"); LCD_ShowString(0,66+16+16+16+16,str,16,RED, GRAY); }else { //计算关系倍率 //ad的长边减去短边再除去实际屏幕像素的长边减短边(260=320-30-30,180=240-30-30) 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; //eeprom块标记 tconfig.begin=0xab; tconfig.end=0xcd; //显示计算结果 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); } //将结果保存起来 EEPROM_WRITE_BATY(16,(char *)&tconfig,sizeof(touch_config)); HAL_Delay(1000); return; } } }