?? touch.c
字號(hào):
#include "touch.h"
//觸摸屏初始化
//使用外部8M晶振,PLL到72M頻率
//正點(diǎn)原子@SCUT
//2009/06/08
//V1.1
//SPI開(kāi)始
void start_spi()
{
TCLK_SET(0);
TCS_SET(1);
TDIN_SET(1);
TCLK_SET(1);
TCS_SET(0);
}
//SPI寫(xiě)數(shù)據(jù)
//向7846寫(xiě)入1byte數(shù)據(jù)
void WriteByteADS(u8 num)
{
u8 count=0;
TCLK_SET(0);
for(count=0;count<8;count++)
{
if(num&0x80)TDIN_SET(1);
else TDIN_SET(0);
num<<=1;
TCLK_SET(0);//上升沿有效
TCLK_SET(1);
}
}
//SPI讀數(shù)據(jù)
//從7846讀取adc值
u16 ReadWordADS(void)
{
u8 count=0;
u16 Num=0;
for(count=0;count<12;count++)
{
Num<<=1;
TCLK_SET(1);//下降沿有效
TCLK_SET(0);
if(DOUT)Num++;
}
return(Num);
}
//讀取一次X,Y值
//讀到的X,Y坐標(biāo)值必須都大于100
//成功返回1,不成功返回0
//讀數(shù)限制在100~3800之間.
u8 read_once(void)
{
start_spi();//啟動(dòng)SPI
WriteByteADS(CMD_RDX);
//ADS7846的轉(zhuǎn)換時(shí)間最長(zhǎng)為6us
TCLK_SET(1);delay_us(3);
TCLK_SET(0);delay_us(3);
Pen_Point.X=4096-ReadWordADS();//讀X坐標(biāo),并轉(zhuǎn)換
WriteByteADS(CMD_RDY);
//ADS7846的轉(zhuǎn)換時(shí)間最長(zhǎng)為6us
TCLK_SET(1);delay_us(3);
TCLK_SET(0);delay_us(3);
Pen_Point.Y=4096-ReadWordADS();//讀Y軸坐標(biāo)
TCS_SET(1);
//限制觸摸屏讀數(shù)范圍,個(gè)人根據(jù)實(shí)際情況定
if(Pen_Point.X<3950&&Pen_Point.X>200&&Pen_Point.Y<3950&&Pen_Point.Y>200)return 1;//讀數(shù)成功
else return 0; //讀數(shù)失敗
}
//讀取ADS7846
//連續(xù)讀取10次數(shù)據(jù),對(duì)十次數(shù)據(jù)排序,然后對(duì)
//中間三次取平均值,得到最終的X,Y值
u8 Read_Ads7846(void)
{
u8 t,t1,count=0;
u16 databuffer[2][10];//數(shù)據(jù)組
u16 temp=0;
do //循環(huán)讀數(shù)10次
{
if(read_once())//讀數(shù)成功
{
databuffer[0][count]=Pen_Point.X;
databuffer[1][count]=Pen_Point.Y;
count++;
}
}while(NPEN&&count<10);
if(count==10)//一定要讀到10次數(shù)據(jù),否則丟棄
{
do//將數(shù)據(jù)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//將數(shù)據(jù)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);
Pen_Point.X=(databuffer[0][3]+databuffer[0][4]+databuffer[0][5])/3;
Pen_Point.Y=(databuffer[1][3]+databuffer[1][4]+databuffer[1][5])/3;
//TFT_ShowString(100,140,"X read:");TFT_ShowNum(142,140,Pen_Point.X); //
//TFT_ShowString(100,152,"Y read:");TFT_ShowNum(142,152,Pen_Point.Y);
return 1;
}
return 0;//讀數(shù)失敗
}
//中斷,檢測(cè)到PEN腳的一個(gè)下降沿.
//置位Pen_Point.Key_Sta為按下?tīng)顟B(tài)
//中斷線0線上的中斷檢測(cè)
void EXTI0_IRQHandler(void)
{
Pen_Point.Key_Sta=Key_Down;//按鍵按下
EXTI->PR=1<<0; //清除LINE0上的中斷標(biāo)志位
}
//按鍵處理程序
//type:按鍵響應(yīng)類(lèi)型
//0,單點(diǎn),定點(diǎn),不擴(kuò)展.一定要按鍵松開(kāi)才返回
//1,單點(diǎn),滑動(dòng),不擴(kuò)展.滾動(dòng)條操作/連加操作
//2,擴(kuò)展按鍵支持:
//即:MOVE_LEFT,MOVE_RIGHT,MOVE_UP,MOVE_DOWN使能
u8 Touch_Key_Pro(u8 type)
{
u16 tempx,tempy;//暫時(shí)保存X,Y坐標(biāo)
u8 ml=0,mr=0,mu=0,md=0;//四個(gè)方向上移動(dòng)次數(shù)
u8 first=1;
//按鍵還是按下的
//手動(dòng)按觸摸屏的時(shí)候,至少需要15ms才能退出這個(gè)循環(huán)
do
{
Pen_Point.Key_Sta=Key_Up;//按鍵狀態(tài)變?yōu)樗砷_(kāi)
if(Read_Ads7846())//成功讀數(shù)
{
if(first)
{
Pen_Point.X0=Pen_Point.X;Pen_Point.Y0=Pen_Point.Y;//得到初始按下的坐標(biāo)
tempx=Pen_Point.X;tempy=Pen_Point.Y;
//printf("X0:%d Y0:%d\n",Pen_Point.X,Pen_Point.Y);
first=0; //標(biāo)記清空
}else if(type==2) //擴(kuò)展按鍵
{
if(tempx>Pen_Point.X)ml++;
else mr++;
if(tempy>Pen_Point.Y)mu++;
else md++;
//設(shè)定一個(gè)門(mén)限值,不能讓一次移動(dòng)大于這個(gè)值,如果一次大于這個(gè)值
//認(rèn)為觸摸屏誤動(dòng)作了.400的時(shí)候,反映比較慢
if(abs(tempx-Pen_Point.X)>700||abs(tempy-Pen_Point.Y)>700)//有抖動(dòng)
{
ml=mr=mu=md=0;//全部清掉
tempx=Pen_Point.X=Pen_Point.X0;//坐標(biāo)復(fù)位
tempy=Pen_Point.Y=Pen_Point.Y0;
break;//退出數(shù)據(jù)采集,結(jié)果為點(diǎn)采集
}
tempx=Pen_Point.X;tempy=Pen_Point.Y;//轉(zhuǎn)移臨時(shí)坐標(biāo)
}else if(type==1)break;
//printf("X:%d Y:%d\n",Pen_Point.X,Pen_Point.Y);
}
delay_ms(10);//10ms消抖
}while(NPEN||Pen_Point.Key_Sta==Key_Down);//PEN=0或者按鍵狀態(tài)為按下?tīng)顟B(tài);
delay_ms(50);
Pen_Point.Key_Sta=Key_Up;//按鍵狀態(tài)變?yōu)樗砷_(kāi)
//單次/不擴(kuò)展 鍵值處理
if(abs(tempx-Pen_Point.X0)<=200&&abs(tempy-Pen_Point.Y0)<=200||type<2)//單次按鍵/不擴(kuò)展按鍵功能
{
if(Pen_Point.xfac!=0)//已經(jīng)校準(zhǔn)過(guò)了
{
Pen_Point.X0=Pen_Point.xfac*Pen_Point.X0+Pen_Point.xoff;
Pen_Point.Y0=Pen_Point.yfac*Pen_Point.Y0+Pen_Point.yoff;
}
Pen_Point.X=Pen_Point.X0;Pen_Point.Y=Pen_Point.Y0;
return CLICK_POINT;//沒(méi)有移動(dòng)
}
//擴(kuò)展鍵值處理
if(abs(tempx-Pen_Point.X0)<=500&&abs(tempy-Pen_Point.Y0)<=500)return 0;//滑動(dòng)距離最少要大于500
else if(Pen_Point.xfac!=0)//已經(jīng)校準(zhǔn)過(guò)了
{
Pen_Point.X0=Pen_Point.xfac*Pen_Point.X0+Pen_Point.xoff;
Pen_Point.Y0=Pen_Point.yfac*Pen_Point.Y0+Pen_Point.yoff;
tempx=Pen_Point.xfac*tempx+Pen_Point.xoff;
tempy=Pen_Point.yfac*tempy+Pen_Point.yoff;
}
if(abs(ml-mr)>abs(mu-md))//數(shù)量 滿足
{
if(abs(tempx-Pen_Point.X0)>abs(tempy-Pen_Point.Y0))//質(zhì)量滿足
{
if(tempx>Pen_Point.X0)return MOVE_RIGHT;
else return MOVE_LEFT;
}else //質(zhì)量不滿足
{
if(tempy>Pen_Point.Y0)return MOVE_DOWN;
else return MOVE_UP;
}
}else
{
if(abs(tempy-Pen_Point.Y0)>abs(tempx-Pen_Point.X0))//質(zhì)量滿足
{
if(tempy>Pen_Point.Y0)return MOVE_DOWN;
else return MOVE_UP;
}else //質(zhì)量不滿足
{
if(tempx>Pen_Point.X0)return MOVE_RIGHT;
else return MOVE_LEFT;
}
}
}
//判斷觸點(diǎn)是不是在指定區(qū)域之內(nèi)
//(x1,y1):起始坐標(biāo)
//(x2,y2):結(jié)束坐標(biāo)
//返回值 :1,在該區(qū)域內(nèi).0,不在該區(qū)域內(nèi).
u8 Is_In_Area(u8 x1,u16 y1,u8 x2,u16 y2)
{
if(Pen_Point.X<=x2&&Pen_Point.X>=x1&&Pen_Point.Y<=y2&&Pen_Point.Y>=y1)return 1;
else return 0;
}
//把觸摸屏得到的數(shù)據(jù)轉(zhuǎn)換為數(shù)字(按鈕值)
//M_Type:按鈕模式;
//0,系統(tǒng)菜單
//1,文件瀏覽模式
//2,時(shí)間模式下,按鍵的獲取,連按支持!
//3,音樂(lè)播放模式下
//4,功能選擇模式下
//5,收音機(jī)模式下
//6,鬧鐘中斷程序按鍵
//7,TXT瀏覽/JPEG瀏覽 時(shí)按鍵處理
//返回值:對(duì)應(yīng)的按鍵值(1~n)
//返回0,則表示此次按鍵無(wú)效
u8 Touch_To_Num(u8 M_Type)
{
u8 xtemp;
u16 t,ytemp;
switch(M_Type)
{
case 0://系統(tǒng)菜單下
xtemp=Touch_Key_Pro(1);//不使用擴(kuò)展按鈕
if(!(xtemp&CLICK_POINT))return 0;//不是點(diǎn)觸直接退出
ytemp=10;
for(t=0;t<9;t++)
{
xtemp=80*(t%3)+10;
if(t>5)ytemp=216;
else if(t>2)ytemp=113;
if(Is_In_Area(xtemp,ytemp,xtemp+59,ytemp+90))return t+1;//返回按鍵值
}
break;
case 1://1,文件瀏覽模式
xtemp=Touch_Key_Pro(2);//支持?jǐn)U展
if(xtemp&CLICK_POINT) //點(diǎn)觸摸 得到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;//按鍵無(wú)效
}
if(xtemp)return xtemp&0xf0;//滑動(dòng)觸摸了!!
break;
case 2://2,時(shí)間模式下,按鍵的獲取,連按支持!
xtemp=Touch_Key_Pro(1);//不擴(kuò)展
if(xtemp&CLICK_POINT) //點(diǎn)觸摸 得到1~8的值
{
if(Is_In_Area(4,142,28,166))return 1;
else if(Is_In_Area(60,142,84,166))return 2;
else if(Is_In_Area(96,142,120,166))return 3;
else if(Is_In_Area(136,142,160,166))return 4;
else if(Is_In_Area(172,142,196,166))return 5;
else if(Is_In_Area(212,142,236,166))return 6;
else if(Is_In_Area(4,206,28,230))return 7;
else if(Is_In_Area(60,206,84,230))return 8;
else if(Is_In_Area(96,206,120,230))return 9;
else if(Is_In_Area(136,206,160,230))return 10;
else if(Is_In_Area(172,206,196,230))return 11;
else if(Is_In_Area(212,206,236,230))return 12;
else if(Is_In_Area(0,300,40,319))return 13;//選擇按鈕被按下
else if(Is_In_Area(200,300,239,319))return 14;//返回按鈕被按下
return 0;//按鍵無(wú)效
}
break;
case 3://MP3界面下面的按鈕值
xtemp=Touch_Key_Pro(1);//不擴(kuò)展
if(xtemp&CLICK_POINT) //點(diǎn)觸摸 得到1~8的值
{
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -