上一步点亮屏幕之后, 现在还不能触摸, 于是这篇讲下如何添加触摸
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