/* 功能:读取触摸屏读坐标,该坐标未做转换,不能直接使用 返回:0=无效坐标 1=有效坐标 说明:本函数连续采样2次,2次采样结果+-5范围内才算有效 */ uint8 TP_GetAdXY2(u16 *x, u16 *y, uint32 delay) {u16 x1,y1; u16 x2,y2; u8 flag; flag=TP_GetAdXY(&x1, &y1); if(flag==0) return(0); // if(delay>=OS_TIME) // os_dly_wait(delay/OS_TIME);//300ms后再采样1次 //do{ flag=TP_GetAdXY(&x2, &y2); //}while(flag); if(flag==0) return(0); if( ( (x2<=x1 && x1<x2+50) || (x1<=x2 && x2<x1+50) )//前后两次采样在+-5内 && ( (y2<=y1 && y1<y2+50) || (y1<=y2 && y2<y1+50) ) ) { *x=(x1+x2)/2; *y=(y1+y2)/2; return(1); } else return(0); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ //Initialize the touchscreen TSC_Init(); #ifdef PRINT_ON_LCD /* LCD Display init */ Display_Init(); #endif /* ADC3 configuration *******************************************************/ /* - Enable peripheral clocks */ /* - DMA2_Stream0 channel2 configuration */ /* - Configure ADC Channel3 pin as analog input */ /* - Configure ADC3 Channel3 */ ADC3_CH3_DMA_Config(); /* Start ADC3 Software Conversion */ ADC_SoftwareStartConv(ADC3); while (1) { int x, y; char szTemp[64]; if (TSC_TouchDet()) { /* Show touch screen activity */ TP_GetAdXY(&x, &y); } else { x = 0; y = 0; } sprintf(szTemp, "X:%04d Y:%04d ", x, y); LCD_DisplayStringLine(LINE(5), (uint8_t *)szTemp); ADC3ConvertedVoltage = ADC3ConvertedValue *3300/0xFFF; #ifdef PRINT_ON_LCD /* Display ADC3 converted value on LCD */ Display(); #endif } }
void TSC_Read(void) { #if TOUCH_SCREEN_CAPABILITY if (TP_IRQ != SET) { TSC_Value_X = 0x00; TSC_Value_Y = 0x00; TP_GetAdXY(&TSC_Value_X, &TSC_Value_Y); u32_TSXCoordinate = getDisplayCoordinateX( TSC_Value_X, TSC_Value_Y ); u32_TSYCoordinate = getDisplayCoordinateY( TSC_Value_X, TSC_Value_Y ); touch_done = 1; } #endif }
/******************************************************************************* * 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½øÐжà´Î²ÉÑù */ ADS7843_SPI_Init(); 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; }
/******************************************************************************* * 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; }
/** * @brief Main program. * @param None * @retval None */ int main(void) { //RCC_Config(); //GPIO_Config(); //RCC_MCO1Config(RCC_MCO1Source_PLLCLK,RCC_MCO1Div_1); uint8_t tmpreg; LIS302DL_InitTypeDef LIS302DL_InitStruct; /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* SysTick end of count event each 10ms */ RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); //NVIC_SetPriority(SysTick_IRQn, -1); /* MEMS configuration and set int1/int2 pins*/ LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE; LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_100; LIS302DL_InitStruct.Axes_Enable = LIS302DL_XYZ_ENABLE; LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3; LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL; LIS302DL_Init(&LIS302DL_InitStruct); //Set INT1/INT2 pins tmpreg = 0x40; LIS302DL_Write(&tmpreg, LIS302DL_CTRL_REG3_ADDR, 1); //Initialize the touchscreen TSC_Init(); /* Initialize LEDs and push-buttons mounted on STM324xG-EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); //STM_EVAL_LEDInit(LED3); //STM_EVAL_LEDInit(LED4); /* Initialize the LCD */ STM324xG_LCD_Init(); //STM_EVAL_LEDOn(LED1); LCD_Clear(Black); LCD_SetTextColor(White); LCD_LOG_SetHeader("STM32 Camera Demo"); LCD_LOG_SetFooter (" Copyright (c) STMicroelectronics" ); /* ADC configuration */ ADC_Config(); /* Initializes the DCMI interface (I2C and GPIO) used to configure the camera */ //OV9655_HW_Init(); OV9712_HW_Init(); /* Read the OV9655/OV2640 Manufacturer identifier */ //OV9655_ReadID(&OV9655_Camera_ID); OV9712_ReadID(&OV9712_Camera_ID); //while(1); if(OV9655_Camera_ID.PID == 0x96) { Camera = OV9712_CAMERA; sprintf((char*)buffer, "OV9655 Camera ID 0x%x", OV9655_Camera_ID.PID); ValueMax = 2; } else if(OV9712_Camera_ID.PIDH == 0x97) { Camera = OV9712_CAMERA; sprintf((char*)buffer, "OV9712 Camera ID 0x%x", OV9712_Camera_ID.PIDH); ValueMax = 2; } else { LCD_SetTextColor(LCD_COLOR_RED); sprintf((char*)buffer, "OV Camera ID 0x%02x%02x", OV9655_Camera_ID.Version, OV9712_Camera_ID.PIDH); LCD_DisplayStringLine(LINE(4), buffer); while(1); } LCD_SetTextColor(LCD_COLOR_YELLOW); LCD_DisplayStringLine(LINE(4), (uint8_t*)buffer); LCD_SetTextColor(LCD_COLOR_WHITE); Delay(200); /* Initialize demo */ ImageFormat = (ImageFormat_TypeDef)BMP_QVGA; /* Configure the Camera module mounted on STM324xG-EVAL board */ Demo_LCD_Clear(); LCD_DisplayStringLine(LINE(4), "Camera Init.. "); Camera_Config(); sprintf((char*)buffer, " Image selected: %s", ImageForematArray[ImageFormat]); LCD_DisplayStringLine(LINE(4),(uint8_t*)buffer); LCD_ClearLine(LINE(4)); Demo_LCD_Clear(); if(ImageFormat == BMP_QQVGA) { /* LCD Display window */ LCD_SetDisplayWindow(60, 80, 160, 120); ReverseLCD(); LCD_WriteRAM_Prepare(); } else if(ImageFormat == BMP_QVGA) { /* LCD Display window */ LCD_SetDisplayWindow(0, 0, 320, 240); ReverseLCD(); LCD_WriteRAM_Prepare(); } { int i, j; for (j = 0; j < 16; j++) { LCD_SetDisplayWindow(0, (240 / 16) * j, 320, (240 / 16)); LCD_WriteRAM_Prepare(); for (i = 0; i < 320 * 240 / 16; i++) { LCD_WriteRAM(0x0003 << j); } } } /* Enable DMA2 stream 1 and DCMI interface then start image capture */ DMA_Cmd(DMA2_Stream1, ENABLE); DCMI_Cmd(ENABLE); /* Insert 100ms delay: wait 100ms */ //Delay(200); DCMI_CaptureCmd(ENABLE); while(1) { OV9655_BrightnessConfig(0x7F);// //static int step = 0; int i, block, begin; unsigned short *p; if (!bShot) { begin = (datablock - 11 + 48) % 48; for (block = begin; block < begin + 11; block++) { p = (unsigned short *)(0x20000000 + (320 * 240 * 2 / 16) * ((block) % 12)); LCD_SetDisplayWindow(0, (block % 16) * (240 / 16), 320, (240 / 16)); //LCD_SetCursor(0, (block % 16) * (240 / 16)); LCD_WriteRAM_Prepare(); for (i = 0; i < 320 * 240 / 16; i++) { LCD_WriteRAM(*p++); } } } if (TSC_TouchDet()) { int x, y; TP_GetAdXY(&x, &y); if (x > 300 && x < 2800 && y > 300 && y < 2800) { if (x < 1550 && y < 1550) { uint32_t StartSector = 0, EndSector = 0, Address = 0, SectorCounter = 0; int m; //拍照bShot bShot = 1; while(datablock % 16); DMA_Cmd(DMA2_Stream1, DISABLE); DCMI_Cmd(DISABLE); //STM_EVAL_LEDOn(LED2); DMA_ClearFlag(DMA2_Stream1, 0x2F7D0F7D); DMA_ClearFlag(DMA2_Stream1, 0x0F7D0F7D); DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1); datablock = 0; DMA2_Stream1->M0AR = 0x20000000 + 9600 * (datablock % 12); DMA_SetCurrDataCounter(DMA2_Stream1, (320 * 240 * 2 / 4) / 16); DCMI_Cmd(ENABLE); DMA_Cmd(DMA2_Stream1, ENABLE); { unsigned long *p, *q; while(datablock < 4); //等待准备好前4块数据,就将这4块数据导入到0x10000000+0x50000之后。 q = (unsigned long *)(0x20000000); p = (unsigned long *)(0x10000000 + 0x5000); while (q < (unsigned long *)(0x20000000 + 4 * (320 * 240 * 2 / 16))) { *p = *q; p++; q++; } } while(datablock < 16); //等待全部采集完成。 STM_EVAL_LEDOn(LED2); //LED2亮表示采集完成。 LCD_SetDisplayWindow(0, 0, 320, 240); LCD_WriteRAM_Prepare(); LCD_Clear(Black); //RAM位置 /* 序号 地址 大小 1: 0x10005000+9600*0 9600 2: 0x10005000+9600*1 9600 3: 0x10005000+9600*2 9600 4: 0x10005000+9600*3 9600 5: 0x20000000+9600*5 9600 6: 0x20000000+9600*6 9600 7: 0x20000000+9600*7 9600 8: 0x20000000+9600*8 9600 9: 0x20000000+9600*9 9600 10: 0x20000000+9600*10 9600 11: 0x20000000+9600*11 9600 12: 0x20000000+9600*0 9600 13: 0x20000000+9600*1 9600 14: 0x20000000+9600*2 9600 15: 0x20000000+9600*3 9600 */ for (m = 0; m < 16; m++) //显示保存的图片 { unsigned short *q; if (m < 4) { q = (unsigned short *)(0x10000000 + 0x5000 + m * (320 * 240 * 2 / 16)); } else { q = (unsigned short *)(0x20000000 + (m % 12) * (320 * 240 * 2 / 16)); } LCD_SetDisplayWindow(0, m * (240 / 16), 320, (240 / 16)); LCD_WriteRAM_Prepare(); for (i = 0; i < 320 * 240 / 16; i++) { LCD_WriteRAM(*q++); } } /* Erase the user Flash area ***********/ FLASH_Unlock(); /* Clear pending flags (if any) */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); /* Get the number of the start and end sectors */ StartSector = GetSector(FLASH_USER_START_ADDR); EndSector = GetSector(FLASH_USER_END_ADDR); for (SectorCounter = StartSector; SectorCounter < EndSector; SectorCounter += 8) { /* Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word */ if (FLASH_EraseSector(SectorCounter, VoltageRange_3) != FLASH_COMPLETE) { /* Error occurred while sector erase. User can add here some code to deal with this error */ while (1) { } } } for (m = 0; m < 16; m++) //保存图片到flash { unsigned long *q; Address = FLASH_USER_START_ADDR + m * (320 * 240 * 2 / 16); if (m < 4) { q = (unsigned long *)(0x10000000 + 0x5000 + m * (320 * 240 * 2 / 16)); } else { q = (unsigned long *)(0x20000000 + (m % 12) * (320 * 240 * 2 / 16)); } while (Address < FLASH_USER_START_ADDR + (m + 1) *(320 * 240 * 2 / 16)) { if (FLASH_ProgramWord(Address, *q) == FLASH_COMPLETE) { Address = Address + 4; q++; } else { /* Error occurred while writing data in Flash memory. User can add here some code to deal with this error */ while (1) { } } } } STM_EVAL_LEDOff(LED2); LCD_SetDisplayWindow(0, 0, 320, 240); LCD_WriteRAM_Prepare(); LCD_Clear(Black); for (m = 0; m < 16; m++) //显示flash中的图片 { unsigned short *q; q = (unsigned short *)(FLASH_USER_START_ADDR + m * (320 * 240 * 2 / 16)); LCD_SetDisplayWindow(0, m * (240 / 16), 320, (240 / 16)); LCD_WriteRAM_Prepare(); for (i = 0; i < 320 * 240 / 16; i++) { LCD_WriteRAM(*q++); } } /* Lock the Flash to disable the flash control register access (recommended to protect the FLASH memory against possible unwanted operation) *********/ FLASH_Lock(); } else if (x >= 1550 && y < 1550) { //righttop STM_EVAL_LEDOff(LED1); STM_EVAL_LEDOff(LED2); bShot = 0; datablock = 0; DMA_Cmd(DMA2_Stream1, ENABLE); DCMI_Cmd(ENABLE); } else if (x < 1550 && y >= 1550) { //righttop //DMA_Cmd(DMA2_Stream1, ENABLE); //DCMI_Cmd(ENABLE); } else if (x >= 1550 && y >= 1550) { //righttop //DMA_Cmd(DMA2_Stream1, ENABLE); //DCMI_Cmd(ENABLE); } } } //Delay(10); } }
/******************************************************************************* * Function Name : Read_Ads7846 * Description : Get TouchPanel 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}}; do { 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 */ if(count==9) /* Average X Y */ { /* Average X */ 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; 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.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; /* Average 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; }
/******************************************************************************* * Function Name : Read_Ads7846 * Description : X Y obtained after filtering * Input : Pointers to variables to store X and Y values in. * Return : 1 for valid touch, 0 for invalid touch. *******************************************************************************/ static _Bool Read_Ads7846(uint16_t *px, uint16_t *py) { int m0, m1, m2, TP_X[1], TP_Y[1], temp[3]; uint8_t count = 0; int buffer[2][9] = { { 0 }, { 0 } }; /* Multiple sampling coordinates X and Y */ do /* Loop sampling 9 times */ { 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); /* when user clicks on the touch screen, TP_INT_IN touchscreen interrupt pin will be set to low. */ if (count == 9) /* Successful sampling 9, filtering */ { /* In order to reduce the amount of computation, were divided into three groups averaged */ 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; /* Calculate the three groups of data */ m0 = temp[0] - temp[1]; m1 = temp[1] - temp[2]; m2 = temp[2] - temp[0]; /* Absolute value of the above difference */ m0 = m0 > 0 ? m0 : (-m0); m1 = m1 > 0 ? m1 : (-m1); m2 = m2 > 0 ? m2 : (-m2); /* Judge whether the absolute difference exceeds the difference between the threshold, If these three absolute difference exceeds the threshold, The sampling point is judged as outliers, Discard sampling points */ if (m0 > TOUCH_CLOSENESS_THRESHOLD && m1 > TOUCH_CLOSENESS_THRESHOLD && m2 > TOUCH_CLOSENESS_THRESHOLD) { return 0; } /* Calculating their average value */ if (m0 < m1) { if (m2 < m0) { *px = (temp[0] + temp[2]) / 2; } else { *px = (temp[0] + temp[1]) / 2; } } else if (m2 < m1) { *px = (temp[0] + temp[2]) / 2; } else { *px = (temp[1] + temp[2]) / 2; } /* calculate the average value of 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 > TOUCH_CLOSENESS_THRESHOLD && m1 > TOUCH_CLOSENESS_THRESHOLD && m2 > TOUCH_CLOSENESS_THRESHOLD) { return 0; } if (m0 < m1) { if (m2 < m0) { *py = (temp[0] + temp[2]) / 2; } else { *py = (temp[0] + temp[1]) / 2; } } else if (m2 < m1) { *py = (temp[0] + temp[2]) / 2; } else { *py = (temp[1] + temp[2]) / 2; } return 1; } return 0; }