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