SWM32S基于GT9157的触摸芯片驱动

cathy的头像
cathy 发布于:周二, 04/11/2023 - 10:14 ,关键词:

此文章介绍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 接口控制模块,同时提供欠压检测及低电压复位功能。

触摸芯片

1.png

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

2.png

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

代码

3.png

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

( 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

4.png

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

5.png

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

6.png

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

7.png

附录:

主程序代码:

#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("\r RGB工程初始化OK ...... \r\n");     

    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 \r\n");  
     
    // 创建静态线程
    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();    
}

来源:华芯微特32位MCU

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 79