?? touchpanel.c
字號:
/****************************************Copyright (c)****************************************************
**
** http://www.powermcu.com
**
**--------------File Info---------------------------------------------------------------------------------
** File name: TouchPanel.c
** Descriptions: The TouchPanel application function
**
**--------------------------------------------------------------------------------------------------------
** Created by: AVRman
** Created date: 2010-11-7
** Version: v1.0
** Descriptions: The original version
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
*********************************************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <includes.h>
/* Private variables ---------------------------------------------------------*/
Matrix matrix ;Coordinate display ;
/* DisplaySample LCD坐標上對應的ads7843采樣AD值 如:LCD 坐標45,45 應該的X Y采樣ADC分別為3388,920 */
Coordinate ScreenSample[3];/* LCD上的坐標 */Coordinate DisplaySample[3] = { { 120,50 }, { 30, 200}, { 290,190} } ;
/* Private define ------------------------------------------------------------*/
#define THRESHOLD 2 /* 差值門限 */
/*******************************************************************************
* Function Name : LPC17xx_SPI_SetSpeed
* Description : Set clock speed to desired value
* Input : - speed: speed
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void LPC17xx_SPI_SetSpeed (uint8_t speed)
{
speed &= 0xFE;
if ( speed < 2 ) {
speed = 2 ;
}
LPC_SSP1->CPSR = speed;
}
/*******************************************************************************
* Function Name : ADS7843_SPI_Init
* Description : ADS7843 SPI 初始化
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
static void ADS7843_SPI_Init(void)
{
volatile uint32_t dummy;
/* Initialize and enable the SSP1 Interface module. */
LPC_SC->PCONP |= (1 << 10); /* Enable power to SSPI1 block */
/* P0.7 SCK, P0.8 MISO, P0.9 MOSI are SSP pins. */
LPC_PINCON->PINSEL0 &= ~((3UL<<14) | (3UL<<16) | (3UL<<18)) ; /* P0.7,P0.8,P0.9 cleared */
LPC_PINCON->PINSEL0 |= (2UL<<14) | (2UL<<16) | (2UL<<18); /* P0.7 SCK1,P0.8 MISO1,P0.9 MOSI1 */
/* PCLK_SSP1=CCLK */
LPC_SC->PCLKSEL0 &= ~(3<<20); /* PCLKSP0 = CCLK/4 (18MHz) */
LPC_SC->PCLKSEL0 |= (1<<20); /* PCLKSP0 = CCLK (72MHz) */
LPC_SSP1->CR0 = 0x0007; /* 8Bit, CPOL=0, CPHA=0 */
LPC_SSP1->CR1 = 0x0002; /* SSP1 enable, master */
LPC17xx_SPI_SetSpeed ( SPI_SPEED_2MHz );
/* wait for busy gone */
while( LPC_SSP1->SR & ( 1 << SSPSR_BSY ) );
/* drain SPI RX FIFO */
while( LPC_SSP1->SR & ( 1 << SSPSR_RNE ) )
{
dummy = LPC_SSP1->DR;
}
}
/*******************************************************************************
* Function Name : TP_Init
* Description : ADS7843端口初始化
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void TP_Init(void)
{
LPC_GPIO0->FIODIR |= (1<<6); /* P0.6 CS is output */
LPC_GPIO2->FIODIR |= (0<<13); /* P2.13 TP_INT is input */
TP_CS(1);
ADS7843_SPI_Init();
}
/*******************************************************************************
* Function Name : DelayUS
* Description : 延時1us
* Input : - cnt: 延時值
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
static void DelayUS(uint16_t cnt)
{
uint16_t i;
for(i = 0;i<cnt;i++)
{
uint8_t us = 12; /* 設置值為12,大約延1微秒 */
while (us--) /* 延1微秒 */
{
;
}
}
}
/*******************************************************************************
* Function Name : WR_CMD
* Description : 向 ADS7843寫數據
* Input : - cmd: 傳輸的數據
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
static uint8_t WR_CMD (uint8_t cmd)
{
uint8_t byte_r;
while (LPC_SSP1->SR & (1 << SSPSR_BSY) ); /* Wait for transfer to finish */
LPC_SSP1->DR = cmd;
while (LPC_SSP1->SR & (1 << SSPSR_BSY) ); /* Wait for transfer to finish */
while( !( LPC_SSP1->SR & ( 1 << SSPSR_RNE ) ) ); /* Wait untill the Rx FIFO is not empty */
byte_r = LPC_SSP1->DR;
return byte_r; /* Return received value */
}
/*******************************************************************************
* Function Name : RD_AD
* Description : 讀取ADC值
* Input : None
* Output : None
* Return : ADS7843返回二字節數據
* Attention : None
*******************************************************************************/
static int RD_AD(void)
{
unsigned short buf,temp;
temp = WR_CMD(0x00);
buf = temp<<8;
DelayUS(1);
temp = WR_CMD(0x00);;
buf |= temp;
buf>>=3;
buf&=0xfff;
return buf;
}
/*******************************************************************************
* Function Name : Read_X
* Description : 讀取ADS7843通道X+的ADC值
* Input : None
* Output : None
* Return : ADS7843返回通道X+的ADC值
* Attention : None
*******************************************************************************/
int Read_X(void)
{
int i;
TP_CS(0);
DelayUS(1);
WR_CMD(CHX);
DelayUS(1);
i=RD_AD();
TP_CS(1);
return i;
}
/*******************************************************************************
* Function Name : Read_Y
* Description : 讀取ADS7843通道Y+的ADC值
* Input : None
* Output : None
* Return : ADS7843返回通道Y+的ADC值
* Attention : None
*******************************************************************************/
int Read_Y(void)
{
int i;
TP_CS(0);
DelayUS(1);
WR_CMD(CHY);
DelayUS(1);
i=RD_AD();
TP_CS(1);
return i;
}
/*******************************************************************************
* Function Name : TP_GetAdXY
* Description : 讀取ADS7843 通道X+ 通道Y+的ADC值
* Input : None
* Output : None
* Return : ADS7843返回 通道X+ 通道Y+的ADC值
* Attention : None
*******************************************************************************/
void TP_GetAdXY(int *x,int *y)
{
int adx,ady;
adx=Read_X();
DelayUS(1);
ady=Read_Y();
*x=adx;
*y=ady;
}
/*******************************************************************************
* Function Name : Read_Ads7846
* Description : 得到濾波之后的X Y
* Input : None
* Output : None
* Return : Coordinate結構體地址
* Attention : None
*******************************************************************************/
Coordinate *Read_Ads7846(void)
{
static Coordinate screen;
int m0,m1,m2,TP_X[1],TP_Y[1],temp[3];
uint8_t count=0;
int buffer[2][9]={{0},{0}}; /* 坐標X和Y進行多次采樣 */
do /* 循環采樣9次 */
{
TP_GetAdXY(TP_X,TP_Y);
buffer[0][count]=TP_X[0];
buffer[1][count]=TP_Y[0];
count++;
}
while(!TP_INT_IN&& count<9); /* TP_INT_IN為觸摸屏中斷引腳,當用戶點擊觸摸屏時TP_INT_IN會被置低 */
if(count==9) /* 成功采樣9次,進行濾波 */
{
/* 為減少運算量,分別分3組取平均值 */
temp[0]=(buffer[0][0]+buffer[0][1]+buffer[0][2])/3;
temp[1]=(buffer[0][3]+buffer[0][4]+buffer[0][5])/3;
temp[2]=(buffer[0][6]+buffer[0][7]+buffer[0][8])/3;
/* 計算3組數據的差值 */
m0=temp[0]-temp[1];
m1=temp[1]-temp[2];
m2=temp[2]-temp[0];
/* 對上述差值取絕對值 */
m0=m0>0?m0:(-m0);
m1=m1>0?m1:(-m1);
m2=m2>0?m2:(-m2);
/* 判斷絕對差值是否都超過差值門限,如果這3個絕對差值都超過門限值,則判定這次采樣點為野點,拋棄采樣點,差值門限取為2 */
if( m0>THRESHOLD && m1>THRESHOLD && m2>THRESHOLD ) return 0;
/* 計算它們的平均值,同時賦值給screen */
if(m0<m1)
{
if(m2<m0)
screen.x=(temp[0]+temp[2])/2;
else
screen.x=(temp[0]+temp[1])/2;
}
else if(m2<m1)
screen.x=(temp[0]+temp[2])/2;
else
screen.x=(temp[1]+temp[2])/2;
/* 同上 計算Y的平均值 */
temp[0]=(buffer[1][0]+buffer[1][1]+buffer[1][2])/3;
temp[1]=(buffer[1][3]+buffer[1][4]+buffer[1][5])/3;
temp[2]=(buffer[1][6]+buffer[1][7]+buffer[1][8])/3;
m0=temp[0]-temp[1];
m1=temp[1]-temp[2];
m2=temp[2]-temp[0];
m0=m0>0?m0:(-m0);
m1=m1>0?m1:(-m1);
m2=m2>0?m2:(-m2);
if(m0>THRESHOLD&&m1>THRESHOLD&&m2>THRESHOLD) return 0;
if(m0<m1)
{
if(m2<m0)
screen.y=(temp[0]+temp[2])/2;
else
screen.y=(temp[0]+temp[1])/2;
}
else if(m2<m1)
screen.y=(temp[0]+temp[2])/2;
else
screen.y=(temp[1]+temp[2])/2;
return &screen;
}
return 0;
}
/* 下面是觸摸屏到液晶屏坐標變換的轉換函數 */
/* 只有在LCD和觸摸屏間的誤差角度非常小時,才能運用下面公式 */
/*******************************************************************************
* Function Name : setCalibrationMatrix
* Description : 計算出 K A B C D E F
* Input : None
* Output : None
* Return : 返回1表示成功 0失敗
* Attention : None
*******************************************************************************/uint8_t setCalibrationMatrix( Coordinate * displayPtr, Coordinate * screenPtr, Matrix * matrixPtr){ uint8_t retTHRESHOLD = 0 ; /* K=(X0-X2) (Y1-Y2)-(X1-X2) (Y0-Y2) */ matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; if( matrixPtr->Divider == 0 ) { retTHRESHOLD = 1; } else {
/* A=((XD0-XD2) (Y1-Y2)-(XD1-XD2) (Y0-Y2))/K */ matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; /* B=((X0-X2) (XD1-XD2)-(XD0-XD2) (X1-X2))/K */ matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) - ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ; /* C=(Y0(X2XD1-X1XD2)+Y1(X0XD2-X2XD0)+Y2(X1XD0-X0XD1))/K */ matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y + (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y + (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ; /* D=((YD0-YD2) (Y1-Y2)-(YD1-YD2) (Y0-Y2))/K */ matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) - ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ; /* E=((X0-X2) (YD1-YD2)-(YD0-YD2) (X1-X2))/K */ matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) - ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ; /* F=(Y0(X2YD1-X1YD2)+Y1(X0YD2-X2YD0)+Y2(X1YD0-X0YD1))/K */ matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y + (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y + (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ; } return( retTHRESHOLD ) ;}
/*******************************************************************************
* Function Name : getDisplayPoint
* Description : 通過 K A B C D E F 把通道X Y的值轉換為液晶屏坐標
* Input : None
* Output : None
* Return : 返回1表示成功 0失敗
* Attention : None
*******************************************************************************/
uint8_t getDisplayPoint(Coordinate * displayPtr, Coordinate * screenPtr, Matrix * matrixPtr ){ uint8_t retTHRESHOLD = 0 ; if( matrixPtr->Divider != 0 ) { /* XD = AX+BY+C */ displayPtr->x = ( (matrixPtr->An * screenPtr->x) + (matrixPtr->Bn * screenPtr->y) + matrixPtr->Cn ) / matrixPtr->Divider ; /* YD = DX+EY+F */ displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) + (matrixPtr->En * screenPtr->y) + matrixPtr->Fn ) / matrixPtr->Divider ; } else { retTHRESHOLD = 1; } return(retTHRESHOLD);}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -