最近因为项目需要,需要在STM32平台上(裸机)驱动电容触摸屏,触摸屏控制IC为FT6206,触摸屏供应商只提供了Linux的驱动代码,看得一头雾水,只好自己写。
网上搜索相关资料,好不容易才搜索到一份敦泰的调屏资料,上面写是0x70,抱着试一下的心态,试了一下,没想到还真的是这个地址,心中窃喜,接下来就简单,读坐标点数据就行了。但碰到一个问题是,资料上写着是支持手势的,但我怎么按屏幕,从手势寄存器中读出来的都是0x00,表示没有手势 ,但坐标点数据读出来都是正确的,心中那个郁闷啊,不过我的项目用不上手势,就不管它了,如果有人知道是为什么,还请多多指点。
还有一个地方需要注意的,就是上电后需要给芯片一个唤醒信号,该信号主机可以通过触摸屏的INT或者RST引脚提供。
好了,直接上代码:
这个是.h文件
#ifndef __TOUCH_H #define __TOUCH_H #ifdef MY_TOUCH_GLOBALS #define MY_TOUCH_EXT #else #define MY_TOUCH_EXT extern #endif /**************************引脚配置********************************/ #define CT_SDA_PIN GPIO_Pin_15 #define CT_SCL_PIN GPIO_Pin_14 #define CT_RST_PIN GPIO_Pin_13 #define CT_INT_PIN GPIO_Pin_12 #define RCC_CT_I2C_PORT RCC_APB2Periph_GPIOF #define RCC_CT_CONTROL_PORT RCC_APB2Periph_GPIOF #define CT_CONTROL_PORT GPIOF #define CT_I2C_PORT GPIOF #define TOUCH_GPIO_PortSource GPIO_PortSourceGPIOF #define TOUCH_GPIO_PinSource GPIO_PinSource12 #define TOUCH_EXTI_Line EXTI_Line12 #define TOUCH_EXTI_IRQn EXTI15_10_IRQn /***************************相关宏定义********************************/ #define TOUCH_NO_POINT (~0) /************************错误代码*****************************/ #define CT_COM_OK (0) #define CT_ACK_FAIL (1) #define FT6X06_ID (0x6206) #define CT_IC (FT6X06_ID) //使用的控制IC #define CT_ADDR (0x70) //器件地址 #define CT_WRITE_MASK (0x00) #define CT_READ_MASK (0x01) #define CT_CACK_TIMEOUT (3000) //等待ACK超时时间 //reg map #define DEVICE_MODE (0x00) //This register is the device mode register, configure it to determine the current mode of the chip #define GEST_ID (0x01) //This register describes the gesture of a valid touch #define TD_STATUS (0x02) //How many points detected #define P1_XH (0x03) //This register describes MSB of the X coordinate of the nth touch point and the corresponding event flag #define P1_XL (0x04) //This register describes LSB of the X coordinate of the nth touch point #define P1_YH (0x05) //This register describes MSB of the Y coordinate of the nth touch point and corresponding touch ID #define P1_YL (0x06) //This register describes LSB of the Y coordinate of the nth touch point #define P2_XH (0x09) #define P2_XL (0x0A) #define P2_YH (0x0B) #define P2_YL (0x0C) #define ID_G_THGROUP (0x80) //灵敏度 #define ID_G_PERIODACTIVE (0x88) //扫描频率,This register describes the period of active status, it should not less than 12,最大14 #define ID_G_AUTO_CLB_MODE (0xA0) //This register describes auto calibration mode #define G_MODE (0xA4) #define ID_G_STATE (0xA7) //This register is used to configure the run mode of TPM. #define ID_G_FTID (0xA8) //芯片ID #define ID_G_ERR (0xA9) //This register describes the error code when the TPM is running /*********************相关结构体*************************/ #if (CT_IC == FT6X06_ID) #define MAX_TOUCH_POINT (2) //最大触摸点个数 #endif #ifndef MAX_TOUCH_POINT #define MAX_TOUCH_POINT (2) #endif //触摸点事件 #define EVENT_PRESS_DOWN (0) #define EVENT_LIFT_UP (1) #define EVENT_CONTACT (2) #define EVENT_NONE (3) //手势 #define GUSTURE_MOVE_UP (0x10) #define GUSTURE_MOVE_RIGHT (0x14) #define GUSTURE_MOVE_DOWN (0x18) #define GUSTURE_MOVE_LEFT (0x1C) #define GUSTURE_MOVE_ZOOM_IN (0x48) #define GUSTURE_MOVE_ZOOM_OUT (0x49) #define GUSTURE_NONE (0x00) #define CT_READ_START (GEST_ID) //每次检测到触摸屏中断信号时从哪个寄存器开始读取数据 #define CT_READ_LENGTH (12) //每次检测到触摸屏中断信号时读取多少个数据 #define CT_READ_NO_GEST (0) //手势在读出数据的位置 #define CT_READ_NO_TD_STATUS (CT_READ_NO_GEST+1) //有效点数 #define CT_READ_NO_P1 (CT_READ_NO_TD_STATUS+1) #define CT_READ_NO_P2 (CT_READ_NO_P1+6) #define CT_DEF_VALID_POINT_ERROR (10) typedef struct { uint8_t M_EventFlag; //触摸点事件 uint16_t M_Xpos; uint16_t M_Ypos; uint16_t M_PreXpos; //上一次的点位置 uint16_t M_PreYpos; }ST_CTPoint; typedef struct { uint8_t M_nPoint; //当前有效,触摸点个数,对于FT6X06最多两个 uint8_t M_Gesture; //手势 ST_CTPoint * M_pStCTPoint[MAX_TOUCH_POINT]; }ST_CTTouchStatus; typedef struct { uint16_t M_ValidStartXpos; //X有效起始位置 uint16_t M_ValidEndXpos; //X有效结束位置 uint16_t M_ValidStartYpos; //Y有效起始位置 uint16_t M_ValidEndYpos; //Y有效结束位置 uint8_t M_ValidErrRange; //容许偏差 }ST_ValidPoint; MY_TOUCH_EXT ST_CTPoint StCTPoint1; MY_TOUCH_EXT ST_CTPoint StCTPoint2; MY_TOUCH_EXT ST_CTTouchStatus StCTTouchStatus; MY_TOUCH_EXT uint8_t FlagCTINT; //触摸中断标志 MY_TOUCH_EXT uint8_t FlagPointToDeal; //是否有点有效标志 /* **函数名:CTI2C_GPIO_Config **传入参数:无 **返回值:无 **功能:初始化CTI2C引脚 */ void CTI2C_GPIO_Config(void); uint8_t CT_Write_Nbyte(const uint8_t sla_add,const uint8_t add,uint16_t n,const uint8_t *s); uint8_t CT_Read_Nbyte(const uint8_t sla_add,const uint8_t add,uint16_t n,uint8_t *s); void CT_Reset(void); void CT_Init_Val(void); uint8_t CT_GetTouch_Status(uint8_t *RetPointToDealFlag); #endif
这个是.c文件
#define MY_TOUCH_GLOBALS #include ".././includes.h" #define SDA_High GPIO_WriteBit(CT_I2C_PORT,CT_SDA_PIN,Bit_SET) #define SDA_Low GPIO_WriteBit(CT_I2C_PORT,CT_SDA_PIN,Bit_RESET) #define SDA_INPUT {CT_I2C_PORT->CRH&=0X0FFFFFFF;CT_I2C_PORT->CRH|= 8ul<<28;}//第15脚,(15-8)*4 = 28 #define SDA_OUTPUT {CT_I2C_PORT->CRH&=0X0FFFFFFF;CT_I2C_PORT->CRH|= 3ul<<28;}//第15脚,(15-8)*4 = 28 #define SCL_High GPIO_WriteBit(CT_I2C_PORT,CT_SCL_PIN,Bit_SET) #define SCL_Low GPIO_WriteBit(CT_I2C_PORT,CT_SCL_PIN,Bit_RESET) #define GetSDABit GPIO_ReadInputDataBit(CT_I2C_PORT,CT_SDA_PIN) #define CT_DELAY_US(val) Delay_us(val) /* **函数名:CTI2C_GPIO_Config **传入参数:无 **返回值:无 **功能:初始化CTI2C引脚 */ void CTI2C_GPIO_Config(void) { /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; /*开启GPIO的外设时钟*/ RCC_APB2PeriphClockCmd(RCC_CT_I2C_PORT | RCC_CT_CONTROL_PORT, ENABLE); /*选择要控制的引脚*/ GPIO_InitStructure.GPIO_Pin = CT_SDA_PIN | CT_SCL_PIN; /*设置引脚模式为通用推挽输出*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*设置引脚速率为10MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; /*调用库函数,初始化GPIO*/ GPIO_Init(CT_I2C_PORT,&GPIO_InitStructure); /*选择要控制的引脚*/ GPIO_InitStructure.GPIO_Pin = CT_RST_PIN; /*设置引脚模式为通用推挽输出*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*设置引脚速率为10MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; /*调用库函数,初始化GPIO*/ GPIO_Init(CT_CONTROL_PORT,&GPIO_InitStructure); /*选择要控制的引脚*/ GPIO_InitStructure.GPIO_Pin = CT_INT_PIN; /*设置引脚模式为通用推挽输出*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; /*设置引脚速率为10MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; /*调用库函数,初始化GPIO*/ GPIO_Init(CT_CONTROL_PORT,&GPIO_InitStructure); /*********************初始化外部中断**********************/ /*开启引脚复用AFIO的外设时钟,因为用到了AFIO外部中断配置寄存器*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE); /* Selects as EXTI Line */ GPIO_EXTILineConfig(TOUCH_GPIO_PortSource, TOUCH_GPIO_PinSource); /*选择外部中断线*/ EXTI_InitStructure.EXTI_Line = TOUCH_EXTI_Line; /*设置EXTI线路为中断请求*/ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; /*下降沿触发*/ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; /*使能选中线路*/ EXTI_InitStructure.EXTI_LineCmd = ENABLE; /*外部中断初始化*/ EXTI_Init(&EXTI_InitStructure); /******************************************************/ } /**************************/ static void CTI2C_start(void)//CTI2C启动函数 { SDA_OUTPUT; SCL_High; SDA_High; CT_DELAY_US(300); SDA_Low; CT_DELAY_US(300); SCL_Low; } /**************************/ static void CTI2C_stop(void)// CTI2C停止函数 { SDA_OUTPUT; SDA_Low; SCL_High; CT_DELAY_US(300); SDA_High; CT_DELAY_US(300); SDA_Low; SCL_Low; } /**************************/ static void CTI2C_write_byte(const uint8_t s)//CTI2C写1byte函数,S为需要写的内容 { uint8_t temps; uint8_t dat,i; temps=s; dat=0x80; SDA_OUTPUT; for(i=0;i<8;i++) { if(dat&temps)//对应位为一就发一 { SDA_High; CT_DELAY_US(100);//延时一下,保证数据建立时间大于50ns //SCL的频率,高速为400KHz,标准为100KHz SCL_High; CT_DELAY_US(300); SCL_Low; CT_DELAY_US(300); } else { SDA_Low; CT_DELAY_US(100);//延时一下,保证数据建立时间大于50ns SCL_High; CT_DELAY_US(300); SCL_Low; CT_DELAY_US(300); } dat=dat>>1;//注意Keil中将有符号数的右移操作作算术右移处理,我需要的是逻辑右移,因此dat要先定义为无符号数,否则会出错 } SDA_High;//主控制器写完后要预先释放对SDA总线的控制 CT_DELAY_US(100);//留一点时间接收应答信号 } /**************************/ static void CTI2C_read_byte(uint8_t *s)//CTI2C读1byte函数,数据放在形参中,成功返回1,失败返回0 { uint8_t temps=0,i; uint8_t text=0x80; uint8_t sdain; SDA_INPUT; SDA_High;//设SDA为输入方式 for(i=0;i<8;i++) { SCL_High;//使SDA上的数据有效 CT_DELAY_US(100);//延时一下,保证SDA已经稳定 sdain = GetSDABit;//取得SDA上的数据 if(1==sdain) { temps |=(text>>i);//先接收高位 } SCL_Low;//读完后允许SDA上的数据刷新,并延时一下让被读器件有时间更新要输出的数据 CT_DELAY_US(300); } *s=temps; CT_DELAY_US(300);//留一点时间发送应答信号 } /**************************/ static uint8_t CTI2C_check_ack(void)//CTI2C应答位检查函数,正常应答返回0,否则返回1 { uint8_t sdain; SDA_INPUT; SDA_High;//置SDA为输入 SCL_High;//使SDA上的数据有效 CT_DELAY_US(100);//延时一下,保证SDA已经稳定 sdain = GetSDABit;//取得SDA上的数据 SCL_Low; if(1==sdain) return 1; else return 0; } /**************************/ static void CTI2C_send_ack(void)//CTI2C发送应答信号函数 { SDA_OUTPUT; SDA_Low; CT_DELAY_US(100);//延时一下,保证SDA已经稳定 SCL_High; CT_DELAY_US(300); SCL_Low; SDA_High; } /**************************/ static void CTI2C_send_nack(void)//CTI2C发送非应答信号函数 { SDA_OUTPUT; SDA_High; CT_DELAY_US(100);//延时一下,保证SDA已经稳定 SCL_High; CT_DELAY_US(300); SCL_Low; SDA_Low; } /**************************/ /****************************************************************************** * FUNCTION: CT_Write_Nbyte ( ) * DESCRIPTION: 写触摸屏寄存器 * Input the description of function: * Input Parameters: 器件地址,待写寄存器地址,待写数据数量,存储待写入数据的地址 * Output Parameters: 无 * Returns Value: * * Author: FuDongQiang @ 2015/05/22 * * modification history * ... ******************************************************************************/ uint8_t CT_Write_Nbyte(const uint8_t sla_add,const uint8_t add,uint16_t n,const uint8_t *s)//CTI2C写nbyte函数,写数据由形参数组传入,成功返回1,失败返回0 { uint8_t temps,ack=1; uint16_t tempn; uint16_t cack_time=0; CTI2C_start();//启动CTI2C总线 CTI2C_write_byte(sla_add | CT_WRITE_MASK);//发送寻址字节 do { cack_time++; if(cack_time>CT_CACK_TIMEOUT)//在规定时间cack_timeout内收不到应答信号,返回出错信号 return CT_ACK_FAIL; } while(CTI2C_check_ack()); CTI2C_write_byte(add);//发送要写入的起始地址 cack_time=0; do { cack_time++; if(cack_time>CT_CACK_TIMEOUT)//在规定时间cack_timeout内收不到应答信号,返回出错信号 return CT_ACK_FAIL; } while(CTI2C_check_ack()); for(tempn=0;tempn<n;tempn++) { ack=1;//应答位 cack_time=0; temps=*(s+tempn); while(ack) { CTI2C_write_byte(temps); ack=CTI2C_check_ack();//检查应答信号,非应答则重发该字节 cack_time++; if(cack_time>CT_CACK_TIMEOUT)//在规定时间cack_timeout内收不到应答信号,返回出错信号 return CT_ACK_FAIL; } } CTI2C_stop();// CTI2C停止 return CT_COM_OK; } /****************************************************************************** * FUNCTION: CT_Read_Nbyte ( ) * DESCRIPTION: 从触摸屏中读出数据 * Input the description of function: * Input Parameters: 器件地址,待读寄存器地址,待读数据数量,存储待读出数据的地址 * Output Parameters: 读取的数据 * Returns Value: * * Author: FuDongQiang @ 2015/05/22 * * modification history * ... ******************************************************************************/ uint8_t CT_Read_Nbyte(const uint8_t sla_add,const uint8_t add,uint16_t n,uint8_t *s)//CTI2C读nbyte函数,所读数据放在形参数组中(由程序员设置合适的数组大小),成功返回1,失败返回0 { uint8_t temps; uint16_t tempn; uint16_t cack_time=0; CTI2C_start();//启动CTI2C总线 CTI2C_write_byte(sla_add | CT_WRITE_MASK);//发送寻址字节,伪写 do { cack_time++; if(cack_time>CT_CACK_TIMEOUT)//在规定时间cack_timeout内收不到应答信号,返回出错信号 return CT_ACK_FAIL; } while(CTI2C_check_ack()); CTI2C_write_byte(add);//发送要读入的起始地址 cack_time=0; do { cack_time++; if(cack_time>CT_CACK_TIMEOUT)//在规定时间cack_timeout内收不到应答信号,返回出错信号 return CT_ACK_FAIL; } while(CTI2C_check_ack()); CTI2C_start();//再次启动CTI2C总线 CTI2C_write_byte(sla_add | CT_READ_MASK);//再次发送寻址字节,读 cack_time=0; do { cack_time++; if(cack_time>CT_CACK_TIMEOUT)//在规定时间cack_timeout内收不到应答信号,返回出错信号 return CT_ACK_FAIL; } while(CTI2C_check_ack()); for(tempn=0;tempn<n;tempn++) { CTI2C_read_byte(&temps); *(s+tempn)=temps; if(tempn+1<n)//如果已经读完所有数据了,就不要发应答信号,直接发非应答位和停止位 CTI2C_send_ack();//CTI2C发送应答信号.准备下一字节的接收 } CTI2C_send_nack();//接收完毕,发送非应答位和停止位 CTI2C_stop(); return CT_COM_OK; } //复位触摸芯片 void CT_Reset(void) { //The reset signal from host to CTPM, active low, and the low pulse width should be more than or equal to 1ms GPIO_SetBits(CT_CONTROL_PORT,CT_RST_PIN); Delay_ms(1); GPIO_ResetBits(CT_CONTROL_PORT,CT_RST_PIN); Delay_ms(5); GPIO_SetBits(CT_CONTROL_PORT,CT_RST_PIN); Delay_ms(1); } /****************************************************************************** * FUNCTION: CT_Init_Val ( ) * DESCRIPTION: 初始化触摸芯片相关变量 * Input the description of function: * Input Parameters: * Output Parameters: * Returns Value: * * Author: FuDongQiang @ 2015/05/22 * * modification history * ... ******************************************************************************/ void CT_Init_Val(void) { FlagCTINT = RESET; FlagPointToDeal = RESET; StCTPoint1.M_EventFlag = EVENT_NONE; StCTPoint2.M_EventFlag = EVENT_NONE; StCTTouchStatus.M_Gesture = GUSTURE_NONE; StCTTouchStatus.M_nPoint = 0; StCTTouchStatus.M_pStCTPoint[0] = &StCTPoint1; StCTTouchStatus.M_pStCTPoint[1] = &StCTPoint2; } /****************************************************************************** * FUNCTION: CT_GetTouch_Status ( ) * DESCRIPTION: 获取当前触摸状态,保存在ST_CTTouchStatus中 * Input the description of function: * Input Parameters: * Output Parameters: 是否有需要处理的触摸状态 * Returns Value: * * Author: FuDongQiang @ 2015/05/22 * * modification history * ... ******************************************************************************/ uint8_t CT_GetTouch_Status(uint8_t *RetPointToDealFlag) { uint8_t StrTempData[CT_READ_LENGTH],Error = ERROR_OK; uint16_t Temp; Error = CT_Read_Nbyte(CT_ADDR,CT_READ_START,CT_READ_LENGTH,StrTempData); if(Error == CT_COM_OK) { Error = ERROR_OK; StCTTouchStatus.M_Gesture = StrTempData[CT_READ_NO_GEST]; //手势 StCTTouchStatus.M_nPoint = StrTempData[CT_READ_NO_TD_STATUS]; //有多少个点有效 if(StCTTouchStatus.M_nPoint > 0 && StCTTouchStatus.M_nPoint <= MAX_TOUCH_POINT) { *RetPointToDealFlag = SET; //Event Flag StCTTouchStatus.M_pStCTPoint[0]->M_EventFlag = StrTempData[CT_READ_NO_P1]>>6; StCTTouchStatus.M_pStCTPoint[1]->M_EventFlag = StrTempData[CT_READ_NO_P1]>>6; //X1 Position Temp = StrTempData[CT_READ_NO_P1]&0x0F; Temp = Temp<<8; Temp += StrTempData[CT_READ_NO_P1+1]; StCTTouchStatus.M_pStCTPoint[0]->M_PreXpos = StCTTouchStatus.M_pStCTPoint[0]->M_Xpos; StCTTouchStatus.M_pStCTPoint[0]->M_Xpos = Temp; //Y1 Position Temp = StrTempData[CT_READ_NO_P1+2]&0x0F; Temp = Temp<<8; Temp += StrTempData[CT_READ_NO_P1+3]; StCTTouchStatus.M_pStCTPoint[0]->M_PreYpos = StCTTouchStatus.M_pStCTPoint[0]->M_Ypos; StCTTouchStatus.M_pStCTPoint[0]->M_Ypos = Temp; //X2 Position Temp = StrTempData[CT_READ_NO_P2]&0x0F; Temp = Temp<<8; Temp += StrTempData[CT_READ_NO_P2+1]; StCTTouchStatus.M_pStCTPoint[1]->M_PreXpos = StCTTouchStatus.M_pStCTPoint[1]->M_Xpos; StCTTouchStatus.M_pStCTPoint[1]->M_Xpos = Temp; //Y2 Position Temp = StrTempData[CT_READ_NO_P2+2]&0x0F; Temp = Temp<<8; Temp += StrTempData[CT_READ_NO_P2+3]; StCTTouchStatus.M_pStCTPoint[1]->M_PreYpos = StCTTouchStatus.M_pStCTPoint[1]->M_Ypos; StCTTouchStatus.M_pStCTPoint[1]->M_Ypos = Temp; } //没有按键按下 else { // StCTTouchStatus.M_pStCTPoint[0]->M_PreXpos = StCTTouchStatus.M_pStCTPoint[0]->M_Xpos; // StCTTouchStatus.M_pStCTPoint[0]->M_Xpos = TOUCH_NO_POINT; // StCTTouchStatus.M_pStCTPoint[0]->M_PreYpos = StCTTouchStatus.M_pStCTPoint[0]->M_Ypos; // StCTTouchStatus.M_pStCTPoint[0]->M_Ypos = TOUCH_NO_POINT; // StCTTouchStatus.M_pStCTPoint[1]->M_PreXpos = StCTTouchStatus.M_pStCTPoint[1]->M_Xpos; // StCTTouchStatus.M_pStCTPoint[1]->M_Xpos = TOUCH_NO_POINT; // StCTTouchStatus.M_pStCTPoint[1]->M_PreYpos = StCTTouchStatus.M_pStCTPoint[1]->M_Ypos; // StCTTouchStatus.M_pStCTPoint[1]->M_Ypos = TOUCH_NO_POINT; Error = ERROR_UNKNOW; } } return Error; } /****************************************************************************** * FUNCTION: CT_Check_Point_Valid ( ) * DESCRIPTION: 检测当前触摸区域是否有效 * Input the description of function: * Input Parameters: 待对比当前有效触摸区域 * Output Parameters: * Returns Value: * * Author: FuDongQiang @ 2015/05/22 * * modification history * ... ******************************************************************************/ uint8_t CT_Check_Point_Valid(ST_ValidPoint *pStValidPoint) { uint8_t Stauts = ERROR_TOUCH_POINT_INVALID,n; uint16_t ValidStart, ValidEnd; for(n = 0; n < StCTTouchStatus.M_nPoint; n++) { //检测X,Y坐标是否都在有效区域内 if(pStValidPoint->M_ValidStartXpos > pStValidPoint->M_ValidErrRange) { ValidStart = pStValidPoint->M_ValidStartXpos - pStValidPoint->M_ValidErrRange; } else { ValidStart = pStValidPoint->M_ValidStartXpos; } ValidEnd = pStValidPoint->M_ValidEndXpos + pStValidPoint->M_ValidErrRange; if((StCTTouchStatus.M_pStCTPoint[n]->M_Xpos >= ValidStart) && (StCTTouchStatus.M_pStCTPoint[n]->M_Xpos <= ValidEnd)) { if(pStValidPoint->M_ValidStartYpos > pStValidPoint->M_ValidErrRange) { ValidStart = pStValidPoint->M_ValidStartYpos - pStValidPoint->M_ValidErrRange; } else { ValidStart = pStValidPoint->M_ValidStartYpos; } ValidEnd = pStValidPoint->M_ValidEndYpos + pStValidPoint->M_ValidErrRange; if((StCTTouchStatus.M_pStCTPoint[n]->M_Ypos >= ValidStart) && (StCTTouchStatus.M_pStCTPoint[n]->M_Ypos <= ValidEnd)) { Stauts = ERROR_TOUCH_POINT_VALID; } } } return Stauts; } void EXTI15_10_IRQHandler(void) { FlagCTINT = SET; /* 清楚中断标志位*/ EXTI_ClearITPendingBit(TOUCH_EXTI_Line); }