前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >STM32F103驱动GT911

STM32F103驱动GT911

作者头像
全栈程序员站长
发布2022-09-07 10:36:56
1.6K1
发布2022-09-07 10:36:56
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

0x00 引脚连接:

// SCL——-PB10 // SDA——-PB11 // INT——–PB1 // RST——–PB2

IIC的SCL与SDA需要接上拉电阻!

0x01 模拟IIC:

在模拟IIC的头文件中:

定义所需的IO操作宏:

//IO操作函数 #define IIC_SCL PBout(10) //SCL #define IIC_SDA PBout(11) //SDA #define READ_SDA PBin(11) //输入SDA

宏定义模拟IIC的引脚:

#define GT911_PIN_SCL GPIO_Pin_10 #define GT911_PIN_SDA GPIO_Pin_11

在模拟IIC的C源文件中实现相关函数:

void SDA_IN(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GT911_PIN_SDA; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); }

void SDA_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GT911_PIN_SDA; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); }

//初始化IIC void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); GPIO_InitStructure.GPIO_Pin = GT911_PIN_SCL|GT911_PIN_SDA; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GT911_PIN_SCL|GT911_PIN_SDA); } //产生IIC起始信号 void IIC_Start(void) { SDA_OUT(); IIC_SDA=1; IIC_SCL=1; delay_us(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4); IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { SDA_OUT(); IIC_SCL=0; IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号 delay_us(4); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 u8 IIC_Wait_Ack(void) { u8 ucErrTime=0; SDA_IN(); //SDA设置为输入 IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } } IIC_SCL=0;//时钟输出0 return 0; } //产生ACK应答 void IIC_Ack(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=0; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0; } //不产生ACK应答 void IIC_NAck(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=1; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(u8 txd) { u8 t; SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输 for(t=0;t<8;t++) { //IIC_SDA=(txd&0x80)>>7; if((txd&0x80)>>7) IIC_SDA=1; else IIC_SDA=0; txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的 IIC_SCL=1; delay_us(2); IIC_SCL=0; delay_us(2); } } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; SDA_IN();//SDA设置为输入 for(i=0;i<8;i++ ) { IIC_SCL=0; delay_us(2); IIC_SCL=1; receive<<=1; if(READ_SDA)receive++; delay_us(1); } if (!ack) IIC_NAck();//发送nACK else IIC_Ack(); //发送ACK return receive; }

0x02 初始化GT911:

查阅《GT911编程指南》:

GT911上电时序
GT911上电时序

IIC通信地址选择 0x28/0x29,在头文件中加入相关声明和定义:

//I2C读写命令 #define GT_CMD_WR 0X28 //写命令 #define GT_CMD_RD 0X29 //读命令 //GT911 部分寄存器定义 #define GT_CTRL_REG 0X8040 //GT911控制寄存器 #define GT_CFGS_REG 0X8047 //GT911配置起始地址寄存器 #define GT_CHECK_REG 0X80FF //GT911校验和寄存器 #define GT_PID_REG 0X8140 //GT911产品ID寄存器

#define GT_GSTID_REG 0X814E //GT911当前检测到的触摸情况

#define GT911_PIN_INT GPIO_Pin_1 #define GT911_PIN_RST GPIO_Pin_2

typedef struct _POINT{ u16 x; u16 y; }POINT, *PPOINT;

typedef struct _GT911_POINT_DATA{ u8 cnt; POINT points[5]; }GT911_POINT_DATA, *PGT911_POINT_DATA;

extern GT911_POINT_DATA gt911_data;

在C源文件中添加GT911初始化所需要的准备函数:

void GT911_INT_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GT911_PIN_INT; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB, GT911_PIN_INT); }

void GT911_INT(u8 cmd) { if(cmd) GPIO_SetBits(GPIOB, GT911_PIN_INT); else GPIO_ResetBits(GPIOB, GT911_PIN_INT); }

void GT911_INT_Change(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GT911_PIN_INT; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB, GT911_PIN_INT); }

void GT911_RST_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GT911_PIN_RST; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB, GT911_PIN_RST); }

void GT911_RST(u8 cmd) { if(cmd) GPIO_SetBits(GPIOB, GT911_PIN_RST); else GPIO_ResetBits(GPIOB, GT911_PIN_RST); }

按照时序GT911上电初始化大致流程如下(IIC通信地址选择 0x28/0x29):

GT911_RST_Init(); GT911_INT_Init(); IIC_Init(); GT911_RST(0); GT911_INT(1); delay_us(200); GT911_RST(1); delay_ms(6); GT911_INT(0); delay_ms(55); GT911_INT_Change(); delay_ms(50);

在C源文件中添加读写GT911寄存器以及修改配置的相关函数:

//reg:起始寄存器地址 //buf:数据缓缓存区 //len:写数据长度 //返回值:0,成功;1,失败. u8 GT911_WR_Reg(u16 reg,u8 *buf,u8 len) { u8 i; u8 ret=0; IIC_Start(); IIC_Send_Byte(GT_CMD_WR); //发送写命令 IIC_Wait_Ack(); IIC_Send_Byte(reg>>8); //发送高8位地址 IIC_Wait_Ack(); IIC_Send_Byte(reg&0XFF); //发送低8位地址 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; }

//reg:起始寄存器地址 //buf:数据缓缓存区 //len:读数据长度 void GT911_RD_Reg(u16 reg,u8 *buf,u8 len) { u8 i; IIC_Start(); IIC_Send_Byte(GT_CMD_WR); //发送写命令 IIC_Wait_Ack(); IIC_Send_Byte(reg>>8); //发送高8位地址 IIC_Wait_Ack(); IIC_Send_Byte(reg&0XFF); //发送低8位地址 IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(GT_CMD_RD); //发送读命令 IIC_Wait_Ack(); for(i=0;i<len;i++) { buf[i]=IIC_Read_Byte(i==(len-1)?0:1); //发数据 } IIC_Stop();//产生一个停止条件 }

//发送配置参数 //mode:0,参数不保存到flash // 1,参数保存到flash u8 GT911_Send_Cfg(u8 mode) { u8 buf[2]; u8 i=0; buf[0]=0; buf[1]=mode; //是否写入到GT911 FLASH? 即是否掉电保存 for(i=0;i<sizeof(GT911_Cfg);i++)buf[0]+=GT911_Cfg[i];//计算校验和 buf[0]=(~buf[0])+1; GT911_WR_Reg(GT_CFGS_REG,(u8*)GT911_Cfg,sizeof(GT911_Cfg));//发送寄存器配置 GT911_WR_Reg(GT_CHECK_REG,buf,2);//写入校验和,和配置更新标记 return 0; }

其中GT911_Cfg为寄存器配置数据,一般由厂商直接提供

完整的GT911初始化代码如下:

void GT911_Init(void) { GT911_RST_Init(); GT911_INT_Init(); IIC_Init(); GT911_RST(0); GT911_INT(1); delay_us(200); GT911_RST(1); delay_ms(6); GT911_INT(0); delay_ms(55); GT911_INT_Change(); delay_ms(50); u8 tmp[4]={0}; //读取PID GT911_RD_Reg(GT_PID_REG, tmp, 4); //修改配置 tmp[0] = 0x02; GT911_WR_Reg(GT_CTRL_REG, tmp, 1); GT911_RD_Reg(GT_CFGS_REG, tmp, 1); if(tmp[0] < 0x60){ printf(“Default Ver:0x%X\r\n”,tmp[0]); GT911_Send_Cfg(1); } delay_ms(10); tmp[0] = 0x00; GT911_WR_Reg(GT_CTRL_REG, tmp, 1); EXTIX_Init(); }

0x03 中断接收GT911坐标数据:

GT911所连引脚外部中断初始化(PB1):

void EXTIX_Init(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);

EXTI_InitStructure.EXTI_Line=EXTI_Line1; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }

中断服务函数:

查阅《GT911编程指南》:

GT911坐标数据读取
GT911坐标数据读取

void EXTI1_IRQHandler(void) { u8 tmp; GT911_RD_Reg(0x8140, data, 0x40); tmp = data[0x0E]; if((tmp&0x80) && ((tmp&0x0f)>0)){ GetPointData(tmp&0x0f, data); ShowPointData(); } tmp = 0; GT911_WR_Reg(0x814E, &tmp, 1); delay_ms(10); EXTI_ClearITPendingBit(EXTI_Line1); }

data为全局数据(0x8140-0x8180一共0x40个数据),直接一次性读出所有的数据

其中获取和打印坐标的相关函数:

在GT911的头文件中:extern GT911_POINT_DATA gt911_data;

void GetPointData(u8 cnt, u8 data[]) { gt911_data.cnt = 0; switch(cnt){ case 5: gt911_data.points[4].x = data[0x31]<<8 | data[0x30]; gt911_data.points[4].y = data[0x33]<<8 | data[0x32]; case 4: gt911_data.points[3].x = data[0x29]<<8 | data[0x28]; gt911_data.points[3].y = data[0x2B]<<8 | data[0x2A]; case 3: gt911_data.points[2].x = data[0x21]<<8 | data[0x20]; gt911_data.points[2].y = data[0x23]<<8 | data[0x22]; case 2: gt911_data.points[1].x = data[0x19]<<8 | data[0x18]; gt911_data.points[1].y = data[0x1B]<<8 | data[0x1A]; case 1: gt911_data.points[0].x = data[0x11]<<8 | data[0x10]; gt911_data.points[0].y = data[0x13]<<8 | data[0x12]; break; default: break; }

gt911_data.cnt = cnt; }

void ShowPointData(void) { u8 cnt = gt911_data.cnt; for(u8 i=0; i<cnt; i++){ printf(“Point%d(%d,%d)\t”, i+1, gt911_data.points[i].x, gt911_data.points[i].y); } printf(“\r\n”); memset(&gt911_data, 0, sizeof(gt911_data)); }

0x04 验证结果:

烧录程序至MCU,接线、上电,打开串口调试助手查看打印信息(最多同时五点触摸):

串口打印坐标
串口打印坐标

转载于:https://www.cnblogs.com/DarkBright/p/10730346.html

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/147622.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 引脚连接:
    • IIC的SCL与SDA需要接上拉电阻!
    • 0x01 模拟IIC:
      • 在模拟IIC的头文件中:
        • 在模拟IIC的C源文件中实现相关函数:
        • 0x02 初始化GT911:
          • IIC通信地址选择 0x28/0x29,在头文件中加入相关声明和定义:
            • 在C源文件中添加GT911初始化所需要的准备函数:
              • 按照时序GT911上电初始化大致流程如下(IIC通信地址选择 0x28/0x29):
                • 在C源文件中添加读写GT911寄存器以及修改配置的相关函数:
                  • 其中GT911_Cfg为寄存器配置数据,一般由厂商直接提供
                • 完整的GT911初始化代码如下:
                • 0x03 中断接收GT911坐标数据:
                  • GT911所连引脚外部中断初始化(PB1):
                    • 中断服务函数:
                      • data为全局数据(0x8140-0x8180一共0x40个数据),直接一次性读出所有的数据
                    • 其中获取和打印坐标的相关函数:
                      • 在GT911的头文件中:extern GT911_POINT_DATA gt911_data;
                  • 0x04 验证结果:
                  相关产品与服务
                  数据库一体机 TData
                  数据库一体机 TData 是融合了高性能计算、热插拔闪存、Infiniband 网络、RDMA 远程直接存取数据的数据库解决方案,为用户提供高可用、易扩展、高性能的数据库服务,适用于 OLAP、 OLTP 以及混合负载等各种应用场景下的极限性能需求,支持 Oracle、SQL Server、MySQL 和 PostgreSQL 等各种主流数据库。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档