原子哥:
最近一直在调试触摸屏,遇到好多问题,用你的程序移植到我的屏上没有问题,我自己写了一个,用的SPI(原子哥的触摸是模拟的),
主要的问题就是触摸PEN脚,一直检测不到低电平,不知道为什么?经过多次尝试,发现只要把 Read_XPT2046();
屏蔽掉,是可以检测到PEN脚的,我为这个问题搞了一个星期了,一直无果,希望原子哥抽点时间帮我看看吧~~~~~
#define TP_CS PEout(0)
#define PEN PEin(1)
int main(void)
{
unsigned short a;
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口1初始化
LCD_Init(); //初始化液晶
TP_Init(); //SPI 触摸电路初始化
LED_Init(); //LED初始化
LCD_Clear(WHITE);
LCD_ShowString(20,60,"Touch the first point");
for(a=0; a<10; a++){ //在竖屏模式下,左上角显示第一个校正点点击区域
drawbigpoint(0,0+a);
drawbigpoint(a,0);
}
while (1) //等待点击第一个触摸校正点
{
if(PEN==0){ //点击第一个校正点 等待触摸检测电平变低 (此处一直进不去)
delay_ms(340); //延时340ms 消除抖动
if(PEN==0){ //检测触摸中断线是否可靠点击
while(PEN==0){ //点击未松开,持续读取触摸坐标
delay_ms(100);
Read_XPT2046(); //读取触摸坐标 (屏蔽掉这个函数就可以检测到PEN的低电平)
Xs=X; Ys=Y; //获得第一个校正点的X,Y
Delay_ms(340); //延时340ms 消除抖动
}
break;
}
}
}
LCD_ShowNum(90,2,Ye,4,16); //显示触摸屏的X值
LCD_ShowNum(90,17,Xe,4,16); //显示触摸屏的Y值
LCD_ShowString(20,120,"Touch the SECOND point");
for(a=0; a<20; a++){ //在竖屏模式下,左上角显示第二个校正点点击区域
drawbigpoint(120,190+a);
drawbigpoint(110+a,200);
}
while (1) //等待点击第二个触摸校正点
{
if(PEN==0){ //点击第二个校正点 等待触摸检测电平变低
delay_ms(340); //延时340ms 消除抖动
if(PEN==0){ //检测触摸中断线是否可靠点击
while(PEN==0){ //点击未松开,持续读取触摸坐标
delay_ms(100);
Read_XPT2046(); //读取触摸坐标
Xe=X; Ye=Y; //获得第二个校正点的X,Y
delay_ms(500); //延时340ms 消除抖动
}
break;
}
}
}
LCD_ShowNum(130,2,Ye,4,16); //显示触摸屏的X值
LCD_ShowNum(130,17,Xe,4,16); //显示触摸屏的Y值
/* 根据第一个校正点和第二个校正点的数据计算出屏幕上一个像素对应的触摸X,Y变化值,为保持精度,此值是浮点数 */
X2=Xs-Xe; X2=X2/120;
Y2=Ys-Ye; Y2=Y2/200;
dw=1; //校正完成标志
LCD_Clear(WHITE); //清屏
/* 在屏幕的指定区域显示调色板图形 */
FillColor( 0, 0, 30,30, RED);
FillColor( 30, 0, 60,30, BLUE);
FillColor( 60, 0, 90,30, GREEN);
FillColor( 90, 0,120,30, YELLOW);
FillColor(120, 0,150,30, BROWN);
FillColor(150, 0,180,30, CYAN);
LCD_ShowString(220,0,"Cl");
while (1) //等待中断到来
{
if(PEN==0){
delay_ms(50); //延时50ms用于触笔消抖
while(PEN==0){ //未抬起触笔的情况下画图
Read_XPT2046();
}
}
}
}
void TP_Init(void)
{
RCC->APB2ENR|=1<<6; //开启时钟E
SPIx_Init(); //SPI初始化
SPIx_SetSpeed(256);
GPIOE->CRL&=0XFFFFFF00; //E0 为TP_CS 片选
GPIOE->CRL|=0X00000083; //E1 为 PEN 输入
GPIOE->ODR|=1<<0;
GPIOE->ODR|=1<<1;
}
/****************************************************************************
* 名 称:u16 TPReadX(void)
* 功 能:触摸屏X轴数据读出
* 入口参数:无
* 出口参数:无
* 说 明:
* 调用方法:
****************************************************************************/
u16 TPReadX(void)
{
u16 x=0;
TP_CS=0; //选择XPT2046
delay_us(20); //延时
SPIx_ReadWriteByte(0x90); //设置X轴读取标志
delay_us(20); //延时
x=SPIx_ReadWriteByte(0x00); //连续读取16位的数据
x<<=8;
x+=SPIx_ReadWriteByte(0x00);
delay_us(20); //禁止XPT2046
TP_CS=1;
x = x>>3; //移位换算成12位的有效数据0-4095
return (x);
}
/****************************************************************************
* 名 称:u16 TPReadY(void)
* 功 能:触摸屏Y轴数据读出
* 入口参数:无
* 出口参数:无
* 说 明:
* 调用方法:
****************************************************************************/
u16 TPReadY(void)
{
u16 y=0;
TP_CS=0; //选择XPT2046
delay_us(20); //延时
SPIx_ReadWriteByte(0xD0); //设置Y轴读取标志
delay_us(20); //延时
y=SPIx_ReadWriteByte(0x00 //连续读取16位的数据
y<<=8;
y+=SPIx_ReadWriteByte(0x00);
delay_us(20); //禁止XPT2046
TP_CS=1;
y = y>>3; //移位换算成12位的有效数据0-4095
return (y);
}
/****************************************************************************
* 名 称:void Read_XPT2046(void)
* 功 能:读取触摸坐标,进行采样计算,并画点
* 入口参数:无
* 出口参数:无
* 说 明:
* 调用方法:
****************************************************************************/
void Read_XPT2046(void)
{
float X1,Y1;
u8 t,t1,count=0;
u16 databuffer[2][30]; //触摸坐标过采样缓冲区
u16 temp=0;
do{ //循环读数30次
Y=TPReadX();
X=TPReadY();
if(X>100&&X<4000&&Y>100&&Y<4000) //如果是在触摸显示有效区范围的值,标示此读数有效
{
databuffer[0][count]=X;
databuffer[1][count]=Y;
count++;
}
}while((PEN==0)&&count<30);
if(count==30) //每次度数一定要读到30次数据,否则丢弃
{
do //将数据X升序排列
{
t1=0;
for(t=0;t<count-1;t++)
{
if(databuffer[0][t]>databuffer[0][t+1])//升序排列
{
temp=databuffer[0][t+1];
databuffer[0][t+1]=databuffer[0][t];
databuffer[0][t]=temp;
t1=1;
}
}
}while(t1);
do //将数据Y升序排列
{
t1=0;
for(t=0;t<count-1;t++)
{
if(databuffer[1][t]>databuffer[1][t+1])//升序排列
{
temp=databuffer[1][t+1];
databuffer[1][t+1]=databuffer[1][t];
databuffer[1][t]=temp;
t1=1;
}
}
}while(t1);
}
/* 从排序过的数组里中间抽取连续的10组数据,进行取平均值,获得较高的精度 */
X1=0; Y1=0;
for(count=10;count<20; count++){
X1=X1+databuffer[0][count];
Y1=Y1+databuffer[1][count];
}
X1=X1/10; Y1=Y1/10;
LCD_ShowNum(190,2,Y1,4,16);
LCD_ShowNum(190,17,X1,4,16);
if(X1<=4096&&Y1<=4096) //触摸坐标值应小于4096
{
X=X1;
Y=Y1;
iif(dw==1){ //如果进行了校正过程
if(X1>=Xs)X1=0; //对该点的触摸X值进行界限判别,如果小于于第一个校正点的触摸X值,该点和校正点的差值初始化为0(和屏有关)
else X1=Xs-X1; //如果小于第一个校正点的触摸X值,计算出该点和校正点的差值(和屏有关)
if(Y1>=Ys)Y1=0; //如果小于第一个校正点的触摸Y值,计算出该点和校正点的差值(和屏有关)
else Y1=Ys-Y1; //对该点的触摸Y值进行界限判别,如果大于第一个校正点的触摸Y值,该点和校正点的差值初始化为0(和屏有关)
X=X1/X2; //根据一个像素对应的触摸值,算出屏幕上的实际X坐标
Y=Y1/Y2; //根据一个像素对应的触摸值,算出屏幕上的实际Y坐标
drawbigpoint(X,Y); //在该坐标画点
}
}
}
|