?? touchstreen.c
字號(hào):
/*
* @file touchstreen.c
* @author dayong
* @version V1.0
* @date 05/24/2012
*/
#include "stm32f10x.h"
#include "fsmc_sram.h"
#include "grlib/grlib.h"
#include "grlib/widget.h"
#include "touchstreen.h"
#include "Calibrate.h"//偏移量矯正算法
#include "lcdhal.h"
#include "usart.h"
//extern TOUCH_CorrectionTypeDef g_TouchCorrectionStruct; //觸摸屏矯正量 結(jié)構(gòu)體
#define Up 1
#define Down 0
extern unsigned char g_ucPenUpDownState;
extern PointTypeDef g_strDpy_Point;
extern TOUCH_CorrectionTypeDef g_strTouchCorrectionStruct;
static long (*g_pfnTSHandler)(unsigned long ulMessage, long lX, long lY);
/****************************************************************************
* 名 稱:void XTP2046_Init(void)
* 功 能:TFT 觸摸屏控制初始化
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 調(diào)用方法:無
****************************************************************************/
void XTP2046_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* SPI1 時(shí)鐘使能 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
/* SPI1 SCK(PA5)、MISO(PA6)、MOSI(PA7) 設(shè)置 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //口線速度50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用模式
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //觸摸檢測(cè)引腳
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* SPI1 觸摸芯片的片選控制設(shè)置 PB7 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //口線速度50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出模式
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 由于SPI1總線上掛接了4個(gè)外設(shè),所以在使用觸摸屏?xí)r,需要禁止其余3個(gè)SPI1 外設(shè), 才能正常工作 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //SPI1 SST25VF016B片選
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //SPI1 VS1003片選
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //SPI1 網(wǎng)絡(luò)模塊片選
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_4); //SPI CS1
GPIO_SetBits(GPIOB, GPIO_Pin_12); //SPI CS4
GPIO_SetBits(GPIOA, GPIO_Pin_4); //SPI NSS
/* SPI1總線 配置 */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全雙工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //時(shí)鐘極性 空閑狀態(tài)時(shí),SCK保持低電平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //時(shí)鐘相位 數(shù)據(jù)采樣從第一個(gè)時(shí)鐘邊沿開始
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //軟件產(chǎn)生NSS
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //波特率控制 SYSCLK/64
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //數(shù)據(jù)高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC多項(xiàng)式寄存器初始值為7
SPI_Init(SPI1, &SPI_InitStructure);
/* SPI1 使能 */
SPI_Cmd(SPI1,ENABLE);
}
/****************************************************************************
* 名 稱:unsigned char SPI_WriteByte(unsigned char data)
* 功 能:SPI1 寫函數(shù)
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 調(diào)用方法:
****************************************************************************/
unsigned char SPI_WriteByte(unsigned char ucData)
{
unsigned char ucDat = 0;
//等待發(fā)送緩沖區(qū)空
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
// 發(fā)送一個(gè)字節(jié)
SPI_I2S_SendData(SPI1,ucData);
//等待是否接收到一個(gè)字節(jié)
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);
// 獲得該字節(jié)
ucDat = SPI_I2S_ReceiveData(SPI1);
// 返回收到的字節(jié)
return ucDat;
}
/****************************************************************************
* 名 稱:unsigned char XTP2046ReadX(void)
* 功 能:觸摸屏X軸數(shù)據(jù)讀出
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 調(diào)用方法:
****************************************************************************/
unsigned int XTP2046Read_X(void)
{
unsigned int uiX=0;
TP_CS(); //選擇XPT2046
Delay(20); //延時(shí)
SPI_WriteByte(0x90); //設(shè)置X軸讀取標(biāo)志
Delay(20); //延時(shí)
uiX=SPI_WriteByte(0x00); //連續(xù)讀取16位的數(shù)據(jù)
uiX<<=8;
uiX+=SPI_WriteByte(0x00);
Delay(20); //禁止XPT2046
TP_DCS();
uiX = uiX>>3; //移位換算成12位的有效數(shù)據(jù)0-4095
//uiX = uiX>>5; //移位換算成10位有效數(shù)據(jù)
return (uiX);
}
/****************************************************************************
* 名 稱:unsigned char XTP2046Read_Y(void)
* 功 能:觸摸屏Y軸數(shù)據(jù)讀出
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 調(diào)用方法:
****************************************************************************/
unsigned int XTP2046Read_Y(void)
{
unsigned int uiY =0;
TP_CS(); //選擇XPT2046
Delay(20); //延時(shí)
SPI_WriteByte(0xD0); //設(shè)置Y軸讀取標(biāo)志
Delay(20); //延時(shí)
uiY=SPI_WriteByte(0x00); //連續(xù)讀取16位的數(shù)據(jù)
uiY<<=8;
uiY+=SPI_WriteByte(0x00);
Delay(20); //禁止XPT2046
TP_DCS();
uiY = uiY>>3; //移位換算成12位的有效數(shù)據(jù)0-4095
//uiY = uiY>>5; //移位換算成10位有效數(shù)據(jù)
return (uiY);
}
/****************************************************************************
* 名 稱:void Get_Coordinat(POINT *psPOINT)
* 功 能:讀取觸摸坐標(biāo),
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 調(diào)用方法:
****************************************************************************/
//unsigned char Get_Coordinat(POINT *psPOINT)
void Get_Coordinat(PointTypeDef *psPOINT)
{
unsigned int uiX,uiY;
unsigned char ucT,ucT1,ucCount = 0;
unsigned int uiDatabuffer[2][30]; //觸摸坐標(biāo)過采樣緩沖區(qū)
unsigned int uiTemp=0;
do{
uiX =XTP2046Read_X();
uiY =XTP2046Read_Y(); //循環(huán)讀數(shù)30次
if(uiX>100&&uiX<4000&&uiY>100&&uiY<4000) //如果是在觸摸顯示有效區(qū)范圍的值,標(biāo)示此讀數(shù)有效
{
uiDatabuffer[0][ucCount]=uiX;
uiDatabuffer[1][ucCount]=uiY;
ucCount++;
}
}while(ucCount<30);
if(ucCount==30) //每次度數(shù)一定要讀到30次數(shù)據(jù),否則丟棄
{
do //將數(shù)據(jù)X升序排列
{
ucT1=0;
for(ucT=0;ucT<ucCount-1;ucT++)
{
if(uiDatabuffer[0][ucT]>uiDatabuffer[0][ucT+1])//升序排列
{
uiTemp=uiDatabuffer[0][ucT+1];
uiDatabuffer[0][ucT+1]=uiDatabuffer[0][ucT];
uiDatabuffer[0][ucT]=uiTemp;
ucT1=1;
}
}
}while(ucT1);
do //將數(shù)據(jù)Y升序排列
{
ucT1=0;
for(ucT=0;ucT<ucCount-1;ucT++)
{
if(uiDatabuffer[1][ucT]>uiDatabuffer[1][ucT+1])//升序排列
{
uiTemp=uiDatabuffer[1][ucT+1];
uiDatabuffer[1][ucT+1]=uiDatabuffer[1][ucT];
uiDatabuffer[1][ucT]=uiTemp;
ucT1=1;
}
}
}while(ucT1);
/* 從排序過的數(shù)組里中間抽取連續(xù)的10組數(shù)據(jù),進(jìn)行取平均值,獲得較高的精度 */
for(ucCount=10;ucCount<20; ucCount++)
{
uiX=uiX+uiDatabuffer[0][ucCount];
uiY=uiY+uiDatabuffer[1][ucCount];
}
//USART_OUT(USART1,"0103");
if(uiX%10 > 5)
{
psPOINT->uiX = uiX/10 +1;
// USART_OUT(USART1,"0104");
}
else
{
psPOINT->uiX = uiX/10;
// USART_OUT(USART1,"0105");
}
if(uiY%10 > 5)
{
psPOINT->uiY = (uiY/10 + 1);
// USART_OUT(USART1,"0106");
}
else
{
psPOINT->uiY = (uiY/10);
// USART_OUT(USART1,"0107");
}
// USART_OUT(USART1,"0108");
//return 1;
}
//USART_OUT(USART1,"0109");
USART_OUT(USART1,"x=%d ",psPOINT->uiX);
USART_OUT(USART1,"y=%d ",psPOINT->uiY);
}
/*
#define VALUE 5
unsigned char Get_Coordinat(POINT *psScreen)
{
//POINT *Screen;
int m0,m1,m2;
unsigned char count = 0;
unsigned int databuffer[2][9]={{0},{0}};//
unsigned int temp[3];
while(1)
{
do
{
databuffer[1][count] = XTP2046Read_X(); // V H coordinat swap
databuffer[0][count] = XTP2046Read_Y(); //
count ++;
}while(count<9);
if(count == 9)
{
temp[0]=(databuffer[0][0]+databuffer[0][1]+databuffer[0][2])/3;
temp[1]=(databuffer[0][3]+databuffer[0][4]+databuffer[0][5])/3;
temp[2]=(databuffer[0][6]+databuffer[0][7]+databuffer[0][8])/3;
m0 = temp[0] - temp[1];
m1 = temp[1] - temp[2];
m2 = temp[2] - temp[0];
m0 = m0 > 0 ? m0 : (0-m0);
m1 = m1 > 0 ? m1 : (0-m1);
m2 = m2 > 0 ? m2 : (0-m2);
if(m0 > VALUE && m1 > VALUE && m2 > VALUE)
{
return 0;
}
if(m0 < m1)
{
if(m2 < m0)
psScreen->x = (temp[0] + temp[2])/2;
else
psScreen->x = (temp[0] + temp[1])/2;
}
else
{
if(m2 < m1)
psScreen->x = (temp[0] + temp[2])/2;
else
psScreen->x = (temp[1] + temp[2])/2;
}
temp[0]=(databuffer[1][0]+databuffer[1][1]+databuffer[1][2])/3;
temp[1]=(databuffer[1][3]+databuffer[1][4]+databuffer[1][5])/3;
temp[2]=(databuffer[1][6]+databuffer[1][7]+databuffer[1][8])/3;
m0 = temp[0] - temp[1];
m1 = temp[1] - temp[2];
m2 = temp[2] - temp[0];
m0 = m0 > 0 ? m0 : (0-m0);
m1 = m1 > 0 ? m1 : (0-m1);
m2 = m2 > 0 ? m2 : (0-m2);
if(m0 > VALUE && m1 > VALUE && m2 > VALUE)
{
return 0;
}
if(m0 < m1)
{
if(m2 < m0)
psScreen->y = (temp[0] + temp[2])/2;
else
psScreen->y = (temp[0] + temp[1])/2;
return 1;
}
else
{
if(m2 < m1)
psScreen->y = (temp[0] + temp[2])/2;
else
psScreen->y = (temp[1] + temp[2])/2;
return 1;
}
break;
}
}
return 0;
}
*/
/****************************************************************************
* 名 稱:void Get_TouchCorrection(TOUCH_CorrectionTypeDef *TouchCorrectionStruct)
* 功 能:獲取觸摸屏校正量,
* 入口參數(shù):無
* 出口參數(shù):無
* 說 明:
* 調(diào)用方法:
****************************************************************************/
void Get_TouchCorrection(TOUCH_CorrectionTypeDef *TouchCorrectionStruct)
{
PointTypeDef strPoint1; //第一個(gè)校正點(diǎn)
PointTypeDef strPoint2; //第二個(gè)校正點(diǎn)
unsigned char ucI;
for(ucI=0; ucI<10; ucI++)
{ //在豎屏模式下,左上角顯示第一個(gè)校正點(diǎn)點(diǎn)擊區(qū)域
PixelDraw (0,0,0+ucI,0xffff);
PixelDraw (0,0+ucI,0,0xffff);
}
USART_OUT(USART1,"push the first Point");
while (1) //等待點(diǎn)擊第一個(gè)觸摸校正點(diǎn)
{
if(PEN==0) //點(diǎn)擊第一個(gè)校正點(diǎn) 等待觸摸檢測(cè)電平變低
{
Delay(34000); //延時(shí)340ms 消除抖動(dòng)
if(PEN==0)
{ //檢測(cè)觸摸中斷線是否可靠點(diǎn)擊
while(PEN==0) //點(diǎn)擊未松開,持續(xù)讀取觸摸坐標(biāo)
{
Delay(1);
Get_Coordinat(&strPoint1);//讀取觸摸坐標(biāo)
//獲得第一個(gè)校正點(diǎn)的X,Y
TouchCorrectionStruct->uiXs=strPoint1.uiX;
TouchCorrectionStruct->uiYs=strPoint1.uiY;
Delay(34000); //延時(shí)340ms 消除抖動(dòng)
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -