加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
    • 1. STM32CubeMX配置
    • 2. KEIL中添加触摸芯片驱动
    • 3. TouchGFX Designer中添加点击事件
    • 4. 下载测试
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

TouchGFX界面开发 | 添加触摸屏驱动

2023/10/09
4869
阅读需 28 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

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

1. STM32CubeMX配置

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

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; 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 将触摸驱动添加到TouchGFX中

将触摸驱动添加到触摸控制文件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中,创建一个按钮,实现点击后背景变色的功能⏩ 添加一个图标按钮,同时添加一个box作为背景

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

⏩ 点击Generate Code生成TouchGFX代码

4. 下载测试

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

 

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
AFBR-5803ATZ 1 Foxconn Transceiver, 1270nm Min, 1380nm Max, 125Mbps(Tx), 125Mbps(Rx), ST Connector, Through Hole Mount, ROHS COMPLIANT, SIP-9
$205.36 查看
LS027B7DH01A 1 Sharp Corp Graphic Dot Matrix LCD Display,
$40.78 查看
KSZ8863MLLI-TR 1 Microchip Technology Inc DATACOM, LAN SWITCHING CIRCUIT
$5.95 查看

相关推荐

电子产业图谱

公众号:嵌入式攻城狮;专注于分享和记录嵌入式开发技术,主要包含C语言、STM32、STM32CubeMX、lwIP、FreeRTOS、Linux、Zigbee、WIFI、BLE、LoRa、NB-loT、PCB电路设计、QT等等。