【正点原子STM32连载】 第四十四章 触摸屏实验 摘自【正点原子】APM32F407最小系统板使用指南

news2024/11/15 10:27:34

1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html##

第四十四章 触摸屏实验

本章将介绍使用APM32F407驱动TFTLCD模块上的触摸屏,实现一个类似画板的应用。通过本章的学习,读者将学习到使用GPIO模拟IIC和SPI时序以及触摸屏的驱动。
本章分为如下几个小节:
44.1 硬件设计
44.2 程序设计
44.3 下载验证

44.1 硬件设计
44.1.1 例程功能

  1. 程序运行后,先显示实验信息,随后在LCD上绘制出触摸屏被触摸的轨迹
  2. 可通过触摸屏幕右上角的“RST”来清空屏幕
  3. 使用电阻式触摸屏的时候,可按下KEY0按键,进行触摸校准
  4. LED0闪烁,指示程序正在运行
    44.1.2 硬件资源
  5. LED
    LED0 - PF9
  6. 按键
    KEY0 - PE4
  7. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
  8. TFTLCD模块上的触摸屏(电阻式、电容式)
    44.1.3 原理图
    本章实验使用了正点原子的TFTLCD模块(兼容正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块),该模块需通过LCD转接板与板载的TFTLCD接口进行连接,该接口与板载MCU的连接原理图,如下所示:
    在这里插入图片描述

图44.1.3.1 TFTLCD模块与MCU的连接原理图
如上图所示,TFTLCD模块上的触摸屏使用T_MISO、T_MOSI、T_PEN、T_CS、T_SCK信号与MCU进行通讯,正点原子的TFTLCD模块采用了两种触摸屏,分别为:电阻式触摸屏和电容式触摸屏,其中电阻式触摸屏使用SPI协议与MCU进行通信,而电容式触摸屏则是使用IIC协议与MCU进行通讯,因此TFT模块上的触摸屏引脚对于不同的触摸屏有不同的引脚定义,请读者自行查看TFTLCD模块的用户手册查看具体的引脚定义。
44.2 程序设计
44.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_Config_T gpio_init_struct;
    
    tp_dev.touchtype = 0;					/* 默认设置(电阻屏、竖屏) */
    tp_dev.touchtype |= lcddev.dir & 0x01;	/* 根据LCD判断是横屏还是竖屏 */
    
    /* 电容触摸屏,4.3寸/10.1寸屏 */
    if ((lcddev.id == 0x5510) || (lcddev.id == 0x4342) || (lcddev.id == 0x1018))
    {
    		gt9xxx_init();
    		tp_dev.scan = gt9xxx_scan;			/* 设置触摸屏扫描函数 */
    		tp_dev.touchtype |= 0x80;			/* 电容屏 */
    }
    /* SSD1963 7寸屏或7寸800*480/1024*600 RGB屏 */
    else if (	(lcddev.id == 0x1963) ||
    				(lcddev.id == 0x7084) ||
    				(lcddev.id == 0x7016))
    {
    		ft5206_init();
    		tp_dev.scan = ft5206_scan;			/* 设置触摸屏扫描函数 */
    		tp_dev.touchtype |= 0x80;			/* 电容屏 */
    }
    /* 电阻屏 */
    else
    {
    		/* 电阻屏的初始化操作,代码省略 */
    }
    
    return 1;
}

从上面的代码中可以看出,触摸屏的初始化会读取TFTLCD模块LCD的ID号,来判断触摸屏的型号,因此在使用本触摸屏驱动初始化触摸屏前,需要先进行LCD的初始化。触摸屏的初始化函数会依据LCD的ID对不同型号的触摸屏进行初始化。
对于触摸屏驱动中的其他内容,请读者自行结合实际使用的TFTLCD的用户手册产看本章配套实验例程的源码。
44.2.2 实验应用代码
本章实验的应用代码,如下所示:

int main(void)
{
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_3);	/* 设置中断优先级分组为组3 */
    sys_apm32_clock_init(336, 8, 2, 7);					/* 配置系统时钟 */
    delay_init(168);										/* 初始化延时功能 */
    usart_init(115200);									/* 初始化串口 */
    led_init();											/* 初始化LED */
    key_init();											/* 初始化按键 */
    lcd_init();											/* 初始化LCD */
    tp_dev.init();										/* 初始化触摸屏 */
    
    lcd_show_string(30, 50, 200, 16, 16, "APM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "TOUCH TEST", 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 KEY0 to 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按键被按下时,便会进行电阻触摸屏校准。
44.3 下载验证
在完成编译和烧录操作后,可以看到LCD上显示了本实验的实验信息,随后便进入“白板”界面,此时便可在LCD上通过触摸屏绘制出任意的图案,若是电容屏,还支持多点触控,若是电阻屏出现触摸点与LCD上显示的绘制点坐标不吻合,可以按下KEY0按键进行电阻触摸屏的校准。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1141514.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu 22.04安装百度网盘

百度网盘 客户端下载 (baidu.com) 下载地址 sudo dpkg -i baidunetdisk_4.17.7_amd64.deb

Go RESTful API 接口开发

文章目录 什么是 RESTful APIGo 流行 Web 框架-GinGo HelloWorldGin 路由和控制器Gin 处理请求参数生成 HTTP 请求响应Gin 的学习内容实战用 Gin 框架开发 RESTful APIOAuth 2.0接口了解用 Go 开发 OAuth2.0 接口示例 编程有一个准则——Don‘t Repeat Yourself&#xff08;不要…

强化学习------PPO算法

目录 简介一、PPO原理1、由On-policy 转化为Off-policy2、Importance Sampling&#xff08;重要性采样&#xff09;3、off-policy下的梯度公式推导 二、PPO算法两种形式1、PPO-Penalty2、PPO-Clip 三、PPO算法实战四、参考 简介 PPO 算法之所以被提出&#xff0c;根本原因在于…

简述一下伪共享的概念以及如何避免

缓存行 计算机工程师为了提高 CPU 的利用率&#xff0c;平衡 CPU 和内存之间的速度差异&#xff0c;在CPU 里面设计了三级缓存。 CPU 在向内存发起 IO 操作的时候&#xff0c;一次性会读取 64 个字节的数据作为一个缓存行&#xff0c;缓存到 CPU 的高速缓存里面。 在 Java 中一…

Codeforces Round 905 (Div. 3)ABCDEF

Codeforces Round 905 (Div. 3) 目录 A. Morning题意思路核心代码 B. Chemistry题意思路核心代码 C. Raspberries题意思路核心代码 D. In Love题意思路核心代码 E. Look Back题意思路核心代码 A. Morning 题意 从一开始&#xff0c;每一次操作可以选择当前的数字打印或者是移…

【代码随想录】算法训练计划03

1、203. 移除链表元素 题目&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 思路&#xf…

【Unity实战】手戳一个自定义角色换装系统——2d3d通用

文章目录 每篇一句前言素材开始切换头型添加更改颜色随机控制头型和颜色新增眼睛同样的方法配置人物的其他部位设置相同颜色部位全部部位随机绘制UI并添加点击事件通过代码控制点击事件添加颜色修改的事件其他部位效果UI切换添加随机按钮保存角色变更数据跳转场景显示角色数据 …

Linux之J2EE的项目部署及发布

目录 前言 一、会议OA单体项目windows系统部署 1.检验工作 1. 检验jar项目包是否可以运行 2. 验证数据库脚本是否有误 3. 测试项目功能 2. 部署工作 2.1 传输文件 2.2 解压项目及将项目配置到服务器中 2.3 配置数据库 2.4 在服务器bin文件下点击startup.bat启动项目 …

Python----break关键字对while...else结构的影响

案例&#xff1a; 女朋友生气&#xff0c;要求道歉5遍&#xff1a;老婆大人&#xff0c;我错了。道歉到第三遍的时候&#xff0c;媳妇埋怨这一遍说的不真诚&#xff0c;是不是就是要退出循环了&#xff1f;这个退出有两种可能性&#xff1a; ① 更生气&#xff0c;不打算原谅…

最优秀的完整的数字音频工作站水果音乐FL Studio21.1.1.3750中文解锁版

FL Studio21.1.1.3750中文解锁版简称 FL 21&#xff0c;全称 Fruity Loops Studio 21&#xff0c;因此国人习惯叫它"水果"。目前最新版本是FL Studio21.1.1.3750中文解锁版版本&#xff0c;它让你的计算机就像是全功能的录音室&#xff0c;大混音盘&#xff0c;非常先…

连续离散混合系统控制与仿真

简单二阶系统 先研究最简单的二阶积分器串联型系统 x ˙ 1 x 2 x ˙ 2 u \begin{aligned} & \dot x_1 x_2 \\ & \dot x_2 u \\ \end{aligned} ​x˙1​x2​x˙2​u​ 使用零阶保持法离散化&#xff08;见附录&#xff09;&#xff0c; A [ 0 1 0 0 ] , B [ 0 …

Leetcode.1465 切割后面积最大的蛋糕

题目链接 Leetcode.1465 切割后面积最大的蛋糕 rating : 1445 题目描述 矩形蛋糕的高度为 h h h 且宽度为 w w w&#xff0c;给你两个整数数组 h o r i z o n t a l C u t s horizontalCuts horizontalCuts 和 v e r t i c a l C u t s verticalCuts verticalCuts&#xf…

Leetcode—66.加一【简单】

2023每日刷题&#xff08;十一&#xff09; Leetcode—66.加一 实现代码1 /*** Note: The returned array must be malloced, assume caller calls free().*/ int* plusOne(int* digits, int digitsSize, int* returnSize){int num 0;int i 0;int arr[110] {0};// 进位标识…

Linux MMC子系统 - 2.eMMC 5.1总线协议浅析

By: Ailson Jack Date: 2023.10.27 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/161.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

Java提升技术,进阶为高级开发和架构师的路线

原文网址&#xff1a;Java提升技术&#xff0c;进阶为高级开发和架构师的路线-CSDN博客 简介 Java怎样提升技术&#xff1f;怎样进阶为高级开发和架构师&#xff1f;本文介绍靠谱的成长路线。 首先点明&#xff0c;只写业务代码是无法成长技术的。提升技术的两个方法是&…

“从部署到优化,打造高效会议管理系统“

目录 引言一、部署单机项目 - 会议OA1.1 硬件和软件环境准备1.2 检查项目1.3 系统部署1.后端部署 二、部署前后端分离项目 - SPA项目后端部署2.前端部署 总结 引言 在现代化办公环境中&#xff0c;会议是组织沟通、决策和合作的重要方式之一。为了提高会议的效率和质量&#x…

MySQL-DQL【数据查询语言】(图码结合)

目录 一.DQL的定义 二.DQL—语法 三.DQL—基础查询(SELECT.. FROM) &#x1f449;查询多个字段 &#x1f449;设置别名 &#x1f449;去除重复记录 准备工作(建表&#xff0c;添加数据&#xff09; &DQL----基本查询的案例 五.DQL—条件查询(WHERE) 5.1 语法: 5…

基于 C# 实现样式与数据分离的打印方案

对于八月份的印象&#xff0c;我发现大部分都留给了出差。而九月初出差回来&#xff0c;我便立马投入了新项目的研发工作。因此&#xff0c;无论是中秋节还是国庆节&#xff0c;在这一连串忙碌的日子里&#xff0c;无不充满着仓促的气息。王北洛说&#xff0c;“活着不就是仓促…

数字化转型系列主题:数据中台知识体系

当前&#xff0c;大部分企业不再建设从源数据采集到分析应用的烟囱式系统&#xff0c;更倾向于数据集中采集、存储&#xff0c;并应用分层建设。这种方式一方面有利于应用系统的快速部署&#xff0c;另一方面也保证了数据的集中管理与运营&#xff0c;体现数据的资产、资源属性…

主动调度是如何发生的

计算机主要处理计算、网络、存储三个方面。计算主要是 CPU 和内存的合作&#xff1b;网络和存储则多是和外部设备的合作&#xff1b;在操作外部设备的时候&#xff0c;往往需要让出 CPU&#xff0c;就像上面两段代码一样&#xff0c;选择调用 schedule() 函数。 上下文切换主要…