📄 touchpanel.c
字号:
//====================================================================================
//File Name: TouchPanel.c
//Description: Touch panel driver
//Update: 2007.06.17 V1.0 by wangtao <wangtao@sunnorth.com.cn>
//====================================================================================
#include "SPCE3200_Register.h"
#include "SPCE3200_Constant.h"
#include "TouchPanel.h"
short LeftBound = TOUCH_DEFAULT_LB; // AD converted value for the left bound (16-bit)
short RightBound = TOUCH_DEFAULT_RB; // AD converted value for the right bound (16-bit)
short TopBound = TOUCH_DEFAULT_TB; // AD converted value for the top bound (16-bit)
short BottomBound = TOUCH_DEFAULT_BB; // AD converted value for the bottom bound (16-bit)
unsigned int TempADCx;
unsigned int TempADCy;
short ADC_Counter;
short Debounce_Counter;
short DebounceX;
short DebounceY;
short ResultX;
short ResultY;
//===========================================================================================================================
//Prototype: void Touch_Init(void)
//Description: Initialization program for the touch panel driver. It initializes variables, ADC, IO; enables ADC interrupt
//Argument: None
//Return Value: None
//===========================================================================================================================
void Touch_Init(void)
{
TempADCx = 0;
TempADCy = 0;
ADC_Counter = 0;
Debounce_Counter = 0;
DebounceX = -1;
DebounceY = -1;
ResultX = -1;
ResultY = -1;
*P_ADC_CLK_CONF = 0x0000;
*P_ADC_CLK_CONF = C_ADC_CLK_EN | C_ADC_RST_DIS;
*P_CLK_PLLAU_CONF |= C_PLLA_CLK_EN;
*P_GPIO_CLK_CONF = C_GPIO_CLK_EN | C_GPIO_RST_DIS;
*P_INT_CLK_CONF = C_INT_RST_DIS;
*P_ADC_MIC_CTRL1 |= C_ADC_MODE_ADC;
*P_ADC_MIC_CTRL2 |= C_ADC_CTRL_EN;
*P_ADC_MIC_CTRL2 &= ~C_ADC_AUTO_MODE;
*P_ADC_INT_STATUS = C_ADC_MANUAL_INTEN | C_ADC_MANUAL_FLAG;
*P_ADC_GPIO_SETUP |= ((TOUCH_X1<<24)|(TOUCH_Y2<<24));
*P_ADC_GPIO_SETUP &= ~(TOUCH_X2<<24)|(TOUCH_Y1<<24);
*P_ADC_GPIO_SETUP |= (TOUCH_X1<<16)|(TOUCH_X2<<16)|(TOUCH_Y1<<16)|(TOUCH_Y2<<16);
*P_ADC_GPIO_SETUP &= ~(TOUCH_X2|TOUCH_Y1);
*P_ADC_GPIO_SETUP |= (TOUCH_X1|TOUCH_Y2);
*P_ADC_GPIO_SETUP &= ~((TOUCH_Y1<<8)|(TOUCH_Y2<<8));
*P_ADC_GPIO_SETUP |= (TOUCH_X1<<8)|(TOUCH_X2<<8);
*P_ADC_AINPUT_CTRL &= ~(TOUCH_X1|TOUCH_X2); // Set x1 to output 1,set x2 to output 0
*P_ADC_AINPUT_CTRL |= (TOUCH_Y1|TOUCH_Y2); // Set y1 and y2 as ADC input
*P_ADC_MIC_CTRL1 &= ~0x000F;
*P_ADC_MIC_CTRL1 |= TOUCH_Y1_BIT;
*P_ADC_INT_STATUS |= C_ADC_MANUAL_START;
*P_INT_MASK_CTRL1 &= ~C_INT_ADC_DIS;
}
//==========================================================================================================================
//Prototype: void Touch_SetBound(unsigned short left, unsigned short right, unsigned short top, unsigned short bottom);
//Description: Set the AD converted value for the four boundaries to calibrate touch panel
//Argument: left: AD converted value for the left bound (16-bit)
// right: AD converted value for the right bound(16-bit)
// top: AD converted value for the top bound(16-bit)
// bottom: AD converted value for the bottom bound(16-bit)
//Return Value: None
//==========================================================================================================================
void Touch_SetBound(unsigned short left, unsigned short right, unsigned short top, unsigned short bottom)
{
LeftBound = left;
RightBound = right;
TopBound = top;
BottomBound = bottom;
}
//=============================================================
//Prototype: void Touch_ADC_ISR(void)
//Description: ADC ISR
//Argument: None
//Return Value: None
//=============================================================
void Touch_ADC_ISR(void)
{
short TempX, TempY;
if(ADC_Counter<16) // Sample 16 times in x direction
{
TempADCx += (*P_ADC_MANUAL_DATA>>16);
ADC_Counter += 1;
if(ADC_Counter==16) // Change to the Y direction
{
*P_ADC_GPIO_SETUP &= ~((TOUCH_X1<<8)|(TOUCH_X2<<8));
*P_ADC_GPIO_SETUP |= (TOUCH_Y1<<8)|(TOUCH_Y2<<8);
*P_ADC_AINPUT_CTRL &= ~(TOUCH_Y1|TOUCH_Y2); // Set y2 to output 1, set y1 to output 0
*P_ADC_AINPUT_CTRL |= (TOUCH_X1|TOUCH_X2); // Set x2 as ADC input
*P_ADC_MIC_CTRL1 &= ~0x000F;
*P_ADC_MIC_CTRL1 |= TOUCH_X2_BIT;
}
}
else if(ADC_Counter<24) // Delete the AD converted values for 8 times
{
ADC_Counter += 1;
}
else if(ADC_Counter<40) // Sample 16 times in Y direction
{
TempADCy +=(*P_ADC_MANUAL_DATA>>16);
ADC_Counter += 1;
if(ADC_Counter == 40)
{
*P_ADC_GPIO_SETUP &= ~((TOUCH_Y1<<8)|(TOUCH_Y2<<8));
*P_ADC_GPIO_SETUP |= (TOUCH_X1<<8)|(TOUCH_X2<<8);
*P_ADC_AINPUT_CTRL &= ~(TOUCH_X1|TOUCH_X2); // Set x1 to output 1, set x2 to output 0
*P_ADC_AINPUT_CTRL |= (TOUCH_Y1|TOUCH_Y2); // Set y1 as ADC input
*P_ADC_MIC_CTRL1 &= ~0x000F;
*P_ADC_MIC_CTRL1 |= TOUCH_Y1_BIT;
TempADCx >>= 4; // Average 16 samples
TempADCy >>= 4;
if( TempADCx<TOUCH_DEFAULT_LB // If sampled data is out of the range of four boundaries
|| TempADCx>TOUCH_DEFAULT_RB
|| TempADCy<TOUCH_DEFAULT_TB
|| TempADCy>TOUCH_DEFAULT_BB
)
{
if(DebounceX==-1 && DebounceY==-1) // Debounce
{
Debounce_Counter += 1;
if(Debounce_Counter==TOUCH_DEBOUNCE_TIME)
{
ResultX = -1;
ResultY = -1;
Debounce_Counter = 0;
}
}
DebounceX = -1;
DebounceY = -1;
TempX = TempY = -1; // Invalid coordinates
}
else // The sample results are in the four bounds.
{
TempX = TOUCH_WIDTH * (TempADCx - TOUCH_DEFAULT_LB) / (TOUCH_DEFAULT_RB - TOUCH_DEFAULT_LB);
TempY = TOUCH_HEIGHT * (TempADCy - TOUCH_DEFAULT_TB) / (TOUCH_DEFAULT_BB - TOUCH_DEFAULT_TB);
}
if(TempX != -1) // Update the coordinates
{
if( TempX-DebounceX<TOUCH_DEBOUNCE_PIXEL // Debounce, wait for the coordinates to be stable, and then save the result
&& TempX-DebounceX>-TOUCH_DEBOUNCE_PIXEL
&& TempY-DebounceY<TOUCH_DEBOUNCE_PIXEL
&& TempY-DebounceY>-TOUCH_DEBOUNCE_PIXEL
)
{
Debounce_Counter += 1;
if(Debounce_Counter==TOUCH_DEBOUNCE_TIME)
{
ResultX = (TempX + DebounceX)>>1; // Save the coordinates
ResultY = (TempY + DebounceY)>>1;
DebounceX = ResultX;
DebounceY = ResultY;
Debounce_Counter = 0;
}
}
else
{
DebounceX = TempX;
DebounceY = TempY;
Debounce_Counter = 0;
}
}
TempADCx = 0;
TempADCy = 0;
}
}
else // Delete the AD converted values for 8 times
{
ADC_Counter += 1;
if(ADC_Counter==64)
ADC_Counter = 0;
}
*P_ADC_INT_STATUS |= C_ADC_MANUAL_FLAG; // Clear interrupt
*P_ADC_INT_STATUS |= C_ADC_MANUAL_START;
}
///=============================================================
//Prototype: void Touch_ADC_ISR(void)
//Description: ADC interrupt sevice subroutine
//Argument: None
//Return Value: None
//=============================================================
short Touch_Get(short *x, short *y)
{
*x = ResultX;
*y = ResultY;
if(ResultX == -1)
return -1;
else
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -