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


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

    一、STM32CubeMX配置

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

    在这里插入图片描述

    二、MKD-ARM 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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 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;
    
    }	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 在工程中添加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:%x\r\n",((uint16_t)temp[0]<<8)+temp[1]);
            return ;
        }
    		printf("CTP ID:%x\r\n",((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;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    三、TouchGFX Designer中添加点击事件

    在TouchGFX Designer中,创建一个按钮,实现点击后背景变色的功能

    • 添加一个图标按钮,同时添加一个box作为背景

    在这里插入图片描述

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

    在这里插入图片描述

    • 点击Generate Code生成TouchGFX代码

    四、下载测试

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

    在这里插入图片描述

  • 相关阅读:
    Makefile Npm
    Hvv--知攻善防应急响应靶机--Web2
    批量转换json到java bean工具说明
    力扣:129. 求根节点到叶节点数字之和(Python3)
    搬砖日记:关于sync用不了的问题
    TinyOs操作系统---第0章 课程概述
    代码随想录算法训练营第二十九天 | 回溯算法总结
    GraphPad Prism 10 for Mac(统计分析绘图软件)
    岩土工程安全监测利器:振弦采集仪的发展
    局部特征描述子和全局特征描述子
  • 原文地址:https://blog.csdn.net/Chuangke_Andy/article/details/129693959