STM32f103的觸摸屏的設(shè)置與使用
多功能采集顯示平臺(tái)的人機(jī)交互采用的觸屏方案。
觸屏功能主要是依賴電阻觸摸屏的主要部分是一塊與顯示器表面非常配合的電阻薄膜屏,這是一種多層的復(fù)合薄膜,它以一層玻璃或硬塑料平板作為基層,表面涂有一層透明氧化金屬(透明的導(dǎo)電電阻)導(dǎo)電層,上面再蓋有一層外表面硬化處理、光滑防擦的塑料層、它的內(nèi)表面也涂有一層涂層、在他們之間有許多細(xì)小的(小于1/1000英寸)的透明隔離點(diǎn)把兩層導(dǎo)電層隔開絕緣。當(dāng)手指觸摸屏幕時(shí),兩層導(dǎo)電層在觸摸點(diǎn)位置就有了接觸,電阻發(fā)生變化,在X和Y兩個(gè)方向上產(chǎn)生信號(hào),然后送觸摸屏控制器。控制器偵測(cè)到這一接觸并計(jì)算出(X,Y)的位置,再根據(jù)獲得的位置模擬鼠標(biāo)的方式運(yùn)作。這就是電阻技術(shù)觸摸屏的最基本的原理。
電阻觸摸屏的優(yōu)點(diǎn):精度高、價(jià)格便宜、抗干擾能力強(qiáng)、穩(wěn)定性好。
電阻觸摸屏的缺點(diǎn):容易被劃傷、透光性不太好、不支持多點(diǎn)觸摸。
多功能采集顯示平臺(tái)采用了觸摸屏控制芯片為XPT2046。XPT2046是一款4導(dǎo)線制觸摸屏控制器,內(nèi)含12位分辨率125KHz轉(zhuǎn)換速率逐步逼近型A/D轉(zhuǎn)換器。XPT2046支持從1.5V到5.25V的低電壓I/O接口。XPT2046能通過執(zhí)行兩次A/D轉(zhuǎn)換查出被按的屏幕位置,除此之外,還可以測(cè)量加在觸摸屏上的壓力。
硬件設(shè)計(jì)方面,多功能采集顯示平臺(tái)采用SPI的方式讀取XPT2046所存儲(chǔ)的XY的邏輯電壓值,同時(shí)采用了外部中斷的方式響應(yīng)電阻觸摸屏的點(diǎn)擊事件。SPI接口使用片上資源的SPI2,占用PB13~15,片選信號(hào)線占用IO口PB12,觸摸響應(yīng)信號(hào)線占用PG7,使用外部中斷模式,并且中斷級(jí)別高于顯示刷新定時(shí)中斷。
軟件設(shè)計(jì)方面有以下3點(diǎn)
第一,初始化XPT2046芯片,初始化SPI功能,并設(shè)置外部中斷事件,同時(shí)使能XPT2046芯片和IO內(nèi)部時(shí)鐘。
第二,電阻觸摸屏的點(diǎn)擊中斷事件,編寫中斷服務(wù)函數(shù),進(jìn)行對(duì)點(diǎn)擊的位置的獲取,并且根據(jù)獲取的位置進(jìn)行區(qū)域判定,經(jīng)行相應(yīng)的操作。
第三,對(duì)于電阻觸摸屏的特性,點(diǎn)擊電阻觸摸屏后驅(qū)動(dòng)芯片可以產(chǎn)生一個(gè)中斷信號(hào)提示觸摸動(dòng)作,同時(shí)在寄存器存放這X和Y軸兩個(gè)邏輯電壓值,這兩個(gè)邏輯電壓值的精度是12位的,與TFTLCD的物理坐標(biāo)值(320*240)是有一定相關(guān)性的,但是便于程序的編寫,我們需要使得邏輯電壓值和物理坐標(biāo)值相同。所以編寫了電阻觸摸屏的校正程序,校正的算法是改進(jìn)的五點(diǎn)校正法
XPT2046觸摸屏初始化代碼如下:
voidTouch_Init(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
NVIC_InitTypeDefNVIC_InitStructure;
EXTI_InitTypeDefEXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG|RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//關(guān)閉jtag,使能SWD,可以用SWD模式調(diào)試
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOG,&GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOG,GPIO_PinSource7);//設(shè)置管較為外部中斷管腳
EXTI_InitStructure.EXTI_Line=EXTI_Line7;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//為中斷請(qǐng)求
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//Falling下降沿Rising上升
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line7);//清除線路掛起位
/*EnabletheEXTI4Interrupt*/
NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
SPI2_Init();
CSPin_init();
}
讀取XY坐標(biāo)函數(shù):
u16ADS_Read(u8CMD)
{
u16Num=0,temp;
TCS_LOW;
SPI2_ReadWriteByte(CMD);
delay_us(6);
temp=SPI2_ReadWriteByte(0x00);
Num=temp<<8;
delay_us(1);
temp=SPI2_ReadWriteByte(0x00);
Num|=temp;
Num>>=4;
TCS_HIGH;
return(Num);
}
u16Read_XY(u8CMD)
{
u16i,j;
u16buf[10];
u16sum=0;
u16temp;
for(i=0;i<10;i++)buf[i]=ADS_Read(CMD);
for(i=0;i<9;i++)
{
for(j=i+1;j<10;j++)
{
if(buf[i]>buf[j])
{
temp=buf[i];
buf[i]=buf[j];
buf[j]=temp;
}
}
}
for(i=3;i<7;i++)sum+=buf[i];
temp=sum/(4);
returntemp;
}
u16Read_X(void)
{
u16tempx;
tempx=(Read_XY(CMD_RDX)-XLC)/(KX)+XC;
returntempx;
}
u16Read_Y(void)
{
u16tempy;
tempy=(Read_XY(CMD_RDY)-YLC)/(KY)+YC;
returntempy;
}
這里的KX KYXLC YLC XC YC 都是用于校正電阻屏的系數(shù),缺省值為1.00。
電阻屏的校正可以使用5點(diǎn)矯正法,詳情請(qǐng)參考:http://blog.csdn.net/devintt/article/details/47022761