此文章介绍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("\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)。