在上个帖子里面(【STM32F469I试用】LCD简单测试之“弹幕”)简单的测试了LCD的显示效果,下面的简单的使用下STM32F469-DISCO的电容触摸屏测下多点触摸的效果。STM32F469-DISCO板载的电容触摸屏最多支持2点触摸,这个足够用来进行模拟常用的2个手指放大缩小的操作了。常见的触摸屏都支持一些按下松开等事件,上下左右滑动,缩小放大等手势也可以直接从触摸屏的寄存器读取,有了这些事件和手势的支持,我们就可以做一下比较复杂的操作了。
STM32F469-DISCO上的触摸驱动IC为FT6206,和mcu通信使用IIC接口,通过IIC可以读取LCD被按下时的位置,事件和手势。FT6206的一些参数如下:
相应的接口连接:
电容触摸屏一般都不要校准,制造时相应的分辨和lcd的分辨率对于关系已经确定,但是为避免一些设计工艺和温度的影响可以校准下使触摸屏更加准确。
读取触摸屏的数据时采用查询模式,先查询有几个点按下,然后读取相应的位置,此时也可以得到事件和手势信息。详细如下:
uint8_t BSP_TS_GetState(TS_StateTypeDef *TS_State)
{
static uint32_t _x[TS_MAX_NB_TOUCH] = {0, 0};
static uint32_t _y[TS_MAX_NB_TOUCH] = {0, 0};
uint8_t ts_status = TS_OK;
uint16_t tmp;
uint16_t Raw_x[TS_MAX_NB_TOUCH];
uint16_t Raw_y[TS_MAX_NB_TOUCH];
uint16_t xDiff;
uint16_t yDiff;
uint32_t index;
#if (TS_MULTI_TOUCH_SUPPORTED == 1)
uint32_t weight = 0;
uint32_t area = 0;
uint32_t event = 0;
#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
/* Check and update the number of touches active detected */
TS_State->touchDetected = ts_driver->DetectTouch(I2C_Address);
if(TS_State->touchDetected)
{
for(index=0; index < TS_State->touchDetected; index++)
{
/* Get each touch coordinates */
ts_driver->GetXY(I2C_Address, &(Raw_x[index]), &(Raw_y[index]));
if(ts_orientation & TS_SWAP_XY)
{
tmp = Raw_x[index];
Raw_x[index] = Raw_y[index];
Raw_y[index] = tmp;
}
if(ts_orientation & TS_SWAP_X)
{
Raw_x[index] = FT_6206_MAX_WIDTH - 1 - Raw_x[index];
}
if(ts_orientation & TS_SWAP_Y)
{
Raw_y[index] = FT_6206_MAX_HEIGHT - 1 - Raw_y[index];
}
xDiff = Raw_x[index] > _x[index]? (Raw_x[index] - _x[index]): (_x[index] - Raw_x[index]);
yDiff = Raw_y[index] > _y[index]? (Raw_y[index] - _y[index]): (_y[index] - Raw_y[index]);
if ((xDiff + yDiff) > 5)
{
_x[index] = Raw_x[index];
_y[index] = Raw_y[index];
}
TS_State->touchX[index] = _x[index];
TS_State->touchY[index] = _y[index];
#if (TS_MULTI_TOUCH_SUPPORTED == 1)
/* Get touch info related to the current touch */
ft6x06_TS_GetTouchInfo(I2C_Address, index, &weight, &area, &event);
/* Update TS_State structure */
TS_State->touchWeight[index] = weight;
TS_State->touchArea[index] = area;
/* Remap touch event */
switch(event)
{
case FT6206_TOUCH_EVT_FLAG_PRESS_DOWN :
TS_State->touchEventId[index] = TOUCH_EVENT_PRESS_DOWN;
break;
case FT6206_TOUCH_EVT_FLAG_LIFT_UP :
TS_State->touchEventId[index] = TOUCH_EVENT_LIFT_UP;
break;
case FT6206_TOUCH_EVT_FLAG_CONTACT :
TS_State->touchEventId[index] = TOUCH_EVENT_CONTACT;
break;
case FT6206_TOUCH_EVT_FLAG_NO_EVENT :
TS_State->touchEventId[index] = TOUCH_EVENT_NO_EVT;
break;
default :
ts_status = TS_ERROR;
break;
} /* of switch(event) */
#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
} /* of for(index=0; index < TS_State->touchDetected; index++) */
#if (TS_MULTI_TOUCH_SUPPORTED == 1)
/* Get gesture Id */
ts_status = BSP_TS_Get_GestureId(TS_State);
#endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */
} /* end of if(TS_State->touchDetected != 0) */
return (ts_status);
}
下面简单的测下手写功能:
对应的mian函数如下,初始化lcd和touch后就不停的查询是否有按下操作:
int main(void)
{
uint32_t ts_status = 0,t;
HAL_Init();
SystemClock_Config();
LED_Init();
BSP_LCD_Init();
BSP_LCD_Layer();
BSP_TS_ResetTouchData(&TS_State);
if (TouchScreen_IsCalibrationDone() == 0)
{
ts_status = Touchscreen_Calibration();
if(ts_status == 0)
{
BSP_LCD_SetTextColor(LCD_COLOR_RED);
BSP_LCD_SetFont(&Font24);
BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 65, (uint8_t *)"Touchscreen calibration success.", CENTER_MODE);
HAL_Delay(1000);
BSP_LCD_Clear(LCD_COLOR_WHITE);
}
}
BSP_LCD_SetTextColor(LCD_COLOR_RED);
BSP_LCD_SetFont(&Font24);
DrawProp[1].TextColor = LCD_COLOR_BLUE;
BSP_LCD_DrawCircle(40,40,40);
BSP_LCD_DisplayStringAt(30,30,(uint8_t*)"C",LEFT_MODE);
while(1)
{
BSP_TS_GetState(&TS_State);
if(TS_State.touchDetected)
{
if(TS_State.touchX[0] < 80 && TS_State.touchY[0] < 80) //clear lcd
{
BSP_LCD_Clear(LCD_COLOR_WHITE);
BSP_LCD_SetTextColor(LCD_COLOR_RED);
BSP_LCD_SetFont(&Font24);
DrawProp[1].TextColor = LCD_COLOR_BLUE;
BSP_LCD_DrawCircle(40,40,40);
BSP_LCD_DisplayStringAt(30,30,(uint8_t*)"C",LEFT_MODE);
}
else
{
for(t = 0;t < TS_State.touchDetected;t ++)
{
DrawProp[1].TextColor = colorBuff[t]; // set color
BSP_LCD_FillCircle(TS_State.touchX[t],TS_State.touchY[t],5); //draw
}
}
}
}
}
单点测试如下:
多点测试如下,一个使用蓝色一个使用红色,2个同时按下,可能是测试的有松开可以看到蓝色和红色分布不是很均匀。
经过lcd和触摸屏的简单测试,以后就可以做些比较好玩的东西了。
|