#include"stm32f10x.h"
#include"ili9320.h"
#include"touch.h"
#include "stdlib.h"
#include "math.h"
#include"usart.h"
#define TDIN_SET GPIO_SetBits(GPIOA,GPIO_Pin_7);
#define TDIN_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_7);
#define TOUT_SET GPIO_SetBits(GPIOA,GPIO_Pin_6);
#define TOUT_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_6);
#define TCLK_SET GPIO_SetBits(GPIOA,GPIO_Pin_5);
#define TCLK_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_5);
#define TCS_SET GPIO_SetBits(GPIOA,GPIO_Pin_8);
#define TCS_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_8);
#define CMD_RDX 0XD0
#define CMD_RDY 0X90
extern Pen_Holder Pen_Point;
unsigned int POINT_COLOR = 0x0000,BACK_COLOR = 0xFFFF;
/************************************************************************************
GPIO口的配置
*************************************************************************************/
void TOUCH_GPIO_Config()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB , ENABLE);
/* 配置管脚: SCK--PA5, and DINT--PA7 2046 CS ---------PA8 ----------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIOA->ODR|=(1<<5)|(1<<7)|(1<<8);
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIOA->ODR|=(1<<5)|(1<<7)|(1<<8);
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 2046 INT_busy --PB10 DOUT--PB6-----PB9----按键*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIOA->ODR|=1<<6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//调用函数使能外设的时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //定义模式;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
extern void EXIT_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure; //申明结构体
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
EXTI_ClearITPendingBit(EXTI_Line1);
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_Line=EXTI_Line1;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
extern void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3); //选择第二组
NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn; //选择中断通道3
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占式中断优先级设置为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应式中断优先级设置为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断 //使能中断
NVIC_Init(&NVIC_InitStructure);
}
extern void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_IMR_MR1) != RESET)
{
  en_Point.Key_Sta=Key_Down;//按键按下
/* Clear the Key Button EXTI line pending bit */
EXTI_ClearITPendingBit(EXTI_IMR_MR1);
}
}
extern void Pen_Int_Set(u8 en)
{
if(en)EXTI->IMR|=1<<1; //开启line9上的中断
else EXTI->IMR&=~(1<<1); //关闭line9上的中断
}
extern u8 Read_TP_Once()
{
u8 t=0;
  en_Int_Set(0);//关闭中断
  en_Point.Key_Sta=Key_Up;
Read_ADS7843TWO(& en_Point.X,& en_Point.Y);
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0&&t<=250)
{
t++;
delayms(10);
};
  en_Int_Set(1);//开启中断
if(t>=250)return 0;//按下2.5s 认为无效
return 1;
}
extern void ADS7843SPI_start()
{
TCLK_CLR;
TCS_SET;
TDIN_SET;
TCLK_SET;
TCS_CLR;
}
/*---------------------------------------------------------------------------------
SPI软件模拟写一个字节
输入:data
无返回值
-----------------------------------------------------------------------------------*/
void ADS7843_Write_Byte(uchar data)
{
uchar count=0;
TCLK_CLR;
TCS_CLR;
for(count=0;count<8;count++)
{
if(data&0x80==1)
TDIN_SET;
if(data&0x80==0)
TDIN_CLR;
data=data<<1;
TCLK_CLR;
TCLK_SET; //上升沿ADS7846读总线的数据
}
}
/*---------------------------------------------------------------------------------
SPI先发送命令字,
然后再读出AD转换的结果
输入:命令控制字
return:转换的结果
-----------------------------------------------------------------------------------*/
unsigned int ADS7843_ReadAD(unsigned char cmd)
{
unsigned char count=0;
unsigned int number=0;
// ADS7843SPI_start();
TCLK_CLR; //先拉低时钟
TDIN_CLR; //拉低数据线
TCS_CLR; //选中触摸屏IC
ADS7843_Write_Byte(cmd);//发送控制命令字
TCLK_CLR;
delay_us(6);
TCLK_SET;
TCLK_CLR;
for(count=0;count<16;count++)
{
number<<=1;
TCLK_CLR;
delay_us(1);
TCLK_SET; //下降沿有效
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6))number++;
} //读出number
number>>=4; //取高12位
TCS_SET; //释放ADS7843
return number;
}
#define READ_TIMES 15//读取次数
#define LOST_VAL 5//丢弃的次数
/*---------------------------------------------------------------------------------
输入:cmd
输出:读15次舍弃10次的平均值
------------------------------------------------------------------------------------*/
unsigned int ADS7843_ReadAvgAD(unsigned char cmd)
{
unsigned int i,j;
unsigned int AD_buffer[READ_TIMES];
unsigned int t,sum,AVG;
for(i=0;i<READ_TIMES;i++)
{
AD_buffer=ADS7843_ReadAD(cmd);
}
for(j=0;j<READ_TIMES;j++)
{
for(i=0;i<READ_TIMES-j;i++)
{
if(AD_buffer>AD_buffer[i+1])
{
t=AD_buffer;
AD_buffer=AD_buffer[i+1];
AD_buffer[i+1]=t;
}
}
}
sum=0;
for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++) //剩余的数据相加
{
sum+=AD_buffer;
}
AVG=sum/(READ_TIMES-2*LOST_VAL); //求取平均值
return AVG;
}
/*-----------------------------------------------------------------------------------
分别测出一个触摸点的x,y
并存入指针
return:读取标志位,是否读取正确
--------------------------------------------------------------------------------------*/
unsigned char Read_ADS7843(unsigned int *x,unsigned int *y)
{
int xtemp,ytemp;
xtemp=ADS7843_ReadAvgAD(CMD_RDX);
ytemp=ADS7843_ReadAvgAD(CMD_RDY);
if(xtemp<100||ytemp<100||xtemp>3800||ytemp>3800) return 0; //读取失败,触摸屏比TFT屏要大,一般小于100的
//是在TFT屏外,这样就没有意义
*x=xtemp;
*y=ytemp;
printf("\n\r X=%d,Y=%d\n\r",xtemp,ytemp);
return 1; //读取成功
}
/*---------------------------------------------------------------------------------
取两次坐标看两次的误差是否在(—+50)一定范围之内
return:标志位
------------------------------------------------------------------------------------*/
#define ERR_RANGE 50
unsigned char Read_ADS7843TWO(unsigned int *x,unsigned int *y)
{
unsigned int x1,y1;
unsigned int x2,y2;
unsigned char flag;
flag=Read_ADS7843(&x1,&y1);
if(flag==0) return 0;
flag=Read_ADS7843(&x2,&y2);
if(flag==0) return 0;
if(((x2<=x1&&x1<x2+ERR_RANGE)||(x1<=x2&&x2<x1+ERR_RANGE)) //前后两次采样xy的误差范围
&&((y2<=y1&&y1<y2+ERR_RANGE)||(y1<=y2&&y2<y1+ERR_RANGE)))
{
*x=(x1+x2)/2; //把两次采集到的数据求平均值存到*x,*y中
*y=(y1+y2)/2;
return 1;
}
else
{
return 0;
}
}
/*----------------------------------------------------------------------------------
因为触摸屏的坐标和TFT坐标是不一样的
所以先要确定一个关系
触摸屏的检验程序
确定四个点的坐标
-------------------------------------------------------------------------------------*/
void Touch_Adjust(void)
{
uint16_t pos_temp[4][2];//坐标缓存值
u8 cnt=0;
u16 d1,d2;
float fac=0;
u32 tem1,tem2;
cnt=0;
  OINT_COLOR=Blue;
BACK_COLOR =White;
CLR_Screen(White);//清屏
  OINT_COLOR=Red;//红色
CLR_Screen(White);//清屏
Drow_Touch_Point(40,40);//画点1
  en_Point.Key_Sta=Key_Up;//消除触发信号
while(1)
{
if(Pen_Point.Key_Sta==Key_Down)//按键按下了
{
if(Read_TP_Once())//得到单次按键值
{
pos_temp[cnt][0]=Pen_Point.X;
pos_temp[cnt][1]=Pen_Point.Y;
cnt++;
}
LCDShow_uCharNumber(100,100,pos_temp[0][0],Black,White);
// LCD_DispNum(pos_temp[0][0],80,80,0,Black,White);
// LCD_DispNum(pos_temp[0][1],60,60,0,Black,White);
delayms(1500);
// return;//校正完成
switch(cnt)
{
case 1:
CLR_Screen(White);//清屏
Drow_Touch_Point(160,40);//画点2
break;
case 2:
CLR_Screen(White);//清屏
Drow_Touch_Point(40,280);//画点3
break;
case 3:
CLR_Screen(White);//清屏
Drow_Touch_Point(160,280);//画点4
break;
case 4:
// LCD_DispNum(pos_temp[0][0],80,80,0,Black,White);
// LCD_DispNum(pos_temp[0][1],70,70,0,Black,White);
delayms(1500);
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;
CLR_Screen(White);//清屏
Drow_Touch_Point(40,40);
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;
CLR_Screen(White);//清屏
Drow_Touch_Point(40,40);
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;
CLR_Screen(White);//清屏
Drow_Touch_Point(40,40);
continue;
}//正确了
//计算结果
  en_Point.xfac=(float)160/(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)240/(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;
CLR_Screen(White);//清屏
LCD_PutString(35,110,"Touch Screen Adjust OK!",Black,White);//校正完成
delayms(1000);
CLR_Screen(White);//清屏
return;//校正完成
//退出校验循环程序
}
}
}
}
/**********************************************************************************
这是一个画笔函数
***********************************************************************************/
extern void Drow_Touch_Point(unsigned int x,unsigned int y)
{
Line(x-12,y,x+13,y,Black);//横线
Line(x,y-12,x,y+13,Black);//竖线
Put_pixel(x+1,y+1,Black);
Put_pixel(x-1,y+1,Black);
Put_pixel(x+1,y-1,Black);
Put_pixel(x-1,y-1,Black);
LCD_DispCircle(x,y,6,Black);//画中心圈
Write_Cmd_Data(0x0000,0x0022);
}
/**********************************************************************************
这是一个画笔函数一个大点
***********************************************************************************/
void Drow_Big_Point(unsigned int x,unsigned int y)
{
Put_pixel(x,y,Black);//中心点
Put_pixel(x+1,y,Black);
Put_pixel(x,y+1,Black);
Put_pixel(x+1,y+1,Black);
}
unsigned int key_scan(void)
{
u8 Read_A12;
Read_A12=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11);
if(Read_A12==0)
{
delayms(10);
led(on);
return 1;
}
return 0;
}
extern u8 key_scan1()
{
u8 Read_A11;
Read_A11=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12);
if(Read_A11==0)
{
delayms(10);
return 1;
}
return 0;
}
|