⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 touch.c

📁 基于stm32的MP3播放器
💻 C
📖 第 1 页 / 共 2 页
字号:
				else if(Is_In_Area(214,224,238,248))return 7;//增加	    
				else if(Is_In_Area(214,252,238,276))return 8; //减少
					
				else if(Is_In_Area(28,288,52,312))return 9;	  //后一取
				else if(Is_In_Area(108,288,132,312))return 10;//播放
				else if(Is_In_Area(188,288,212,312))return 11;//上一曲

				else if(Is_In_Area(30,83,210,98))return 12;	  //进度条按下,y方向扩大了一点范围
															   
				//else if(Is_In_Area(0,300,40,319))return 13;//选择按钮被按下
				//else if(Is_In_Area(200,300,239,319))return 14;//返回按钮被按下
				return 0;//按键无效
			}
		case 4://4,功能选择模式下
			xtemp=Touch_Key_Pro(1);//不支持扩展	  
			if(xtemp&CLICK_POINT)  //点触摸	 得到1~8的值
			{
				for(t=0;t<8;t++)
				{	  
					if(Is_In_Area(0,42+t*32,239,42+(t+1)*32))return t+1;
				}
				if(Is_In_Area(0,300,40,319))return 9;//选择按钮被按下
				if(Is_In_Area(200,300,239,319))return 10;//返回按钮被按下
				return 0;//按键无效
			}										    
			break;
		case 5://5,收音机模式下
			xtemp=Touch_Key_Pro(1);//不支持扩展	
			if(xtemp&CLICK_POINT)  //点触摸	 得到1~8的值
			{
				if(Is_In_Area(37,215,61,239))return 1;//循环模式更改	    
				else if(Is_In_Area(93,215,117,239))return 2;//循环模式更改
				else if(Is_In_Area(152,218,203,236))return 3;   //音效存/取		 
					
				else if(Is_In_Area(28,261,52,285))return 4;	 //后一取
				else if(Is_In_Area(108,261,132,285))return 5;//播放
				else if(Is_In_Area(188,261,212,285))return 6;//上一曲
																		   
				else if(Is_In_Area(0,300,40,319))return 7;//选项按钮被按下
				else if(Is_In_Area(200,300,239,319))return 8;//返回按钮被按下
				return 0;//按键无效
			}  
			break; 
		case 6://6,闹钟中断程序按键
			xtemp=Touch_Key_Pro(1);//不支持扩展	
			if(xtemp&CLICK_POINT)  //点触摸	 得到1~8的值
			{
				if(Is_In_Area(111,151,153,169))return 1;//循环模式更改	       
				return 0;//按键无效
			}  
			break; 	  	    		 
	}
	return 0;
}
//得到键盘返回值
//返回:0~11
//返回11:按键无效
//返回10:退格按键
u8 Get_KeyBoard_Val(void)
{
	u8 t;
	for(t=0;t<10;t++) //加载外框
	{				 
		if(Is_In_Area(14+18*t,269,30+18*t,285))return t;//16*16方框  
	}  
	if(Is_In_Area(194,269,226,285))return 10;//32*16方框 
	return 11;
}
//保存校准参数
//保存区域:FM24C16的 40~52这段地址区间,总共12个字节
void save_adjdata(void)
{
	u32 temp;			 
	//保存校正结果!	    
	temp=Pen_Point.xfac*100000000;//保存x校正因素   
	FM24C16_WriteOneByte(40,temp&0xff);
	FM24C16_WriteOneByte(41,(temp>>8)&0xff);
	FM24C16_WriteOneByte(42,(temp>>16)&0xff);	
	FM24C16_WriteOneByte(43,(temp>>24)&0xff);

	temp=Pen_Point.yfac*100000000;//保存y校正因素  
	FM24C16_WriteOneByte(44,temp&0xff);
	FM24C16_WriteOneByte(45,(temp>>8)&0xff);
	FM24C16_WriteOneByte(46,(temp>>16)&0xff);	
	FM24C16_WriteOneByte(47,(temp>>24)&0xff);  
	//保存x偏移量
	FM24C16_WriteOneByte(48,Pen_Point.xoff&0xff);
	FM24C16_WriteOneByte(49,(Pen_Point.xoff>>8)&0xff);
	//保存y偏移量
	FM24C16_WriteOneByte(50,Pen_Point.yoff&0xff);
	FM24C16_WriteOneByte(51,(Pen_Point.yoff>>8)&0xff);	    							 
	temp=FM24C16_ReadOneByte(52);
	temp|=0x01;//标记校准过了
	FM24C16_WriteOneByte(52,temp);			 
}
//得到保存在EEPROM里面的校准值
//返回值:1,成功获取数据
//        0,获取失败,要重新校准
u8 get_adjdata(void)
{					  
	u32 tempfac;
	tempfac=FM24C16_ReadOneByte(52); 		 
	if(tempfac&0x01)//触摸屏已经校准过了			   
	{    
		tempfac=FM24C16_ReadOneByte(43);    
	    tempfac=(tempfac<<8)+FM24C16_ReadOneByte(42);	  
	    tempfac=(tempfac<<8)+FM24C16_ReadOneByte(41);
	    tempfac=(tempfac<<8)+FM24C16_ReadOneByte(40); 		   
		Pen_Point.xfac=(float)tempfac/100000000;//得到x校准参数

		tempfac=FM24C16_ReadOneByte(47);    
	    tempfac=(tempfac<<8)+FM24C16_ReadOneByte(46);	  
	    tempfac=(tempfac<<8)+FM24C16_ReadOneByte(45);
	    tempfac=(tempfac<<8)+FM24C16_ReadOneByte(44);        
		Pen_Point.yfac=(float)tempfac/100000000;//得到y校准参数
	    //得到x偏移量
		tempfac=FM24C16_ReadOneByte(49); 
	    tempfac=(tempfac<<8)+FM24C16_ReadOneByte(48); 	  
		Pen_Point.xoff=tempfac;					 
	    //得到y偏移量
		tempfac=FM24C16_ReadOneByte(51); 
	    tempfac=(tempfac<<8)+FM24C16_ReadOneByte(50); 	  
		Pen_Point.yoff=tempfac;				   
		return 1;	 
	}
	return 0;
}
//触摸屏校准代码
//得到四个校准参数
void touch_adjust(void)
{								 
	u16 pos_temp[4][2];//坐标缓存值
	u8  cnt=0;	
	u16 d1,d2;
	u32 tem1,tem2;
	float fac; 
	 
	cnt=0;				
	POINT_COLOR=BLUE;
	BACK_COLOR =WHITE;
	TFT_CLEAR(WHITE);//清屏 
	TFT_ShowString(24,110,"Touch Screen Adjusting..."); 
	delay_ms(1000);	    
	POINT_COLOR=RED;//红色 
	TFT_CLEAR(WHITE);//清屏 
	drow_touch_point(20,20);//画点1 
	Pen_Point.Key_Sta=Key_Up;//消除触发信号 
	Pen_Point.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误	 
	while(1)
	{
		if(Pen_Point.Key_Sta==Key_Down)//按键按下了
		{
			if(Touch_Key_Pro(0)&CLICK_POINT)//得到单次按键值
			{  								   
				pos_temp[cnt][0]=Pen_Point.X;
				pos_temp[cnt][1]=Pen_Point.Y;
				cnt++;
			}			 
			switch(cnt)
			{			   
				case 1:
					TFT_CLEAR(WHITE);//清屏 
					drow_touch_point(220,20);//画点2
					break;
				case 2:
					TFT_CLEAR(WHITE);//清屏 
					drow_touch_point(20,300);//画点3
					break;
				case 3:
					TFT_CLEAR(WHITE);//清屏 
					drow_touch_point(220,300);//画点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)//不合格
					{
						cnt=0;
						TFT_CLEAR(WHITE);//清屏 
						drow_touch_point(20,20);
						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;
						TFT_CLEAR(WHITE);//清屏 
						drow_touch_point(20,20);
						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;
						TFT_CLEAR(WHITE);//清屏 
						drow_touch_point(20,20);
						continue;
					}//正确了
					//计算结果
					Pen_Point.xfac=(float)200/(pos_temp[1][0]-pos_temp[0][0]);//得到xfac		 
					Pen_Point.xoff=(240-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff
						  
					Pen_Point.yfac=(float)280/(pos_temp[2][1]-pos_temp[0][1]);//得到yfac
					Pen_Point.yoff=(320-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff  
					POINT_COLOR=BLUE;
					TFT_CLEAR(WHITE);//清屏
					TFT_ShowString(35,110,"Touch Screen Adjust OK!");//校正完成
					delay_ms(1800);
					TFT_CLEAR(WHITE);//清屏   
					save_adjdata();
					return;//校正完成				 
			}
		}
	} 
}			    
//中断优先级管理/开启	   
void NVIC_TOUCHConfiguration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	//存储器映射,不用理    
#ifdef  VECT_TAB_RAM  									   
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 
#else   							 
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif  
	//第0组,没有抢断优先级
	//第4组,没有响应优先级				  
	//第2组,有4个抢断,4个响应
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//优先级分到第2组 总共5组		 
  	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel; //使用外部中断0
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//阶级2,可以被1抢断.
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		 //阶层0
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure); 
	//RTC中断配置
	NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//阶层1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		 //阶层0,响应优先级较低
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);	  									 
}	    
//外部中断初始化函数
void touch_init(void)
{				   
	//注意,时钟使能之后,对GPIO的操作才有效
	//所以上拉之前,必须使能时钟.才能实现真正的上拉输出
	RCC->APB2ENR|=1<<2;    //PA时钟使能
	RCC->APB2ENR|=1<<3;    //PB时钟使能

	RCC->APB2ENR|=1<<0;    //开启辅助时钟
	AFIO->MAPR=0X04000000;//关闭JTAG 

	GPIOA->CRL&=0XFFFFF000;//PA.2输出    PA.0/1输入
	GPIOA->CRL|=0X00000388;//3推挽输出   0/1上拉输入
	GPIOA->ODR|=0X0007;    //012 全部上拉

	GPIOB->CRL&=0XFFF00FFF;
  	GPIOB->CRL|=0X00033000;//PB.3/4输出
	GPIOB->ODR|=1<<4;      //PB.4上拉   
	GPIOB->ODR|=1<<3; 	   //PB.3上拉

 	Read_Ads7846();        //第一次读取初始化	  
	NVIC_TOUCHConfiguration();  
	RCC->APB2ENR|=0x01;    //使能io复用时钟
    AFIO->EXTICR[0]|=0X00; //EXTI8映射到PA.0   
	EXTI->IMR|=1<<0;       //开启line0上的中断
	EXTI->EMR|=1<<0;       //不屏蔽line0上的事件
	EXTI->FTSR|=1<<0;      //line0上事件下降沿触发 

	if(get_adjdata())return;//已经校准
	else			   //未校准?
	{ 										    
		TFT_CLEAR(WHITE);//清屏
	    touch_adjust();  //屏幕校准,带自动保存	  
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -