|
楼主 |
发表于 2014-8-11 16:23:25
|
显示全部楼层
回 eric2013 的帖子
eric2013:1. 把你的界面程序贴出来看下。
2. 触摸滤波看我60期emWin教程即可。 (2014-07-29 17:58)  界面都好了,就是触摸问题了,就是依次按下面板上某个矩形区域边框ABCD的斜对角两点A,C,那么第三个点B或者D位置也会被按下,不知道是不是飞点的原因,第一次弄这个,没经验啊,还望高手指点!!!附上触摸程序(程序比较乱--海涵啊)
#define XSIZE_PHYS 800 //wind
#define YSIZE_PHYS 480
//
// Virtual display size
//
#define VXSIZE_PHYS (XSIZE_PHYS)
#define VYSIZE_PHYS (YSIZE_PHYS)
//
// Color conversion
//
#define COLOR_CONVERSION GUICC_M565
//
// Pixel width in bytes
//
#define PIXEL_WIDTH 2
//
// Display driver//
//
//#define DISPLAY_DRIVER &GUIDRV_Lin_OSX_16_API//竖屏
#define DISPLAY_DRIVER &GUIDRV_Lin_16_API//横屏
//
// Video RAM address
//
#define VRAM_ADDR_PHYS (U32)&_aVRAM[0]
//
// Touch controller settings
#define TOUCH_AD_RIGHT 98
#define TOUCH_AD_LEFT 3980
#define TOUCH_AD_TOP 3920
#define TOUCH_AD_BOTTOM 105
#define TOUCH_TIMER_INTERVAL 10
/*********************************************************************
*
* Configuration checking
*
**********************************************************************
*/
#ifndef VXSIZE_PHYS
#define VXSIZE_PHYS XSIZE_PHYS
#endif
#ifndef VYSIZE_PHYS
#define VYSIZE_PHYS YSIZE_PHYS
#endif
#ifndef VRAM_ADDR_PHYS
#define VRAM_ADDR_PHYS 0
#endif
#ifndef VRAM_ADDR_VIRT
#define VRAM_ADDR_VIRT 0
#endif
#ifndef XSIZE_PHYS
#error Physical X size of display is not defined!
#endif
#ifndef YSIZE_PHYS
#error Physical Y size of display is not defined!
#endif
#ifndef COLOR_CONVERSION
#error Color conversion not defined!
#endif
#ifndef DISPLAY_DRIVER
#error No display driver defined!
#endif
/*********************************************************************
*
* Defines
*
**********************************************************************
*/
//
// LCDC configuration
//
#define PPL 800 // Pixels per line
#define HSW 48 // HSYNC pulse width
#define HFP 40 // Horizontal front porch
#define HBP 40 // Horizontal back porch
#define LPP 480 // Lines per panel
#define VSW 3 // VSYNC pulse width
#define VFP 13 // Vertical front porch
#define VBP 28 // Vertical back porch
#define ACB 1 // AC bias frequency (not used)
#define IVS 1 // Invert VSYNC
#define IHS 1 // Invert HSYNC
#define IPC 1 // Invert panel clock
#define CPL 800 // Clock per line (identical to pixels per line)
#define BPP 6 // Bits per pixel b110 = 16 bpp 5:6:5 mode
#define BGR 1 // Swap red and blue
#define LCDTFT 1 // LCD TFT panel
#define OPT_CLK 8200000 // Optimal clock rate (Hz) between 1-8.22 MHz according to SSD1289 datasheet */
#define BCD_BIT 26 // Bypass pixel clock divider
#define LCD_BACKLIGHT_BIT 18 // P1.18
#define LCD_REG_BIT 19 // P0.19
#define LCD_DATA() (LPC_GPIO0->SET = (1 << LCD_REG_BIT))
#define LCD_CMD() (LPC_GPIO0->CLR = (1 << LCD_REG_BIT))
//
// SSP
//
#define SSPSR_TNF (1 << 1) // Transmit FIFO not full
#define SSPSR_RNE (1 << 2) // Receive FIFO not empty
#define SSPSR_BSY (1 << 4) // Busy
//#define SSP_CLOCK 3000000
#define SSP_CLOCK 120000
#define SSP_FIFO_SIZE 8
#define SSP_MODE_LCD 0
#define SSP_MODE_TS 1
//
// Touch screen
//
#define TOUCH_CS_BIT 23
#define TS_CS_SET() LPC_GPIO2->CLR = (1 << TOUCH_CS_BIT)
#define TS_CS_CLR() LPC_GPIO2->SET = (1 << TOUCH_CS_BIT)
#define ADS_START (1 << 7)
#define ADS_A2A1A0_d_y (1 << 4) // Differential
#define ADS_A2A1A0_d_z1 (3 << 4) // Differential
#define ADS_A2A1A0_d_z2 (4 << 4) // Differential
#define ADS_A2A1A0_d_x (5 << 4) // Differential
#define ADS_A2A1A0_vaux (6 << 4) // Non-differential
#define ADS_12_BIT (0 << 3)
#define ADS_SER (1 << 2) // Non-differential
#define ADS_DFR (0 << 2) // Differential
#define ADS_PD10_ADC_ON (1 << 0) // ADC on
#define ADS_PD10_REF_ON (2 << 0) // vREF on + penirq
#define ADS_PD10_ALL_ON (3 << 0) // ADC + vREF on
#define READ_12BIT_DFR(D, ADC, VREF) (ADS_START | \\
D | \\
ADS_12_BIT | \\
ADS_DFR | \\
(ADC ? ADS_PD10_ADC_ON : 0) | \\
(VREF ? ADS_PD10_REF_ON : 0))
#define READ_12BIT_SER(x) (ADS_START | /* Single-ended samples need to power */ \\
x | /* up reference voltage first; therefor */ \\
ADS_12_BIT | /* we leave both VREF and ADC powered. */ \\
ADS_SER)
#define REF_ON (READ_12BIT_DFR(ADS_A2A1A0_d_x, 1, 1))
#define READ_Y(VREF) (READ_12BIT_DFR(ADS_A2A1A0_d_y, 1, VREF))
#define READ_Z1(VREF) (READ_12BIT_DFR(ADS_A2A1A0_d_z1, 1, VREF))
#define READ_Z2(VREF) (READ_12BIT_DFR(ADS_A2A1A0_d_z2, 1, VREF))
#define READ_X(VREF) (READ_12BIT_DFR(ADS_A2A1A0_d_x, 1, VREF))
#define PWRDOWN (READ_12BIT_DFR(ADS_A2A1A0_d_y, 0, 0))//PWRDOWN=0X00000082
#define TS_DEBOUNCE_MAX 10
#define TS_DEBOUNCE_TOL 2
#ifndef ABS
#define ABS(x) (((int32_t)(x)) < 0 ? (-x) : (x))
#endif
/*********************************************************************
*
* Defines, sfrs
*
**********************************************************************
*/
#define MATRIX_ARB (*(volatile U32*)(0x400FC188))
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
//
// Video RAM
//
#ifdef __ICCARM__
#pragma data_alignment=8 // 8 byte align frame buffer to be on the safe side (some display controllers need this)
#pragma location="VRAM"
static __no_init U32 _aVRAM[VXSIZE_PHYS * VYSIZE_PHYS / (4 / PIXEL_WIDTH)];//一帧图片所用RAM
#endif
#ifdef __CC_ARM //一帧图片所用RAM
U32 static _aVRAM[VXSIZE_PHYS * VYSIZE_PHYS / (4 / PIXEL_WIDTH)] __attribute__ ((section ("VRAM"), zero_init));
#endif
#if GUI_SUPPORT_TOUCH // Used when touch screen support is enabled
//
// Touch screen results
//
static int _TouchX;
static int _TouchY;
static U8 _PenIsDown;
typedef struct
{
uint16_t XYChange; /* X, Y 是否交换 */
uint16_t usMaxAdc; /* 触摸板最大ADC值,用于有效点判断. 最小ADC = 0 */
int16_t _TouchX;
int16_t _TouchY;
uint8_t Enable; /* 触摸检测使能标志 */
}TOUCH_T;
TOUCH_T g_tTP;
#endif
/*********************************************************************
*
* _SetDisplayOrigin()
*/
static void _SetDisplayOrigin(int x, int y) {
(void)x;
//
// Set start address for display data and enable LCD controller
//
LPC_LCD->UPBASE = VRAM_ADDR_PHYS + (y * YSIZE_PHYS * PIXEL_WIDTH); // Needs to be set, before LCDC is enabled
}
/*********************************************************************
*
* _FindClockDivisor
*
* Function description:
* Find closest clock divider to get the desired clock rate.
*/
static U32 _FindClockDivisor(U32 TargetClock) {
U32 Divider;
U32 r;
Divider = 1;
while (((SystemCoreClock / Divider) > TargetClock) && (Divider <= 0x3F)) {
Divider++;
}
if (Divider <= 1) {
r = (1 << BCD_BIT); // Skip divider logic if clock divider is 1
} else {
//
// Use found divider
//
Divider -= 2;
r = 0
| (((Divider >> 0) & 0x1F)
| (((Divider >> 5) & 0x1F) << 27))
;
}
return r;
}
/*********************************************************************
*
* _InitLcdControllerDisabled
*
* Function description:
* Initializes the port pins as needed and initializes the LCD
* controller but leaves it disabled.
*/
static void _InitLcdControllerDisabled(void) {
U32 i;
MATRIX_ARB = 0 // Set AHB Matrix priorities [0..3] with 3 being highest priority
| (1 << 0) // PRI_ICODE : I-Code bus priority. Should be lower than PRI_DCODE for proper operation.
| (2 << 2) // PRI_DCODE : D-Code bus priority.
| (0 << 4) // PRI_SYS : System bus priority.
| (0 << 6) // PRI_GPDMA : General Purpose DMA controller priority.
| (0 << 8) // PRI_ETH : Ethernet: DMA priority.
| (3 << 10) // PRI_LCD : LCD DMA priority.
| (0 << 12) // PRI_USB : USB DMA priority.
;
//
// Init port pins
//
LPC_IOCON->2_12 = 0x25; // LCD_VD_3
LPC_IOCON->2_6 = 0x27; // LCD_VD_4
LPC_IOCON->2_7 = 0x27; // LCD_VD_5
LPC_IOCON->2_8 = 0x27; // LCD_VD_6
LPC_IOCON->4_29 = 0x25; // LCD_VD_7
/* G */
LPC_IOCON->1_20 = 0x27; // LCD_VD_10
LPC_IOCON->1_21 = 0x27; // LCD_VD_11
LPC_IOCON->1_22 = 0x27; // LCD_VD_12
LPC_IOCON->1_23 = 0x27; // LCD_VD_13
LPC_IOCON->1_24 = 0x27; // LCD_VD_14
LPC_IOCON->P1_25 = 0x27; // LCD_VD_15
/* B */
LPC_IOCON->P2_13 = 0x27; // LCD_VD_19
LPC_IOCON->P1_26 = 0x27; // LCD_VD_20
LPC_IOCON->P1_27 = 0x27; // LCD_VD_21
LPC_IOCON->P1_28 = 0x27; // LCD_VD_22
LPC_IOCON->P1_29 = 0x27; // LCD_VD_23
LPC_GPIO4->DIR |= 1<<22;
LPC_GPIO4->SET |= 1<<22;
LPC_GPIO0->DIR |= 1<<18;
LPC_GPIO0->CLR |= 1<<18; //CLR
LPC_IOCON->P2_2 = 7; // LCD_DCLK
LPC_IOCON->P2_3 = 7; // LCD_FP
LPC_IOCON->P2_4 = 7; // LCD_ENAB_M
LPC_IOCON->P2_5 = 7; // LCD_LP
LPC_GPIO1->DIR |= (1 << LCD_BACKLIGHT_BIT);
LPC_GPIO1->CLR |= (1 << LCD_BACKLIGHT_BIT); // Initially set backlight to off
//
// Init LCDC wind
//
LPC_SC->PCONP |= (1UL << 0); // Power the LCDC
LPC_LCD->CTRL &= ~(1UL << 0); // Disable the LCDC
LPC_LCD->TIMH = 0 // Configure horizontal axis
| (((PPL / 16) - 1) << 2)
| ((HSW - 1) << 8)
| ((HFP - 1) << 16)
| ((HBP - 1) << 24)
;
LPC_LCD->TIMV = 0 // Configure vertical axis
| ((LPP - 1) << 0)
| ((VSW - 1) << 10)
| ((VFP) << 16)
| ((VBP) << 24)
;
#if 0
LPC_LCD->POL = 0 // Configure clock and signal polarity
| (_FindClockDivisor(OPT_CLK) << 0)
| ((ACB - 1) << 6)
| ((IVS) << 11)
| ((IHS) << 12)
| ((IPC) << 13)
| ((CPL - 1) << 16)
;
#endif
#if 1
LPC_LCD->POL = (1 << 26) | /* 旁路时钟分频器r */
((CPL-1) << 16) | /* 每行320个时钟脉冲 */
(0 << 14) | /* LCDENAB 输出高电平有效 */
(1 << 13) | /* 数据在LCDDCLK的下降沿输出 */
(1 << 12) | /* HSYNC 低电平有效 */
(1 << 11) | /* VSYNC 低电平有效 */
(0 << 5); /* 选择 HCLK */
#endif
LPC_LCD->CTRL = 0 // Configure operating mode and panel parameters
| (BPP << 1)
| (BGR << 8)
| (LCDTFT << 5)
;
for (i = 0; i < SEGGER_COUNTOF(LPC_LCD->PAL); i++) {
LPC_LCD->PAL = 0; // Clear the color palette with black
}
// LPC_SC->LCD_CFG = 0x0; // No panel clock prescaler
LPC_SC->LCD_CFG = 0x4; // No panel clock prescaler
//LPC_SC->LCD_CFG = 0x13; // No panel clock prescaler
// LPC_LCD->CTRL |= (1 << 11); /* 使能数据输出 */
}
/*********************************************************************
*
* _EnableLcdController
*
* Function description:
* Enables the LCD controller, backlight and sets the frame buffer.
*/
static void _EnableLcdController(void) {
LPC_LCD->UPBASE = VRAM_ADDR_PHYS;
LPC_LCD->LPBASE = VRAM_ADDR_PHYS;
LPC_LCD->CTRL |= (1 << 0); // Enable LCD signals
LPC_LCD->CTRL |= (1 << 11); // Enable LCD power
LPC_GPIO1->SET |= (1 << LCD_BACKLIGHT_BIT); // Set backlight to on
}
/*********************************************************************
*
* _GetSspDividers
*
* Function description:
* Find best SSP dividers for the desired clock rate.
*/
static void _GetSspDividers(U32 TargetClock, U8* Scr, U8* Cpsr) {
U16 tScr = 1;
U8 tCpsr = 2;
U32 Clock = PeripheralClock;
while (Clock > TargetClock) {
Clock = PeripheralClock / ((tScr + 1) * tCpsr);
if (Clock > TargetClock) {
tScr++;
if (tScr > 0xFF) {
tScr = 0;
tCpsr += 2;
}
}
}
*Scr = (U8)tScr;
*Cpsr = tCpsr;
}
/*********************************************************************
*
* _InitSSP
*
* Function description:
* Initialize the SSP interface. Used to configure Truly LCD display
* controller IC on Embedded Artists QVGA Base Board.
*/
static void _InitSSP(U8 Mode) {
U8 Cpsr;
U8 Scr;
U8 i;
volatile U32 v;
//
// Init ports
//
// LPC_IOCON->P2_11 = 1;
// LPC_GPIO2->DIR &= ~(1uL << 11);
LPC_IOCON->P2_22 = 2; // SSP0_SCK
//LPC_IOCON->P2_23 = 2; // SSP0_SSEL
LPC_IOCON->P2_23 = 0; // SSP0_SSEL
LPC_IOCON->P2_26 = 2; // SSP0_MISO
LPC_IOCON->P2_27 = 2; // SSP0_MOSI
//
// Init SSP parameters
//
_GetSspDividers(SSP_CLOCK, &Scr, &Cpsr);
v = 0
| (7 << 0) // DSS : 8-bit transfer
| (0 << 4) // FRF : Frame Format -> 0 = SPI
| (Scr << 8) // SCR : Serial Clock Rate
;
if (Mode == SSP_MODE_LCD) {
v |= 0
| (0 << 6) // CPOL: Clock out polarity
| (0 << 7) // CPHA: Clock out phase
;
} else if (Mode == SSP_MODE_TS) {
v |= 0
| (1 << 6) // CPOL: Clock out polarity
| (1 << 7) // CPHA: Clock out phase
;
}
LPC_SSP0->CR0 = v;
LPC_SSP0->CPSR = Cpsr; // CPSR: Clock prescale register, master mode, minimum divisor is 0x02
for (i = 0; i < SSP_FIFO_SIZE; i++) {
v = LPC_SSP0->DR; // Clear the RxFIFO
}
LPC_SSP0->CR1 = 0
| (1 << 1) // SSE : Enable SSP
| (0 << 2) // MS : Master mode
;
}
/*********************************************************************
*
* _SSP_Send
*
* Function description:
* Sends data via the SSP0 interface. Used to configure Truly LCD
* display controller IC on Embedded Artists QVGA Base Board.
*/
static void _SSP_Send(U8* pData, U32 NumBytes) {
volatile U8 Dummy;
do {
//
// Wait for not busy and TX FIFO not full
//
while ((LPC_SSP0->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF);
//
// Send next byte
//
LPC_SSP0->DR = *pData;
pData++;
//
// Whenever a byte is written, MISO FIFO counter is incremented.
// Therefor we have to clear the byte from FIFO as otherwise we would
// get old data on next read.
//
while ((LPC_SSP0->SR & (SSPSR_BSY|SSPSR_RNE)) != SSPSR_RNE);
Dummy = LPC_SSP0->DR;
}
while (--NumBytes);
}
/*********************************************************************
*
* _WriteLcdReg
*
* Function description:
* Write to display register. Used to configure Truly LCD display
* controller IC on Embedded Artists QVGA Base Board.
*/
static void _WriteLcdReg(U16 Addr, U16 Data) {
U8 Buffer[2];
LCD_CMD();
Buffer[0] = 0;
Buffer[1] = Addr & 0xFF;
_SSP_Send(Buffer, 2);
LCD_DATA();
Buffer[0] = Data >> 8;
Buffer[1] = Data & 0xFF;
_SSP_Send(Buffer, 2);
LCD_CMD();
Buffer[0] = 0;
Buffer[1] = 0x22;
_SSP_Send(Buffer, 2);
}
/*********************************************************************
*
* _DelayMs
*
* Function description:
* Starts a timer and waits for the given delay in ms.
*/
static void _DelayMs(U32 ms) {
LPC_TIM0->TCR = 0x02; // Reset timer计数器被禁能,定时计数器和预分频计数器在pclk的下一个正向沿同步复位
LPC_TIM0->PR = 0x00; // Set prescaler to zero定时器每个pclk周期加一
LPC_TIM0->MR0 = ms * (SystemCoreClock / (LPC_SC->PCLKSEL & 0x1F) / 1000 - 1);
LPC_TIM0->IR = 0xFF; // Reset all interrrupts
LPC_TIM0->MCR = 0x04; // Stop timer on match MR1与TC值匹配将产生中断
LPC_TIM0->TCR = 0x01; // Start timer定时计数器和预分频计数器使能计数
//
// Wait until delay time has elapsed
//
while (LPC_TIM0->TCR & 1);
}
/*********************************************************************
*
* _InitTrulyLCD
*
* Function description:
* Initialize the LCD display. Used to configure Truly LCD display
* controller IC on Embedded Artists QVGA Base Board.
*/
static void _InitTrulyLCD(void) {
//
// Power LCD
//
LPC_GPIO2->DIR |= 1; // Set to output
LPC_GPIO2->SET = 1; // Output LCD power
//
// Set display CMD/DATA register select pin to output high
//
LPC_GPIO0->DIR |= (1 << LCD_REG_BIT);
//
// Display init sequence
//
_WriteLcdReg(0x00,0x0001);
_DelayMs(15 * 2);
_WriteLcdReg(0x03,0x6E3E); // AAAC
_WriteLcdReg(0x0C,0x0007); // 0002
_WriteLcdReg(0x0D,0x000E); // 000A
_WriteLcdReg(0x0E,0x2C00); // 2C00
_WriteLcdReg(0x1E,0x00AE); // 00B8
_DelayMs(15 * 2);
_WriteLcdReg(0x07,0x0021);
_DelayMs(50 * 2);
_WriteLcdReg(0x07,0x0023);
_DelayMs(50 * 2);
_WriteLcdReg(0x07,0x0033);
_DelayMs(50 * 2);
_WriteLcdReg(0x01,0x2B3F);
_WriteLcdReg(0x02,0x0600);
_WriteLcdReg(0x10,0x0000);
_DelayMs(15 * 2);
_WriteLcdReg(0x11,0xC5B0); // 60B0: RGB I/R
_DelayMs(20 * 2);
_WriteLcdReg(0x15,0x00D0);
_WriteLcdReg(0x05,0x0000);
_WriteLcdReg(0x06,0x0000);
_WriteLcdReg(0x16,0xEF1C);
_WriteLcdReg(0x17,0x0003);
_WriteLcdReg(0x07,0x0233);
_WriteLcdReg(0x0B,0x5310);
_WriteLcdReg(0x0F,0x0000);
_WriteLcdReg(0x25,0xE000);
_DelayMs(20 * 2);
_WriteLcdReg(0x41,0x0000);
_WriteLcdReg(0x42,0x0000);
_WriteLcdReg(0x48,0x0000);
_WriteLcdReg(0x49,0x013F);
_WriteLcdReg(0x44,0xEF00);
_WriteLcdReg(0x45,0x0000);
_WriteLcdReg(0x46,0x013F);
_WriteLcdReg(0x4A,0x0000);
_WriteLcdReg(0x4B,0x0000);
_DelayMs(20 * 2);
_WriteLcdReg(0x30,0x0707);
_WriteLcdReg(0x31,0x0600); // 0704
_WriteLcdReg(0x32,0x0005); // 0204
_WriteLcdReg(0x33,0x0402); // 0201
_WriteLcdReg(0x34,0x0203);
_WriteLcdReg(0x35,0x0204);
_WriteLcdReg(0x36,0x0204);
_WriteLcdReg(0x37,0x0401); // 0502
_WriteLcdReg(0x3A,0x0302);
_WriteLcdReg(0x3B,0x0500);
_DelayMs(20 * 2);
_WriteLcdReg(0x22,0x0000);
_DelayMs(20 * 2);
}
/*********************************************************************
*
* _InitLCD
*
* Function description:
* Sets LCD configuration and initializes the LCD.
*/
static void _InitLCD(unsigned LayerIndex) {
//
// Set display size and video-RAM address
//
LCD_SetSizeEx (XSIZE_PHYS, YSIZE_PHYS, LayerIndex);
LCD_SetVSizeEx(VXSIZE_PHYS, VYSIZE_PHYS, LayerIndex);
LCD_SetVRAMAddrEx(LayerIndex, (void*)VRAM_ADDR_PHYS);
//
// Init LCD
//
_InitSSP(SSP_MODE_LCD);
_InitLcdControllerDisabled();
_InitTrulyLCD();
_EnableLcdController();
}
#if GUI_SUPPORT_TOUCH // Used when touch screen support is enabled
/*********************************************************************
*
* _SSP_Recv
*
* Function description:
* Sends data via the SSP0 interface. Used to configure Truly LCD
* display controller IC on Embedded Artists QVGA Base Board.
*/
static void _SSP_Recv(U8* pData, U32 NumBytes) {
do {
LPC_SSP0->DR = 0xFF; // Using peer-to-peer communication, SSPDR has to be written to receive data
while ((LPC_SSP0->SR & (SSPSR_BSY | SSPSR_RNE)) != SSPSR_RNE); // Wait for not busy and receive buffer not empty
*pData++ = LPC_SSP0->DR;
} while (--NumBytes);
}
/*********************************************************************
*
* _SSP_SendCmd
*
* Function description:
* Sends a cmd via the SSP0 interface and returns the answer.
* Used to configure Truly LCD display controller IC on
* Embedded Artists QVGA Base Board.
*/
static U16 _SSP_SendCmd(U8 Cmd) {
U8 v[2];
v[0] = Cmd;
TS_CS_SET();
_SSP_Send(v, 1);
_SSP_Recv(v, 2);
TS_CS_CLR();
return ((v[0] << 8) | v[1]);
}
/*********************************************************************
*
* _CheckUpdateTouch
*
* Function description:
* Reads touch values from ADC on Truly LCD display
* controller IC on Embedded Artists QVGA Base Board.
* Checks if a touch event has occurred. If we found an event the
* static variables for x and y will be filled with new values that
* can be processed via GUI touch routines.
*
* Return value:
* 0 No touch event, x, y have not been updated
* != 0 Touch event occurred, x, y have been updated and return value is read z value
*/
static int _CheckUpdateTouch(void)
{ int z;
int LastZ1;
int LastZ2;
int LastX;
LastX = _SSP_SendCmd(READ_X(0));
LastX >>= 3;
LastZ1 = _SSP_SendCmd(READ_Z1(0));
LastZ1 >>= 3;
LastZ2 = _SSP_SendCmd(READ_Z2(0));
LastZ2 >>= 3;
z = (LastX * LastZ2 - LastZ1) / LastZ1;
if ((z > 40000) || (z == 0))
{
return 0; // No update
}
return z;
}
/*********************************************************************
*
* _InitTouch
*
* Function description:
* Initializes the touch screen.
*/
static void _InitTouch(void) {
U32 TouchOrientation;
U8 Config[3];
U32 pclk;
//
// Init ports and SSP interface as needed for touch
//
LPC_GPIO2->DIR |= (1 << TOUCH_CS_BIT); // P0.20 as output (touch controller CS)
_InitSSP(SSP_MODE_TS);
Config[0] = REF_ON;
Config[1] = (READ_12BIT_SER(ADS_A2A1A0_vaux) | ADS_PD10_ALL_ON);
Config[2] = PWRDOWN;
TS_CS_SET();
_SSP_Send(Config, 3);
TS_CS_CLR();
//----------------------------触屏方向----------------------
// TouchOrientation = GUI_MIRROR_X | GUI_SWAP_XY ;//竖屏
TouchOrientation = 0 ;//横屏
//GUI_TOUCH_SetOrientation(TouchOrientation);//设置触屏方向
GUI_TOUCH_Calibrate(GUI_COORD_X, 0, XSIZE_PHYS, TOUCH_AD_LEFT, TOUCH_AD_RIGHT);
GUI_TOUCH_Calibrate(GUI_COORD_Y, 0, YSIZE_PHYS, TOUCH_AD_TOP , TOUCH_AD_BOTTOM);
//
// Start touch timer
//
LPC_SC->PCONP |= (0x1<<2);//复位定时器0和1
pclk = SystemCoreClock/4;
LPC_TIM1->PR = pclk/1000000; /* Set prescaler to get 1 M counts/sec */
LPC_TIM1->MR0 = 1000 * TOUCH_TIMER_INTERVAL;
LPC_TIM1->MCR = (0x3<<0); /* Interrupt and Reset on MR0 */
NVIC_EnableIRQ(TIMER1_IRQn);
LPC_TIM1->TCR = 1; /* Enable timer 1 */
}
#endif // GUI_SUPPORT_TOUCH
/*********************************************************************
*
* _InitController
*
* Function description:
* Initializes the LCD controller and touch screen
*
*/
static void _InitController(unsigned LayerIndex) {
_InitLCD(LayerIndex);
#if GUI_SUPPORT_TOUCH // Used when touch screen support is enabled没变
_InitTouch();
#endif
}
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* LCD_X_Config//没变
*
* Purpose:
* Called during the initialization process in order to set up the
* display driver configuration.
*/
void LCD_X_Config(void) {
//
// Set display driver and color conversion for 1st layer
//
GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER, COLOR_CONVERSION, 0, 0);
//
// Display driver configuration, required for Lin-driver
//
LCD_SetPosEx (0, 0, 0);
if (LCD_GetSwapXYEx(0)) {
LCD_SetSizeEx (0, YSIZE_PHYS , XSIZE_PHYS);
LCD_SetVSizeEx (0, VYSIZE_PHYS, VXSIZE_PHYS);
} else {
LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);
LCD_SetVSizeEx (0, VXSIZE_PHYS, VYSIZE_PHYS);
}
LCD_SetVRAMAddrEx(0, (void*)VRAM_ADDR_VIRT);
//
// Set user palette data (only required if no fixed palette is used)
//
#if defined(PALETTE)
LCD_SetLUTEx(0, PALETTE);
#endif
}
/*********************************************************************
*
* LCD_X_DisplayDriver
*
* Purpose:
* This function is called by the display driver for several purposes.
* To support the according task the routine needs to be adapted to
* the display controller. Please note that the commands marked with
* 'optional' are not cogently required and should only be adapted if
* the display controller supports these features.
*
* Parameter:
* LayerIndex - Index of layer to be configured
* Cmd - Please refer to the details in the switch statement below
* pData - Pointer to a LCD_X_DATA structure
*
* Return Value:
* < -1 - Error
* -1 - Command not handled
* 0 - Ok
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
int r;
LCD_X_SETORG_INFO * pSetOrg;
(void) LayerIndex;
switch (Cmd) {
//
// Required
//
case LCD_X_INITCONTROLLER:
//
// Called during the initialization process in order to set up the
// display controller and put it into operation. If the display
// controller is not initialized by any external routine this needs
// to be adapted by the customer...
//
// ...
_InitController(0);
return 0;
case LCD_X_SETORG:
//
// Required for setting the display origin which is passed in the 'xPos' and 'yPos' element of p
//
pSetOrg = (LCD_X_SETORG_INFO *)pData;
_SetDisplayOrigin(pSetOrg->xPos, pSetOrg->yPos);
return 0;
default:
r = -1;
}
return r;
}
/*********************************************************************
*
* Global functions for GUI touch
*
**********************************************************************
*/
uint16_t TOUCH_DataFilter(U8 Cmd)
{
uint16_t i, j;
uint16_t buf[5];
uint16_t usSum;
uint16_t usTemp;
/* 读取READ_TIMES次数据*/
for(i=0; i < 5; i++)
{
buf = _SSP_SendCmd(Cmd);
buf >>= 3;
}
/* 升序排列 */
for(i = 0; i < 5 - 1; i++)
{
for(j = i + 1; j < 5; j++)
{
if(buf > buf[j])
{
usTemp = buf;
buf = buf[j];
buf[j] = usTemp;
}
}
}
usSum = 0;
/*求和 */
for(i = 1; i < 5 - 1; i++)
{
usSum += buf;
}
/*求平均 */
usTemp = usSum / (5 - 2 * 1);
return usTemp;
}
int32_t TOUCH_Abs(int32_t x)
{
if (x >= 0)
{
return x;
}
else
{
return -x;
}
}
static void _ExecTouch(void);
static void _ExecTouch(void)
{
uint8_t s_invalid_count = 0;
int HasUpdate;
GUI_PID_STATE State;
HasUpdate = _CheckUpdateTouch();
//_SSP_SendCmd(PWRDOWN);
if (HasUpdate) {
_PenIsDown = 1;
GUI_TOUCH_Exec();//此函数调用GUI_TOUCH_X_ActivateX(),GUI_TOUCH_X_ActivateY(),GUI_TOUCH_X_MeasureX(),GUI_TOUCH_X_MeasureY()这四个函数
} else if (_PenIsDown) {
//
// No further touch event after at least one touch event means we have
// lift the pen from the touch screen which means a click.
//
_PenIsDown = 0;
GUI_PID_GetState(&State);
State.Pressed = 0;
GUI_PID_StoreState(&State);
}
}
#if GUI_SUPPORT_TOUCH // Used when touch screen support is enabled
void GUI_TOUCH_X_ActivateX(void)
{
// TOUCH_ReadAdcXY(_TouchX, 0);
uint16_t iX1;
uint16_t iX2;
uint16_t iX;
iX1 = TOUCH_DataFilter(READ_X(0));
iX2 = TOUCH_DataFilter(READ_X(0));
iX = TOUCH_Abs(iX1 - iX2);
/* 前后两次采样在+-ERR_RANGE内 */
if (iX <= 5)
{ _TouchX = (iX1 + iX2) / 2;
}
//_TouchX=TOUCH_DataFilter(READ_X(0));
}
//
//
void GUI_TOUCH_X_ActivateY(void)
{
uint16_t iY1;
uint16_t iY2;
uint16_t iY;
iY1 = TOUCH_DataFilter(READ_Y(0));
iY2 = TOUCH_DataFilter(READ_Y(0));
iY = TOUCH_Abs(iY1 - iY2);
/* 前后两次采样在+-ERR_RANGE内 */
if (iY <= 5)
{ _TouchY = (iY1 + iY2) / 2;
}
//_TouchX=TOUCH_DataFilter(READ_X(0));
// TOUCH_ReadAdcXY(0, _TouchY);
//_TouchY=TOUCH_DataFilter(READ_Y(0));
}
/*********************************************************************
*
* GUI_TOUCH_X_MeasureX()返回A/D转换器的x轴测量结果
*
* Function decription:
* Called from GUI, if touch support is enabled.
* Measures voltage of X-axis.
*/
int GUI_TOUCH_X_MeasureX(void) {
// _ExecTouch();
// return(g_tTP._TouchX);
return _TouchY;
}
/*********************************************************************
*
* GUI_TOUCH_X_MeasureY()返回A/D转换器的Y轴测量结果
*
* Function decription:
* Called from GUI, if touch support is enabled.
* Measures voltage of Y-axis.
*/
int GUI_TOUCH_X_MeasureY(void) {
// return(g_tTP._TouchY);
return _TouchX;
}
#endif // GUI_SUPPORT_TOUCH
//------------------------l滤波test----------------------
/*************************** End of file ****************************/
void TIMER1_IRQHandler (void)
{
if ( LPC_TIM1->IR & (0x1<<0) )//IR=n,选择定时器n(n=0~3),n=4-CR0,n=5-CR1
{
LPC_TIM1->IR = 0x1<<0; /* clear interrupt flag */
_ExecTouch();
//_ExecTouch();
}
} |
|