如何添加触摸屏驱动到TouchGFX中?

描述

使用STM32CubeMX移植TouchGFX 一文中介绍了如何用TouchGFX点亮屏幕,但是此时屏幕还没有触摸的功能。下面将介绍如何添加触摸屏驱动到TouchGFX中

1. STM32CubeMX配置

在使用STM32CubeMX移植TouchGFX文中的STM32CubeMX配置基础上,再激活一个定时器,用来给IIC通信提供微秒(us)延时。本文通过软件来模拟IIC通信,因此不使用STM32CubeMX来进行IIC配置

stm32cubemx

2. KEIL中添加触摸芯片驱动

本文中的RGB (800 * 480)屏触摸驱动IC为FT5206芯片,该驱动芯片通过 4 根线与外部连接:CT_RST(PI8), CT_INT(PH7), CT_SDA(PI3), CT_SCL(PH6)。由于通过软件来模拟IIC通信,因此不使用STM32CubeMX来进行配置

2.1 添加微秒延时函数

在自动生成的tim.c文件中添加微秒延时函数,并在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芯片驱动

  在工程中添加FT5206芯片驱动头文件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芯片驱动文件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; itouch_num = touch_num;
 if((touch_num&0XF)&&((touch_num&0XF)<6))
 {
  for(i = 0;idir){
    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 将触摸驱动添加到TouchGFX中

  将触摸驱动添加到触摸控制文件STM32TouchController.cpp中

 

#include 

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中,创建一个按钮,实现点击后背景变色的功能 添加一个图标按钮,同时添加一个box作为背景

stm32cubemx

添加交互动作:实现点击图标按钮,背景颜色由黑色变为白色

stm32cubemx

点击Generate Code生成TouchGFX代码

4. 下载测试

回到Keil工程中,编译无误后,下载到开发板中。点击屏幕上的按钮,若屏幕背景色由黑色变为白色,说明点击成功,触摸驱动添加成功

stm32cubemx    







审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分