使用STM32CubeMX移植TouchGFX?一文中介紹了如何用TouchGFX點亮屏幕,但是此時屏幕還沒有觸摸的功能。下面將介紹如何添加觸摸屏驅(qū)動到TouchGFX中
1. STM32CubeMX配置
在使用STM32CubeMX移植TouchGFX文中的STM32CubeMX配置基礎(chǔ)上,再激活一個定時器,用來給IIC通信提供微秒(us)延時。本文通過軟件來模擬IIC通信,因此不使用STM32CubeMX來進行IIC配置
2.?KEIL中添加觸摸芯片驅(qū)動
本文中的RGB (800 * 480)屏觸摸驅(qū)動IC為FT5206芯片,該驅(qū)動芯片通過 4 根線與外部連接:CT_RST(PI8), CT_INT(PH7), CT_SDA(PI3), CT_SCL(PH6)。由于通過軟件來模擬IIC通信,因此不使用STM32CubeMX來進行配置
2.1?添加微秒延時函數(shù)
在自動生成的tim.c文件中添加微秒延時函數(shù),并在tim.h中聲明
void?delay_us(uint16_t?us)
{
?uint16_t?differ?=?0xffff?-?us?-5;
?__HAL_TIM_SET_COUNTER(&htim6,?differ);
?HAL_TIM_Base_Start(&htim6);
?
?while(differ?<?0xffff?-?5){
??differ?=?__HAL_TIM_GET_COUNTER(&htim6);
?}
?
?HAL_TIM_Base_Stop(&htim6);
}
2.2?軟件模擬IIC通信
??IIC通信頭文件:在工程中添加IIC通信頭文件ctiic.h
#ifndef?__CT_IIC_H
#define?__CT_IIC_H
#include?"main.h"
#define?IIC_SDA_PORT?GPIOI
#define?IIC_SDA_PIN??GPIO_PIN_3
#define?IIC_SCL_PORT?GPIOH
#define?IIC_SCL_PIN??GPIO_PIN_6
#define?SET_SDA_PIN_H?HAL_GPIO_WritePin(IIC_SDA_PORT,?IIC_SDA_PIN,?GPIO_PIN_SET)
#define?SET_SDA_PIN_L?HAL_GPIO_WritePin(IIC_SDA_PORT,?IIC_SDA_PIN,?GPIO_PIN_RESET)
#define?SET_SCL_PIN_H?HAL_GPIO_WritePin(IIC_SCL_PORT,?IIC_SCL_PIN,?GPIO_PIN_SET)
#define?SET_SCL_PIN_L?HAL_GPIO_WritePin(IIC_SCL_PORT,?IIC_SCL_PIN,?GPIO_PIN_RESET)
void?SET_SDA_DIR_OUT(void);
void?SET_SDA_DIR_IN(void);
uint8_t?READ_IIC_SDA(void);
void?WRITE_IIC_SDA(uint8_t?state);
void?IIC_Init(void);
void?IIC_Start(void);
void?IIC_Stop(void);
uint8_t?IIC_Wait_Ack(void);
void?IIC_Ack(void);
void?IIC_NAck(void);
void?IIC_Send_Byte(uint8_t?txd);
uint8_t?IIC_Read_Byte(unsigned?char?ack);
#endif
? IIC通信源文件:在工程中添加IIC通信源文件ctiic.c
#include?"ctiic.h"
#include?"tim.h"
void?SET_SDA_DIR_OUT(void)
{
? GPIO_InitTypeDef?GPIO_Initure;
????
??GPIO_Initure.Pin???=?IIC_SDA_PIN;????????????
??GPIO_Initure.Mode??=?GPIO_MODE_OUTPUT_PP;??
??GPIO_Initure.Pull??=?GPIO_PULLUP;??????????
??GPIO_Initure.Speed?=?GPIO_SPEED_HIGH;
?
??HAL_GPIO_Init(IIC_SDA_PORT,?&GPIO_Initure);?????
}
?
void?SET_SDA_DIR_IN(void)
{
? GPIO_InitTypeDef?GPIO_Initure;
????
??GPIO_Initure.Pin???=?IIC_SDA_PIN;????????????
??GPIO_Initure.Mode??=?GPIO_MODE_INPUT;??
??GPIO_Initure.Pull??=?GPIO_PULLUP;??????????
??GPIO_Initure.Speed?=?GPIO_SPEED_HIGH;
?
??HAL_GPIO_Init(IIC_SDA_PORT,?&GPIO_Initure);?????
}?
uint8_t?READ_IIC_SDA(void)
{
? return?HAL_GPIO_ReadPin(IIC_SDA_PORT,?IIC_SDA_PIN);
}?
void?WRITE_IIC_SDA(uint8_t?state)
{
? HAL_GPIO_WritePin(IIC_SDA_PORT,?IIC_SDA_PIN,?state);
}?
void?IIC_Init()
{
? GPIO_InitTypeDef?GPIO_Initure;
? __HAL_RCC_GPIOI_CLK_ENABLE();
?__HAL_RCC_GPIOH_CLK_ENABLE();
????
??GPIO_Initure.Pin???=?IIC_SCL_PIN;????????????
??GPIO_Initure.Mode??=?GPIO_MODE_OUTPUT_PP;??
??GPIO_Initure.Pull??=?GPIO_PULLUP;??????????
??GPIO_Initure.Speed?=?GPIO_SPEED_HIGH;?
??HAL_GPIO_Init(IIC_SCL_PORT,?&GPIO_Initure);????
?
? GPIO_Initure.Pin???=?IIC_SDA_PIN;????????????
??HAL_GPIO_Init(IIC_SDA_PORT,?&GPIO_Initure);
? SET_SDA_PIN_H;
? SET_SCL_PIN_H;
}?
void?IIC_Start()
{
? SET_SDA_DIR_OUT();
?SET_SDA_PIN_H;
?SET_SCL_PIN_H;
?delay_us(30);
?SET_SDA_PIN_L;
?delay_us(2);
?SET_SCL_PIN_L;
}?
void?IIC_Stop(void)
{
?SET_SDA_DIR_OUT();
?SET_SCL_PIN_L;
?SET_SDA_PIN_L;
?delay_us(30);
?SET_SCL_PIN_H;
?delay_us(2);
?SET_SDA_PIN_H;
}
uint8_t?IIC_Wait_Ack(void)
{
?uint8_t?ucErrTime?=?0;
?SET_SDA_DIR_IN();
?SET_SDA_PIN_H;
?SET_SCL_PIN_H;
?delay_us(2);
?while(READ_IIC_SDA()){
??ucErrTime++;
? ?if(ucErrTime?>?250){
???IIC_Stop();
???return?1;
??}
??delay_us(2);
?}
?SET_SCL_PIN_L;
?return?0;
}?
void?IIC_Ack(void)
{
?SET_SCL_PIN_L;
?SET_SDA_DIR_OUT();
?SET_SDA_PIN_L;
?delay_us(2);
?SET_SCL_PIN_H;
?delay_us(2);
?SET_SCL_PIN_L;
}?
void?IIC_NAck(void)
{
?SET_SCL_PIN_L;
?SET_SDA_DIR_OUT();
?SET_SDA_PIN_H;
?delay_us(2);
?SET_SCL_PIN_H;
?delay_us(2);
?SET_SCL_PIN_L;
}?
void?IIC_Send_Byte(uint8_t?txd)
{
??uint8_t?t;???
?SET_SDA_DIR_OUT();
?SET_SCL_PIN_L;
?for(t=0;t<8;t++){??????????????
????WRITE_IIC_SDA((txd&0x80)>>7);
????txd?<<=?1;?
?? delay_us(2);???????
? ?SET_SCL_PIN_H;
? ??delay_us(2);
? ??SET_SCL_PIN_L;
? ?delay_us(2);?
??}??
}?
uint8_t?IIC_Read_Byte(unsigned?char?ack)
{
? uint8_t?i,receive?=?0;
?SET_SDA_DIR_IN();
?delay_us(30);
?for(i=0;i<8;i++?)
?{?
? ?SET_SCL_PIN_L;
? ?delay_us(2);
??SET_SCL_PIN_H;??
??receive?<<=?1;
??if(READ_IIC_SDA())
???receive++;?
??delay_us(2);?
?}????????
?if?(!ack)
?? IIC_NAck();
?else?
?? IIC_Ack();???
?return?receive;
}?
2.3 FT5206芯片驅(qū)動
?在工程中添加FT5206芯片驅(qū)動頭文件ft5206.h
#ifndef?__FT5206_H
#define?__FT5206_H
#include?"ctiic.h"
#define?FT_CMD_WR?????0X70?????
#define?FT_CMD_RD?????0X71??
??
#define?FT_DEVIDE_MODE????0x00?????
#define?FT_REG_NUM_FINGER???????0x02??
#define?FT_TP1_REG?????0X03????
#define?FT_TP2_REG?????0X09??
#define?FT_TP3_REG?????0X0F??
#define?FT_TP4_REG?????0X15??
#define?FT_TP5_REG?????0X1B??
#define?FT_ID_G_LIB_VERSION??0xA1??
#define?FT_ID_G_MODE????0xA4?????
#define?FT_ID_G_THGROUP???0x80?????
#define?FT_ID_G_PERIODACTIVE?0x88?????
#define?TOUCH_MAX_NUM?5
typedef?struct
{
?uint8_t?touch_type;
?uint8_t?dir;???//0表示豎屏,1表示橫屏
?uint16_t?pix_w;
?uint16_t?pix_h;
?uint8_t?touch_num;
?uint16_t?x[TOUCH_MAX_NUM];
?uint16_t?y[TOUCH_MAX_NUM];?
}TouchTypedef;
uint8_t?FT5206_WR_Reg(uint16_t?reg,?uint8_t?*buf,?uint8_t?len);
void?FT5206_RD_Reg(uint16_t?reg,?uint8_t?*buf,?uint8_t?len);
void?FT5206_Init(void);
uint8_t?FT5206_Scan(TouchTypedef?*touch);
#endif
? 在工程中添加FT5206芯片驅(qū)動文件ft5206.c
#include?"ft5206.h"
#include?"stdio.h"
static?const?uint16_t?FT5206_TPX_TBL[5]={FT_TP1_REG,?FT_TP2_REG,?FT_TP3_REG,?FT_TP4_REG,?FT_TP5_REG};
uint8_t?FT5206_WR_Reg(uint16_t?reg,?uint8_t?*buf,?uint8_t?len)
{
???uint8_t?i;
????uint8_t?ret=0;
????IIC_Start();
????IIC_Send_Byte(FT_CMD_WR);?
????IIC_Wait_Ack();
????IIC_Send_Byte(reg&0XFF);???
????IIC_Wait_Ack();
????for(i=0;?i<len;?i++)
????{
????????IIC_Send_Byte(buf[i]);???
????????ret?=?IIC_Wait_Ack();
????????if(ret)break;
????}
????IIC_Stop();?????
????return?ret;
}
void?FT5206_RD_Reg(uint16_t?reg,?uint8_t?*buf,?uint8_t?len)
{
????uint8_t?i;
????IIC_Start();
????IIC_Send_Byte(FT_CMD_WR);????
????IIC_Wait_Ack();
????IIC_Send_Byte(reg&0XFF);????
????IIC_Wait_Ack();
????IIC_Start();
????IIC_Send_Byte(FT_CMD_RD);????
????IIC_Wait_Ack();
????for(i=0;?i<len;?i++)
????{
????????buf[i]=IIC_Read_Byte(i==(len-1)?0:1);?
????}
????IIC_Stop();?
}
void?FT5206_Init(void)
{
????uint8_t?temp[2];
????GPIO_InitTypeDef?GPIO_Initure;
?
????__HAL_RCC_GPIOH_CLK_ENABLE();???
????__HAL_RCC_GPIOI_CLK_ENABLE();???
?
????//PH7
????GPIO_Initure.Pin=GPIO_PIN_7;????????????
????GPIO_Initure.Mode=GPIO_MODE_INPUT;??????
????GPIO_Initure.Pull=GPIO_PULLUP;??????????
????GPIO_Initure.Speed=GPIO_SPEED_HIGH;?????
????HAL_GPIO_Init(GPIOH,&GPIO_Initure);????
?
????//PI8
????GPIO_Initure.Pin=GPIO_PIN_8;????????????
????GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;??
????HAL_GPIO_Init(GPIOI,&GPIO_Initure);????
?
????IIC_Init();
?
? HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_RESET);????
????HAL_Delay(20);
????HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_SET);????
????HAL_Delay(50);
????temp[0]=0;
????FT5206_WR_Reg(FT_DEVIDE_MODE,temp,1);?
????FT5206_WR_Reg(FT_ID_G_MODE,temp,1);??
????temp[0]=22;????????
????FT5206_WR_Reg(FT_ID_G_THGROUP,temp,1);?
????temp[0]=12;???????
????FT5206_WR_Reg(FT_ID_G_PERIODACTIVE,temp,1);
???
????FT5206_RD_Reg(FT_ID_G_LIB_VERSION,&temp[0],2);
????if((temp[0]==0X30&&temp[1]==0X03)||temp[1]==0X01||temp[1]==0X02)
????{
????????printf("CTP?ID:%xrn",((uint16_t)temp[0]<<8)+temp[1]);
????????return?;
????}
??printf("CTP?ID:%xrn",((uint16_t)temp[0]<<8)+temp[1]);
}?
uint8_t?FT5206_Scan(TouchTypedef?*touch)
{
?uint8_t?buf[4];
?uint8_t?touch_num;
?uint8_t?i?=?0;
?//uint8_t?touch_state?=?0;
?FT5206_RD_Reg(FT_REG_NUM_FINGER,&touch_num,1);
?touch->touch_num?=?touch_num;
?if((touch_num&0XF)&&((touch_num&0XF)<6))
?{
??for(i?=?0;i<touch_num;i++){
???FT5206_RD_Reg(FT5206_TPX_TBL[i],buf,4);
???uint16_t?x?=?0;
???uint16_t?y?=?0;
???
???if(touch->dir){
????y?=?((uint16_t)(buf[0]&0X0F)<<8)+buf[1];
????x?=?((uint16_t)(buf[2]&0X0F)<<8)+buf[3];
???}else{
???x?=?touch->pix_h?-?(((uint16_t)(buf[0]&0X0F)<<8)+buf[1]);
????y?=?((uint16_t)(buf[2]&0X0F)<<8)+buf[3];
???}
???touch->x[i]?=?x;
???touch->y[i]?=?y;
??}
?}else{
??touch->touch_num?=?0;
??return?0;
?}
?return?touch_num;
}
2.4?將觸摸驅(qū)動添加到TouchGFX中
將觸摸驅(qū)動添加到觸摸控制文件STM32TouchController.cpp中
#include?<STM32TouchController.hpp>
extern?"C"{
#include?"ft5206.h"
}
TouchTypedef?mtouch;
void?STM32TouchController::init()
{
?FT5206_Init();
?mtouch.dir?=?1;
?mtouch.pix_w?=?800;
?mtouch.pix_h?=?480;
}
bool?STM32TouchController::sampleTouch(int32_t&?x,?int32_t&?y)
{
?if(FT5206_Scan(&mtouch)){
??x?=?mtouch.x[0];
??y?=?mtouch.y[0];
??return?true;
?}?
????return?false;
}
3.?TouchGFX Designer中添加點擊事件
在TouchGFX Designer中,創(chuàng)建一個按鈕,實現(xiàn)點擊后背景變色的功能? 添加一個圖標按鈕,同時添加一個box作為背景
? 添加交互動作:實現(xiàn)點擊圖標按鈕,背景顏色由黑色變?yōu)榘咨?/p>
? 點擊Generate Code生成TouchGFX代碼
4.?下載測試
回到Keil工程中,編譯無誤后,下載到開發(fā)板中。點擊屏幕上的按鈕,若屏幕背景色由黑色變?yōu)榘咨f明點擊成功,觸摸驅(qū)動添加成功