最近因为项目需要,需要在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
#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);
}
#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);
}