cubemx6.0配置touchgfx 正点原子触摸屏,touchgfx添加触摸驱动

上一步点亮屏幕之后, 现在还不能触摸, 于是这篇讲下如何添加触摸

0 如何添加触摸代码

只需要在stm32Ouchcontroller.cpp中添加如何获取点就可以了

注意这个是c++写的, 传统的驱动是C写的,不能直接调用

要extern "C"来调用

1 正点原子驱动代码

正点原子代码有点乱, 我重写了下驱动

软件IIC, 通过宏定义方便移植, 同时把delay_us函数写到main.c中实现, 因为带操作系统和不带操作系统的delay_us实现方式不一样

并且如果时钟频率不一样那么就不能直接用

1 IIC软件驱动

#include "siic.h"


#define SIIC_SDA_PORT      GPIOI
#define SIIC_SDA_PIN  	GPIO_PIN_3
#define SIIC_SDA_PORT_LCK __HAL_RCC_GPIOI_CLK_ENABLE();   //使能GPIOH时钟


#define SIIC_SCL_PORT      GPIOH
#define SIIC_SCL_PIN  	GPIO_PIN_6
#define SIIC_SCL_PORT_LCK __HAL_RCC_GPIOH_CLK_ENABLE();   //使能GPIOH时钟


#define SIIC_SDA_H  HAL_GPIO_WritePin(SIIC_SDA_PORT,SIIC_SDA_PIN,GPIO_PIN_SET)
#define SIIC_SDA_L  HAL_GPIO_WritePin(SIIC_SDA_PORT,SIIC_SDA_PIN,GPIO_PIN_RESET)

#define SIIC_SCL_H  HAL_GPIO_WritePin(SIIC_SCL_PORT,SIIC_SCL_PIN,GPIO_PIN_SET)
#define SIIC_SCL_L  HAL_GPIO_WritePin(SIIC_SCL_PORT,SIIC_SCL_PIN,GPIO_PIN_RESET)

#define SIIC_SPEED_DELAY()       delay_us(2)
#define SIIC_SPEED_START_DELAY()  delay_us(30)


void SIIC_SDA_OUT()
{
		GPIO_InitTypeDef GPIO_Initure;
    //SDA
    GPIO_Initure.Pin=SIIC_SDA_PIN;
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(SIIC_SDA_PORT,&GPIO_Initure);     //初始化
}
void SIIC_SIIC_SDA_IN()
{
		GPIO_InitTypeDef GPIO_Initure;
    //SDA
    GPIO_Initure.Pin=SIIC_SDA_PIN;
    GPIO_Initure.Mode=GPIO_MODE_INPUT;  //推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(SIIC_SDA_PORT,&GPIO_Initure);     //初始化
}

uint8_t SIIC_SIIC_SDA_Read(void)
{
	
    return HAL_GPIO_ReadPin(SIIC_SDA_PORT,SIIC_SDA_PIN);
}

void SIIC_SIIC_SDA_Write(uint8_t state)
{
    HAL_GPIO_WritePin(SIIC_SDA_PORT,SIIC_SDA_PIN,state);
}



//SIIC初始化
void SIIC_Init(void)
{
		GPIO_InitTypeDef GPIO_Initure;

    SIIC_SDA_PORT_LCK;
    SIIC_SCL_PORT_LCK;

    // SCL
    GPIO_Initure.Pin=SIIC_SCL_PIN;
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(SIIC_SCL_PORT,&GPIO_Initure);     //初始化

    //SDA
    GPIO_Initure.Pin=SIIC_SDA_PIN;
    HAL_GPIO_Init(SIIC_SDA_PORT,&GPIO_Initure);     //初始化

    SIIC_SDA_H;
    SIIC_SCL_H;
}

//产生SIIC起始信号
void SIIC_Start(void)
{
    SIIC_SDA_OUT();     //sda线输出
    SIIC_SDA_H;
    SIIC_SCL_H;
    SIIC_SPEED_START_DELAY();
    SIIC_SDA_L;//START:when CLK is high,DATA change form high to low
    SIIC_SPEED_DELAY();
    SIIC_SCL_L;//钳住I2C总线,准备发送或接收数据
}
//产生SIIC停止信号
void SIIC_Stop(void)
{
    SIIC_SDA_OUT();//sda线输出
    SIIC_SCL_L;
    SIIC_SDA_L;//STOP:when CLK is high DATA change form low to high
    SIIC_SPEED_START_DELAY();
    SIIC_SCL_H;
    SIIC_SPEED_DELAY();
    SIIC_SDA_H;//发送I2C总线结束信号

}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
uint8_t SIIC_Wait_Ack(void)
{
    uint8_t ucErrTime=0;
    SIIC_SIIC_SDA_IN();
    SIIC_SDA_H;
    SIIC_SCL_H;
    SIIC_SPEED_DELAY();
    while(SIIC_SIIC_SDA_Read())
    {
        ucErrTime++;
        if(ucErrTime>250)
        {
            SIIC_Stop();
            return 1;
        }
        SIIC_SPEED_DELAY();
    }
    SIIC_SCL_L;//时钟输出0
    return 0;
}
//产生ACK应答
void SIIC_Ack(void)
{
    SIIC_SCL_L;
    SIIC_SDA_OUT();
    SIIC_SDA_L;
    SIIC_SPEED_DELAY();
    SIIC_SCL_H;
    SIIC_SPEED_DELAY();
    SIIC_SCL_L;
}
//不产生ACK应答
void SIIC_NAck(void)
{
    SIIC_SCL_L;
    SIIC_SDA_OUT();
    SIIC_SDA_H;
    SIIC_SPEED_DELAY();
    SIIC_SCL_H;
    SIIC_SPEED_DELAY();
    SIIC_SCL_L;
}
//SIIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void SIIC_Send_Byte(uint8_t txd)
{
    uint8_t t;
    SIIC_SDA_OUT();
    SIIC_SCL_L;//拉低时钟开始数据传输
    for(t=0; t<8; t++)
    {

        SIIC_SIIC_SDA_Write(((txd&0x80)>>7));
        txd<<=1;
        SIIC_SPEED_DELAY();   //对TEA5767这三个延时都是必须的
        SIIC_SCL_H;
        SIIC_SPEED_DELAY();
        SIIC_SCL_L;
        SIIC_SPEED_DELAY();
    }
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
uint8_t SIIC_Read_Byte(unsigned char ack)
{
    unsigned char i,receive=0;
    SIIC_SIIC_SDA_IN();//SDA设置为输入
    SIIC_SPEED_START_DELAY();
    for(i=0; i<8; i++ )
    {
        SIIC_SCL_L;
        SIIC_SPEED_DELAY();
        SIIC_SCL_H;
        receive<<=1;
        if(SIIC_SIIC_SDA_Read())
        {

            receive++;
        }
        SIIC_SPEED_DELAY();
    }
    if (!ack)
        SIIC_NAck();//发送nACK
    else
        SIIC_Ack(); //发送ACK
    return receive;
}

2 ft5206驱动

#include "ft5206.h"
#include "siic.h"


//I2C读写命令
#define FT_CMD_WR 				0X70    	//写命令
#define FT_CMD_RD 				0X71		//读命令

//FT5206 部分寄存器定义
#define FT_DEVIDE_MODE 					0x00   		//FT5206模式控制寄存器
#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   		//FT5206中断模式控制寄存器
#define FT_ID_G_THGROUP				0x80   		//触摸有效值设置寄存器
#define FT_ID_G_PERIODACTIVE	0x88   		//激活状态周期设置寄存器


static const uint16_t FT5206_TPX_TBL[5]={FT_TP1_REG,FT_TP2_REG,FT_TP3_REG,FT_TP4_REG,FT_TP5_REG};

static void delay_ms(uint32_t time)
{
    HAL_Delay(time);
}
uint8_t FT5206_WR_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
{
    uint8_t i;
    uint8_t ret=0;
    SIIC_Start();
    SIIC_Send_Byte(FT_CMD_WR);	//发送写命令
    SIIC_Wait_Ack();
    SIIC_Send_Byte(reg&0XFF);   	//发送低8位地址
    SIIC_Wait_Ack();
    for(i=0; i<len; i++)
    {
        SIIC_Send_Byte(buf[i]);  	//发数据
        ret=SIIC_Wait_Ack();
        if(ret)break;
    }
    SIIC_Stop();					//产生一个停止条件
    return ret;
}
//从FT5206读出一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:读数据长度
void FT5206_RD_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
{
    uint8_t i;
    SIIC_Start();
    SIIC_Send_Byte(FT_CMD_WR);   	//发送写命令
    SIIC_Wait_Ack();
    SIIC_Send_Byte(reg&0XFF);   	//发送低8位地址
    SIIC_Wait_Ack();
    SIIC_Start();
    SIIC_Send_Byte(FT_CMD_RD);   	//发送读命令
    SIIC_Wait_Ack();
    for(i=0; i<len; i++)
    {
        buf[i]=SIIC_Read_Byte(i==(len-1)?0:1); //发数据
    }
    SIIC_Stop();	//产生一个停止条件
}

void ft5206_init(void)
{
    uint8_t temp[2];
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_GPIOH_CLK_ENABLE();			//开启GPIOH时钟
    __HAL_RCC_GPIOI_CLK_ENABLE();			//开启GPIOI时钟

    //PH7
    GPIO_Initure.Pin=GPIO_PIN_7;            //PH7
    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;            //PI8
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    HAL_GPIO_Init(GPIOI,&GPIO_Initure);     //初始化

    SIIC_Init();

		HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_RESET);				//复位
    delay_ms(20);
    HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_SET);				//释放复位
    delay_ms(50);
    temp[0]=0;
    FT5206_WR_Reg(FT_DEVIDE_MODE,temp,1);	//进入正常操作模式
    FT5206_WR_Reg(FT_ID_G_MODE,temp,1);		//查询模式
    temp[0]=22;								//触摸有效值,22,越小越灵敏
    FT5206_WR_Reg(FT_ID_G_THGROUP,temp,1);	//设置触摸有效值
    temp[0]=12;								//激活周期,不能小于12,最大14
    FT5206_WR_Reg(FT_ID_G_PERIODACTIVE,temp,1);
    //读取版本号,参考值:0x3003
    FT5206_RD_Reg(FT_ID_G_LIB_VERSION,&temp[0],2);
    if((temp[0]==0X30&&temp[1]==0X03)||temp[1]==0X01||temp[1]==0X02)//版本:0X3003/0X0001/0X0002
    {
        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(int 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;
}

3 touch.h头文件

这个的目的是为了兼容不同种类的触摸屏, 虽然我只有一块屏幕

#ifndef _touch_H
#define _touch_H

#include "main.h"

#define TOUCH_MAX_NUM 5
typedef struct TouchTypedef_TAG
{
	uint8_t touch_type;
	uint8_t dir;
	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;


#endif

3 添加触摸驱动到touchgfx中

extern "C"
{
	#include "ft5206.h"
	void ft5206_init(void);
	uint8_t ft5206_scan(TouchTypedef *touch);
}
TouchTypedef mtouch;

void STM32TouchController::init()
{
    /**
     * Initialize touch controller and driver
     *
     */
	ft5206_init();
	mtouch.dir = PIXELS_DIR;
	mtouch.pix_h = PIXELS_H;
	mtouch.pix_w = PIXELS_W;
}

bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y)
{
    /**
     * By default sampleTouch returns false,
     * return true if a touch has been detected, otherwise false.
     *
     * Coordinates are passed to the caller by reference by x and y.
     *
     * This function is called by the TouchGFX framework.
     * By default sampleTouch is called every tick, this can be adjusted by HAL::setTouchSampleRate(int8_t);
     *
     */
		if(ft5206_scan(&mtouch)){
			x = mtouch.x[0];
			y = mtouch.y[0];
			return true;
		}
    return false;
}

地址: https://github.com/KiritoGoLeon/stm32-HAL-learn/tree/master/stm32_f429_cubemx_touchgfx

csdn: stm32cubemx6.0配置原子7寸rgb1024x600touchgfx-互联网文档类资源-CSDN下载

视频: Stm32f249使用cubemx6.0配置touchgfx 4.15_哔哩哔哩_bilibili

链接:https://pan.baidu.com/s/1ooMOsiQqckzCP3afEqD7Xg 
提取码:a6pc

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 威纶通触摸屏编程教程v6.0 是一本适用于 HMI(人机界面)开发及编程的教程手册。该教程以实践为主,结合实例讲解了如何使用威纶通编辑器进行触摸屏的设计和编程,同时涉及了相关软件的安装、配置、组态及调试。针对不同的应用场景,教程还介绍了如何进行数据采集、通信控制、多语言支持和密码保护等常用功能的实现。 威纶通触摸屏编程教程采用简洁明了的文字和图表,让读者易于理解和记忆。教程不仅适用于工程师和技术人员,在学校里学习HMI编程的学生也可以从中受到启发和帮助,作为一个初学者,可以先从最基础的操作开始,逐渐掌握轻松操作,一步步搭建起自己的人机界面。 总之,威纶通触摸屏编程教程v6.0是一本含有丰富实例和操作步骤的教程书籍,对于需要使用HMI开发和编程的读者来说,是一本非常有价值的学习资料。 ### 回答2: 威纶通触摸屏编程教程v6.0是一本非常实用的编程教程。该教程内容丰富,一共分为13个章节,每一章节都介绍了不同的触摸屏编程技巧和相关知识。此外,在教程中还包含了大量的实例和案例,让读者可以更好地理解和掌握编程技巧。 其中,第一章介绍了威纶通触摸屏编程的基础知识,包括触摸屏的概念和原理、威纶通触摸屏的硬件、编程软件和环境搭建等内容。接下来的几章则介绍了不同的编程技巧,包括界面设计、图形绘制、键盘输入、触摸事件等。 在第六章,该教程还介绍了常见的触摸屏控件,如按键、滑动条、选择器等,让读者可以学会制作更加复杂的图形界面。此外,该教程还介绍了触摸屏编程中常用的通信协议和网络操作,并提供了实例代码,让读者可以进行实践操作。 总之,威纶通触摸屏编程教程v6.0是一本非常实用和详细的教程,对于想要学习和掌握触摸屏编程技巧的读者来说是一本必备的参考书。 ### 回答3: 威纶通技术是一家专业的触摸屏生产厂家,公司自主研发了一款触摸屏编程软件,即威纶通触摸屏编程教程v6.0。该软件是威纶通公司多年的技术积累和市场经验的结晶,具备了强大的屏幕控制能力和丰富的人机交互界面设计功能,可以为客户提供量身定制的触摸屏控制方案。 威纶通触摸屏编程教程v6.0支持多种编程语言,如C、C++、VB、.NET等,同时支持PLC、HMI、PC等多种控制设备的数据通信。在编程过程中,使用者可以通过易于操作的图形界面完成屏幕元件的添加、编辑和布局,还可以自定义控件的样式和属性,从而实现触摸屏的个性化设计。 除了基本的控件和事件处理外,威纶通触摸屏编程教程v6.0还提供了完善的屏幕动画效果、中英文多语言支持、自定义字库等功能,让使用者能够轻松地打造出高效、美观、易用的触摸屏控制界面。此外,软件还配备了丰富的示例程序和用户手册,让使用者可以快速学习和掌握编程技巧,上手编写出符合自己需求的触摸屏程序。 总之,威纶通触摸屏编程教程v6.0是一款集成了强大功能与友好操作的触摸屏编程软件,为广大客户提供了高效、灵活、可靠的控制方案,受到了业界的广泛认可和好评。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值