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

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

0 如何添加触摸代码

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

cubemx6.0配置touchgfx 正点原子触摸屏,touchgfx添加触摸驱动_第1张图片

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

要extern "C"来调用

cubemx6.0配置touchgfx 正点原子触摸屏,touchgfx添加触摸驱动_第2张图片

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; itouch_num = touch_num;
	if((touch_num&0XF)&&((touch_num&0XF)<6))
 {
	 for(int 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;
}

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: https://download.csdn.net/download/a2267542848/13628090

视频: https://www.bilibili.com/video/BV1cA411s7X7

你可能感兴趣的:(stm32,stm32,驱动程序)