/** * @brief: 触摸屏初始化 * @retval:0 - 没有进行校准 * 1 - 进行过校准 * @note: * - T_SCK -> PB1 * - T_CS -> PB2 * - T_MISO -> PF8 * - T_MOSI -> PF9 * - T_PEN -> PF10 */ u8 TP_Init(void) { RCC->APB2ENR|=1<<3; //PB时钟使能 RCC->APB2ENR|=1<<7; //PF时钟使能 GPIOB->CRL&=0XFFFFF00F; //PB1 PB2 GPIOB->CRL|=0X00000330; GPIOB->ODR|=3<<1; //PB1 PB2 推挽输出 GPIOF->CRH&=0XFFFFF000; GPIOF->CRH|=0X00000838; //PF8-上拉输入 PF9-推挽输出 PF10-上拉输入 GPIOF->ODR|=7<<8; //PF8 PF9 PF10 全部上拉 TP_Read_XY(&tp_dev.x,&tp_dev.y);//第一次读取初始化 IIC_Init(); //初始化IIC while(AT24CXX_Check()) //检测不到24c02 { LCD_ShowString(16,150,200,16,16,"24C02 Check Failed!"); delay_ms(500); LCD_ShowString(16,150,200,16,16,"Please Check! "); delay_ms(500); } if(TP_Get_Adjdata())return 0; //已经校准 else //未校准 { LCD_Clear(WHITE); //清屏 TP_Adjust(); //屏幕校准 TP_Save_Adjdata(); } TP_Get_Adjdata(); return 1; }
//触摸屏初始化 //返回值:0,没有进行校准 // 1,进行过校准 //触摸屏初始化 //返回值:0,没有进行校准 // 1,进行过校准 u8 TP_Init(void) { //注意,时钟使能之后,对GPIO的操作才有效 //所以上拉之前,必须使能时钟.才能实现真正的上拉输出 GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF, ENABLE); //使能PB,PF端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2; // PB1,PB2端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_1|GPIO_Pin_2);//上拉 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PF9端口配置 推挽输出 GPIO_Init(GPIOF, &GPIO_InitStructure); GPIO_SetBits(GPIOF,GPIO_Pin_9);//P9 上拉 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_10; // PF8.PF10端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入 GPIO_Init(GPIOF, &GPIO_InitStructure); TP_Read_XY(&tp_dev.x,&tp_dev.y);//第一次读取初始化 AT24CXX_Init();//初始化24CXX if(TP_Get_Adjdata())return 0;//已经校准 else //未校准? { LCD_Clear(WHITE);//清屏 TP_Adjust(); //屏幕校准 TP_Save_Adjdata(); } TP_Get_Adjdata(); return 1; }
/** * @brief: 触摸屏校准代码,得到四个校准参数 */ void TP_Adjust(void) { u16 pos_temp[4][2]; //坐标缓存值 u8 cnt=0; u16 d1,d2; u32 tem1,tem2; float fac; u16 outtime=0; cnt=0; POINT_COLOR=BLUE; BACK_COLOR =WHITE; LCD_Clear(WHITE); //清屏 POINT_COLOR=RED; //红色 LCD_Clear(WHITE); //清屏 POINT_COLOR=BLACK; LCD_ShowString(40,40,160,100,16,TP_REMIND_MSG_TBL);//显示提示信息 TP_Drow_Touch_Point(20,20,RED); //画点1 tp_dev.sta=0; //消除触发信号 tp_dev.xfac=0; //xfac用来标记是否校准过,所以校准之前必须清掉!以免错误 while(1) //如果连续10秒钟没有按下,则自动退出 { tp_dev.scan(1); //扫描物理坐标 if((tp_dev.sta&0xc0)==TP_CATH_PRES) //按键按下了一次(此时按键松开了) { outtime=0; tp_dev.sta&=~(1<<6); //标记按键已经被处理过了. pos_temp[cnt][0]=tp_dev.x; pos_temp[cnt][1]=tp_dev.y; cnt++; switch(cnt) { case 1: TP_Drow_Touch_Point(20,20,WHITE); //清除点1 TP_Drow_Touch_Point(lcddev.width-20,20,RED); //画点2 break; case 2: TP_Drow_Touch_Point(lcddev.width-20,20,WHITE);//清除点2 TP_Drow_Touch_Point(20,lcddev.height-20,RED); //画点3 break; case 3: TP_Drow_Touch_Point(20,lcddev.height-20,WHITE); //清除点3 TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,RED); //画点4 break; case 4: //全部四个点已经得到 tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2 tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2 tem1*=tem1; tem2*=tem2; d1=sqrt(tem1+tem2);//得到1,2的距离 tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4 tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4 tem1*=tem1; tem2*=tem2; d2=sqrt(tem1+tem2);//得到3,4的距离 fac=(float)d1/d2; if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格 { cnt=0; TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4 TP_Drow_Touch_Point(20,20,RED); //画点1 TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据 continue; } tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3 tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3 tem1*=tem1; tem2*=tem2; d1=sqrt(tem1+tem2);//得到1,3的距离 tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4 tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4 tem1*=tem1; tem2*=tem2; d2=sqrt(tem1+tem2);//得到2,4的距离 fac=(float)d1/d2; if(fac<0.95||fac>1.05)//不合格 { cnt=0; TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4 TP_Drow_Touch_Point(20,20,RED); //画点1 TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据 continue; }//正确了 //对角线相等 tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3 tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3 tem1*=tem1; tem2*=tem2; d1=sqrt(tem1+tem2);//得到1,4的距离 tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4 tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4 tem1*=tem1; tem2*=tem2; d2=sqrt(tem1+tem2);//得到2,3的距离 fac=(float)d1/d2; if(fac<0.95||fac>1.05)//不合格 { cnt=0; TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4 TP_Drow_Touch_Point(20,20,RED); //画点1 TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据 continue; }//正确了 //计算结果 tp_dev.xfac=(float)(lcddev.width-40)/(pos_temp[1][0]-pos_temp[0][0]); //得到xfac tp_dev.xoff=(lcddev.width-tp_dev.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2; //得到xoff tp_dev.yfac=(float)(lcddev.height-40)/(pos_temp[2][1]-pos_temp[0][1]); //得到yfac tp_dev.yoff=(lcddev.height-tp_dev.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff if(abs(tp_dev.xfac)>2||abs(tp_dev.yfac)>2)//触屏和预设的相反了. { cnt=0; TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4 TP_Drow_Touch_Point(20,20,RED); //画点1 LCD_ShowString(40,26,lcddev.width,lcddev.height,16,"TP Need readjust!"); tp_dev.touchtype=!tp_dev.touchtype;//修改触屏类型. if(tp_dev.touchtype)//X,Y方向与屏幕相反 { CMD_RDX=0X90; CMD_RDY=0XD0; } else //X,Y方向与屏幕相同 { CMD_RDX=0XD0; CMD_RDY=0X90; } continue; } POINT_COLOR=BLUE; LCD_Clear(WHITE);//清屏 LCD_ShowString(35,110,lcddev.width,lcddev.height,16,"Touch Screen Adjust OK!");//校正完成 delay_ms(1000); TP_Save_Adjdata(); LCD_Clear(WHITE);//清屏 return;//校正完成 } } delay_ms(10); outtime++; if(outtime>1000) { TP_Get_Adjdata(); break; } } }