SWM32S基于GT9157的触摸芯片驱动

电子说

1.2w人已加入

描述

       此文章介绍SWM32S基于5寸800*480分辨率液晶屏+GT9157触摸芯片的驱动实现过程。

硬件

     MCU:SWM32SRET6

     TFT-LCD:5.0寸 800*480电容屏

     触摸芯片:GT9157

MCU

      SWM32S 内嵌 ARM Cortex-M4 控制器,片上包含精度为 1%以内的 20MHz/40MHz 时钟,可通过 PLL 倍频到 120MHz 时钟,提供多种内置 FLASH/SRAM 大小可供选择,支持 ISP(在系统编程)操作及 IAP(在应用编程)。


     外设串行总线包括 1 个 CAN 接口,多个 UART 接口、 SPI 通信接口(支持主/从选择)及 I2C 接口(支持主/从选择)。此外还包括 1 个 32 位看门狗定时器, 6 组 32 位通用定时器, 1 组 32 位专用脉冲宽度测量定时器, 12 通道 16 位的 PWM 发生器, 2 个 8 通道 12 位、 1MSPS 的逐次逼近型ADC 模块, 1 个 SDIO 接口模块, TFT-LCD 液晶驱动模块以及 RTC 实时时钟、 SRAMC、 SDRAMC、NORFLC 接口控制模块,同时提供欠压检测及低电压复位功能。

触摸芯片

控制器

      GT9157拥有26个驱动通道和14个感应通道,以满足更高的touch 精度要求。同时支持最先进的短距离传输功能HotKnot。GT9157可同时识别5个触摸点位的实时准确位置,移动轨迹及触摸面积。并可根据主控需要,读取相应点数的触摸信息,其内部结构如上图所示。

控制器

        GT9157触控芯片有两个备选的I2C通讯地址,这是由芯片的上电时序决定,如图所示。上 电时序有Reset 引脚和INT引脚生成,若Reset引脚从低电电平转变到高电平期间,INT 引脚为高电平的时候,触控芯片使用的I2C设备地址为0x28/0x29(8位写、读地址),7位地址为0x14;若Reset引脚从低电电平转变到高电平期间,INT 引脚一直为低电平,则触控芯片使用的I2C设备地址为0xBA/0xBB(8位写、读地址),7位地址为0x5D。

代码

控制器

红色框内文件相对重要并解读

( 1) bsp_I2C_GT9XX.c 文件的解读

#include "bsp_I2C_GT9XX.h"

#include "string.h" 

#include "bsp_SysTick.h"

#include

void I2C_Mst_Init(void)

{

 I2C_InitStructure I2C_initStruct;

 PORT_Init(PORTA, PIN4, FUNMUX0_I2C0_SCL, 1); // GPIOA.4配置为I2C0 SCL引脚

 PORT_Init(PORTA, PIN5, FUNMUX1_I2C0_SDA, 1); // GPIOA.5配置为I2C0 SDA引脚

 I2C_initStruct.Master = 1;

 I2C_initStruct.Addr7b = 1;

 I2C_initStruct.MstClk = 400000;

 I2C_initStruct.MstIEn = 0;

 I2C_Init(I2C0, &I2C_initStruct);

 I2C_Open(I2C0);

}

void bsp_GT9XX_InitRst(void)

{

 // 第一阶段设置端口,并拉低两个端口

 GPIO_Init(GPIO_PORT_GT_RST, GPIO_PIN_GT_RST, 1, 0, 0);    // 复位脚 输出

 GPIO_Init(GPIO_PORT_GT_INT, GPIO_PIN_GT_INT, 1, 0, 0);    // 中断脚 

 GPIO_ClrBit(GPIOC, PIN3);

 GPIO_ClrBit(GPIOC, PIN2);      // 拉低两个端口的电平,准备复位

 rt_thread_delay(10);

 // 第二阶段复位芯片

 GPIO_SetBit(GPIOC, PIN3);      // 拉高开始复位芯片

 rt_thread_delay(10);

 // 第三阶段设置中断引脚为 中断功能

 GPIO_Init(GPIOC, PIN2, 0, 0, 0);

 EXTI_Init(GPIOC, PIN2, EXTI_RISE_EDGE);   // 上升沿触发中断

 I2C_Mst_Init();         // 硬件IIC端口初始化

 rt_thread_delay(10); 

}

void GT9XX_IRQEnable(void)

{

 NVIC_EnableIRQ(GPIOC2_IRQn);     // 使能GPIOC.2端口中断

 EXTI_Open(GPIOC, PIN2);       // 打开外部中断  

}

void GT9XX_IRQDisable(void)

{

 NVIC_DisableIRQ(GPIOC2_IRQn);     // 禁止GPIOC.2端口中断

 EXTI_Close(GPIOC, PIN2);      // 关闭外部中断 

 GPIO_Init(GPIOC, PIN2, 1, 0, 1);    // 回到普通输出端口

 GPIO_ClrBit(GPIOC, PIN2);

}

/********************************************************************************************************************** 

* 函数名称: bsp_WrNumByte()

* 功能说明: IIC写Num个字节 

* 输    入: reg 寄存器地址,*p数据,WrByteNum写入的数据个数

* 输    出: 0,正常     其他,失败

* 注意事项: 

**********************************************************************************************************************/

uint8_t bsp_GT9XX_WrReg(uint8_t IdAddr,uint8_t *p,uint8_t WrByteNum)

{

    I2C0->MSTDAT = IdAddr | 0;       // 发送器件地址+写命令

 I2C0->MSTCMD = (1 << I2C_MSTCMD_STA_Pos) |  

       (1 << I2C_MSTCMD_WR_Pos);  // 发送起始位和从机地址

 while(I2C0->MSTCMD & I2C_MSTCMD

       以上程序是我们为移植“ bsp_GT9XX.c”文件做的基本驱动,接下来我们详细分析一下,


   这部分源码具体实现了什么功能。I2C_Mst_Init()函数中,我们首先声明了一个结构体,接着将 GPIOA.4 和 GPIOA.5进行了特殊功能管脚的分配,设置为 I2C 接口。接着是给结构体赋值, 他们的意义分别是设置为主机模式;地址为 7 位接口;I2C 通信时钟频率设为 400HHz;不使能中断模式,接着是调用库函数进行给寄存器赋值;最后打开 I2C 接口。接下来 bsp_GT9XX_InitRst()函数为初始化,主要是设置端口,并将 GT9157 的设备 I2C 地址设置为 0xBA,这个设置过程参加上面的时序;接着将 GPIOC.2 设置为中断,上升沿触发。函数 GT9XX_IRQEnable()和 GT9XX_IRQDisable(),顾名思义,就是使能中断和失能中断,这个好理解最后就是两个读写 GT9157 寄存器的函数,这两个函数,需要读者先理解 I2C 通信的基本协议,之后安装基本协议,一句、一句的理解,这里需要注意的是

I2C0->MSTCMD = (1 << I2C_MSTCMD_RD_Pos)  |

   (1 << I2C_MSTCMD_ACK_Pos) |

   (1 << I2C_MSTCMD_STO_Pos);

      这三行程序,当我们在跑该程序的时候, 一般是先写寄存器,再读数,而此时如果没有这三行程序,会把下一次的读数据和写寄存器混淆,导致 GT9157 芯片不认识此协议。当我们加了之后,就有结束,有开始,继而芯片能够识别此协议。

现象

复位 初始化后串口打印,可以看到x轴800 ,y轴480

控制器

进行一个点的触摸 ID:0 定位是(257,237) 宽度62

控制器

进行两个点的触摸 可以看到ID0  ID1

控制器

进行五个点的触摸 可以看到ID0  ID1  ID2  ID3  ID4

控制器

                   

附录

主程序代码:

#include "bsp_uart.h"

#include "rtthread.h"

#include "ugui.h"

#include "bsp_gt9xx.h"

extern void GTP_TouchProcess(void);

UG_GUI gui;

uint32_t LCD_Buffer[800*480 * 2 / 4] __attribute__((at(SDRAMM_BASE))) = {0};

void _HW_DrawPoint(UG_S16 x, UG_S16 y, UG_COLOR c)

{

LCD_Buffer[y*400 + x/2] &= ~(0xFFFF << ((x%2) == 0 ? 0 : 16));

LCD_Buffer[y*400 + x/2] |=  (c      << ((x%2) == 0 ? 0 : 16));

}

ALIGN(RT_ALIGN_SIZE)       // 以字对齐(4字节)

static rt_uint8_t rt_Test_thread_stack[1024]; // 线程栈

// 线程Test

static void Test_thread_entry(void* parameter)

{

printf(" RGB工程初始化OK ...... ");

LCD->SRCADDR = (uint32_t)LCD_Buffer;

LCD_Start(LCD);

UG_Init(&gui,(void(*)(UG_S16,UG_S16,UG_COLOR))_HW_DrawPoint,800,480);

GTP_Init_Panel();

while(1)

{

}

}

int main(void)

{

static struct rt_thread Test_thread;   // 线程控制块  

printf("SWM320 ");  

    // 创建静态线程

    rt_thread_init(&Test_thread,                  // 线程控制块

                   "Test",                        // 线程名字,在shell里面可以看到

                   Test_thread_entry,             // 线程入口函数

                   RT_NULL,                      // 线程入口函数参数

                   &rt_Test_thread_stack[0],      // 线程栈起始地址

                   sizeof(rt_Test_thread_stack),   // 线程栈大小

                   5,           // 线程的优先级

                   20);                          // 线程时间片

    rt_thread_startup(&Test_thread);              // 启动线程

}

void LCD_Handler(void)

{

LCD_INTClr(LCD);

LCD_Start(LCD);

}

void GPIOC2_Handler(void)

{

EXTI_Clear(GPIOC, PIN2);     // 清楚中断标志位

GTP_TouchProcess();    

}

审核编辑 :李倩

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分