本帖最后由 正点原子运营 于 2024-5-10 15:00 编辑
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板
2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版
6)正点原子STM32技术交流QQ群:725095144
本章将介绍使用STM32F103驱动TFTLCD模块上的触摸屏,实现一个类似画板的应用。通过本章的学习,读者将学习到使用GPIO模拟IIC和SPI时序以及触摸屏的驱动。 本章分为如下几个小节: 42.1 硬件设计 42.2 程序设计 42.3 下载验证
42.1 硬件设计 42.1.1 例程功能 1. LCD上实时显示触摸屏被触摸的触摸轨迹,并可通过触摸右上角的RST来清空轨迹 2. 按下KEY0按键可进行电阻触摸屏的触摸校准 3. LED0闪烁,提示程序正在运行
42.1.2 硬件资源 1. LED LED0 - PB5 2. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块 3. 按键 WKUP - PA0 4. 24C02 IIC_SCL - PB10 IIC_SDA - PB11
42.1.3原理图 本章实验使用了正点原子的TFTLCD模块(兼容正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块),该模块需通过LCD转接板与板载的TFTLCD接口进行连接,该接口与板载MCU的连接原理图,如图25.1.3.1所示。 如图25.1.3.1所示,TFTLCD模块上的触摸屏使用T_MISO、T_MOSI、T_PEN、T_CS、T_SCK信号与MCU进行通讯,正点原子的TFTLCD模块采用了两种触摸屏,分别为:电阻式触摸屏和电容式触摸屏,其中电阻式触摸屏使用SPI协议与MCU进行通信,而电容式触摸屏则是使用IIC协议与MCU进行通讯,因此TFT模块上的触摸屏引脚对于不同的触摸屏有不同的引脚定义,请读者自行查看TFTLCD模块的用户手册查看具体的引脚定义。
42.2 程序设计 42.2.1 触摸屏驱动 本章实验的触摸屏驱动主要负责向应用层提供触摸屏的初始化和获取触摸屏触摸坐标等函数。本章实验中,触摸屏的驱动代码包括touch.c、touch.h、ctiic.c、ctiic.h、ft5206.c、ft5206.h、gt9xxx.c、gt9xxx.h八个文件。 触摸屏驱动中,触摸屏的初始化函数,如下所示: - /**
- *@brief 触摸屏初始化
- *@param 无
- *@retval 0,没有进行校准
- * 1,进行过校准
- */
- uint8_t tp_init(void)
- {
- GPIO_InitTypeDef gpio_init_struct;
-
- tp_dev.touchtype = 0; /* 默认设置(电阻屏 & 竖屏) */
- tp_dev.touchtype |= lcddev.dir & 0X01; /* 根据LCD判定是横屏还是竖屏 */
-
- if (lcddev.id == 0x7796)
- {
- /* 初始化GT系列触摸屏成功,即当前3.5寸屏为电容触摸屏 */
- if (gt9xxx_init() == 0)
- {
- tp_dev.scan = gt9xxx_scan; /* 扫描函数指向GT9147触摸屏扫描 */
- tp_dev.touchtype |= 0X80; /* 电容屏 */
- return 0;
- }
- }
-
- if (lcddev.id == 0X5510 ||
- lcddev.id == 0X9806 ||
- lcddev.id == 0X4342 ||
- lcddev.id == 0X4384 ||
- lcddev.id == 0X1018) /* 电容触摸屏,4.3寸/10.1寸屏 */
- {
- gt9xxx_init();
- tp_dev.scan = gt9xxx_scan; /* 扫描函数指向GT9147触摸屏扫描 */
- tp_dev.touchtype |= 0X80; /* 电容屏 */
- return 0;
- }
- /* SSD1963 7寸屏或者 7寸800*480/1024*600RGB屏 */
- else if (lcddev.id == 0X1963 ||
- lcddev.id == 0X7084 ||
- lcddev.id == 0X7016)
- {
- /* 触摸IC是FT系列的就执行ft5206_init函数以及使用ft5206_scan扫描函数 */
- if (!ft5206_init())
- {
- tp_dev.scan = ft5206_scan; /* 扫描函数指向FT5206触摸屏扫描 */
- }
- else
- {
- gt9xxx_init();
- tp_dev.scan = gt9xxx_scan; /* 扫描函数指向GT9147触摸屏扫描 */
- }
- tp_dev.touchtype |= 0X80; /* 电容屏 */
- return 0;
- }
- else
- {
- /* 电阻屏的初始化操作,代码省略 */
- }
- return 1;
- }
复制代码从上面的代码中可以看出,触摸屏的初始化会读取TFTLCD模块LCD的ID号,来判断触摸屏的型号,因此在使用本触摸屏驱动初始化触摸屏前,需要先进行LCD的初始化。触摸屏的初始化函数会依据LCD的ID对不同型号的触摸屏进行初始化。 对于触摸屏驱动中的其他内容,请读者自行结合实际使用的TFTLCD的用户手册产看本章配套实验例程的源码。
42.2.2 实验应用代码 本章实验的应用代码,如下所示: - int main(void)
- {
- HAL_Init(); /* 初始化HAL库 */
- sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
- delay_init(72); /* 初始化延时 */
- usart_init(115200); /* 初始化串口 */
- led_init(); /* 初始化LED */
- key_init(); /* 初始化按键 */
- lcd_init(); /* 初始化LCD */
- tp_dev.init(); /* 初始化触摸屏 */
-
- lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
- lcd_show_string(30, 70, 200, 16, 16, "TOUCHTEST", RED);
- lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
-
- /* 电阻屏显示触摸校准提示 */
- if ((tp_dev.touchtype & 0x80) == 0)
- {
- lcd_show_string(30, 110, 200, 16, 16, "Press KEY0to Adjust", RED);
- }
- delay_ms(1500);
- load_draw_dialog();
-
- if (tp_dev.touchtype & 0x80)
- {
- /* 电容屏测试 */
- ctp_test();
- }
- else
- {
- /* 电阻屏测试 */
- rtp_test();
- }
- }
复制代码在进行完触摸屏的初始化后,便根据触摸屏的不同类型调用了不同的测试函数,这是因为电容屏是支持多点触控的,而电阻屏并不支持。 电容屏测试测试函数,如下所示: - /**
- *@brief 电容触摸屏测试
- *@param 无
- *@retval 无
- */
- static void ctp_test(void)
- {
- uint8_t t = 0;
- uint8_t i = 0;
- uint16_t lastpos[10][2];
- uint8_t maxp = 5;
-
- if (lcddev.id == 0x1018)
- {
- maxp = 10;
- }
-
- while (1)
- {
- tp_dev.scan(0);
- for (t=0; t<maxp; t++)
- {
- if ((tp_dev.sta) & (1 << t))
- {
- /* 坐标在屏幕范围内 */
- if ( (tp_dev.x[t] < lcddev.width) &&
- (tp_dev.y[t] < lcddev.height))
- {
- if (lastpos[t][0] == 0xFFFF)
- {
- lastpos[t][0] = tp_dev.x[t];
- lastpos[t][1] = tp_dev.y[t];
- }
-
- lcd_draw_bline( lastpos[t][0], /* 画线 */
- lastpos[t][1],
- tp_dev.x[t],
- tp_dev.y[t],
- 2,
- POINT_COLOR_TBL[t]);
- lastpos[t][0] = tp_dev.x[t];
- lastpos[t][1] = tp_dev.y[t];
-
- if (tp_dev.x[t] > (lcddev.width - 24) && tp_dev.y[t] < 20)
- {
- load_draw_dialog(); /* 清除 */
- }
- }
- }
- else
- {
- lastpos[t][0] = 0xFFFF;
- }
- }
-
- delay_ms(5);
- i++;
- if ((i % 20) == 0)
- {
- LED0_TOGGLE();
- }
- }
- }
复制代码因为电容屏触摸屏支持多点触控,因此电容屏测试函数在扫描到每一个触摸点坐标后,便将每一个触摸点对应LCD屏幕上的坐标在LCD屏幕上进行绘制,并且每个触摸点使用不同的颜色进行绘制。 电阻屏测试函数,如下所示: - /**
- *@brief 电阻触摸屏测试
- *@param 无
- *@retval 无
- */
- void rtp_test(void)
- {
- uint8_t key;
- uint8_t i = 0;
-
- while (1)
- {
- key = key_scan(0);
- tp_dev.scan(0);
-
- if (tp_dev.sta & TP_PRES_DOWN) /* 触摸屏被按下 */
- {
- if ( (tp_dev.x[0] < lcddev.width) &&
- (tp_dev.y[0] < lcddev.height))
- {
- if ( (tp_dev.x[0] > (lcddev.width - 24)) &&
- (tp_dev.y[0] < 16))
- {
- load_draw_dialog(); /* 清除 */
- }
- else
- {
- tp_draw_big_point(tp_dev.x[0], tp_dev.y[0], RED); /* 画点 */
- }
- }
- }
- else
- {
- delay_ms(10); /* 没有按键按下的时候 */
- }
-
- if (key == KEY0_PRES) /* KEY0按下,则执行校准程序 */
- {
- tp_adjust(); /* 屏幕校准 */
- tp_save_adjust_data();
- load_draw_dialog();
- }
-
- i++;
- if ((i % 20) == 0)
- {
- LED0_TOGGLE();
- }
- }
- }
复制代码电阻触摸屏就相对简单,因为电阻触摸屏仅支持单点触控,因此仅需将触摸的1个触摸点对应LCD屏幕上坐标的点进行绘制即可,同时因为电阻触摸屏是需要校准的,因此当检测到KEY0按键被按下时,便会进行电阻触摸屏校准。
42.3 下载验证 在完成编译和烧录操作后,可以看到LCD上显示了本实验的实验信息,随后便进入“白板”界面,此时便可在LCD上通过触摸屏绘制出任意的图案,若是电容屏,还支持多点触控,若是电阻屏出现触摸点与LCD上显示的绘制点坐标不吻合,可以按下KEY0按键进行电阻触摸屏的校准。 |