RK3568平台(触摸篇)串口触摸屏
一.什么是串口屏
串口屏,可组态方式二次开发的智能串口控制显示屏,是指带有串口通信的TFT彩色液晶屏显示控制模组。利用显示屏显示相关数据,通过触摸屏、按键、鼠标等输入单元写入参数或者输入操作指令,进而实现用户与机器进行信息交互。


主要特点 :
通讯方式简单(线少): 串口屏只需通过几根线与主控器连接,大大简化了硬件设计和布线复杂度。
多种尺寸和分辨率可选(大屏): 从1英寸的小屏幕到20多英寸的大屏幕,可以根据应用需求选择不同的尺寸和分辨率。
内置图形库和触控驱动(能触摸): 串口屏通常内置了一些常用的图形库和触控驱动,使得开发者无需编写复杂的显示和触控代码。
易于编程(简单): 通过指令集或协议发送简单的命令即可实现丰富的显示效果,如绘制图形、显示文本、切换页面等。
强大的功能扩展: 有些高级串口屏还支持播放视频、显示动态图表、联网功能等。
缺点:
成本相对较高: 由于集成了更多功能,价格相对较高。
依赖性强: 依赖屏幕厂商提供的协议和命令集,灵活性较低。
二.串口屏驱动示例
这里是将串口作为一个serio总线设备,利用linux内核提供serio总线驱动,通过设置对应的串口,调用serport提供的函数将串口当做serio总线设备,在驱动里面需要按照serio总线设备驱动的框架来实现,在内核源码drivers/input/touchscreen下提供了两个例子,touchright.c和touchit123.c,可以参考这两个例子编写驱动。
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>#define DRIVER_DESC "EETI Egalax serial touchscreen driver"MODULE_AUTHOR("Zolt??n B??sz??rm??nyi <zboszor@xxxxx>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");/** Definitions & global arrays.*/
#define SERIO_EGALAX 0x3f
#define EGALAX_FORMAT_MAX_LENGTH 6
#define EGALAX_RESPONSE_BEGIN_BYTE 0x80
#define EGALAX_FORMAT_PRESSURE_BIT 0x40
#define EGALAX_FORMAT_TOUCH_BIT 0x01
#define EGALAX_FORMAT_RESOLUTION 0x06#define EGALAX_MIN_XC 0
#define EGALAX_MAX_XC 0x4000
#define EGALAX_MIN_YC 0
#define EGALAX_MAX_YC 0x4000#define EGALAX_GET_XC(data, resbits, shift) ((((data[1] & (resbits)) << 7) | (data[2] & 0x7f)) << shift)
#define EGALAX_GET_YC(data, resbits, shift) ((((data[3] & (resbits)) << 7) | (data[4] & 0x7f)) << shift)
#define EGALAX_GET_TOUCHED(data) (EGALAX_FORMAT_TOUCH_BIT & data[0])/** Per-touchscreen data.*/struct egalax {struct input_dev *dev;struct serio *serio;int idx;int bytes;int resbits;int shift;unsigned char data[EGALAX_FORMAT_MAX_LENGTH];char phys[32];
};static void egalax_process_data(struct egalax *pegalax)
{struct input_dev *dev = pegalax->dev;if (++pegalax->idx == pegalax->bytes) {input_report_abs(dev, ABS_X, EGALAX_GET_XC(pegalax->data, pegalax->resbits, pegalax->shift));input_report_abs(dev, ABS_Y, EGALAX_GET_YC(pegalax->data, pegalax->resbits, pegalax->shift));//input_report_key(dev, BTN_TOUCH, EGALAX_GET_TOUCHED(pegalax->data));input_report_abs(dev, ABS_PRESSURE, EGALAX_GET_TOUCHED(pegalax->data));input_sync(dev);pegalax->idx = 0;}
}static irqreturn_t egalax_interrupt(struct serio *serio,unsigned char data, unsigned int flags)
{struct egalax *pegalax = serio_get_drvdata(serio);pegalax->data[pegalax->idx] = data;if (EGALAX_RESPONSE_BEGIN_BYTE & pegalax->data[0]) {pegalax->bytes = (EGALAX_FORMAT_PRESSURE_BIT & pegalax->data[0] ? 6 : 5);switch ((EGALAX_FORMAT_RESOLUTION & pegalax->data[0]) >> 1) {case 0:pegalax->resbits = 0x0f;pegalax->shift = 3;break;case 1:pegalax->resbits = 0x1f;pegalax->shift = 2;break;case 2:pegalax->resbits = 0x3f;pegalax->shift = 1;break;default:pegalax->resbits = 0x7f;pegalax->shift = 0;break;}egalax_process_data(pegalax);}elsedev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n",pegalax->data[0]);return IRQ_HANDLED;
}static void egalax_disconnect(struct serio *serio)
{struct egalax *pegalax = serio_get_drvdata(serio);input_get_device(pegalax->dev);input_unregister_device(pegalax->dev);serio_close(serio);serio_set_drvdata(serio, NULL);input_put_device(pegalax->dev);kfree(pegalax);
}/** egalax_connect() is the routine that is called when someone adds a* new serio device that supports egalax protocol and registers it as* an input device. This is usually accomplished using inputattach.*/static int egalax_connect(struct serio *serio, struct serio_driver *drv)
{struct egalax *pegalax;struct input_dev *input_dev;int err;pegalax = kzalloc(sizeof(struct egalax), GFP_KERNEL);input_dev = input_allocate_device();if (!pegalax || !input_dev) {err = -ENOMEM;goto fail1;}pegalax->serio = serio;pegalax->dev = input_dev;snprintf(pegalax->phys, sizeof(pegalax->phys),"%s/input1", serio->phys);input_dev->name = "EETI eGalaxTouch Serial TouchScreen";input_dev->phys = pegalax->phys;input_dev->id.bustype = BUS_RS232;input_dev->id.vendor = SERIO_EGALAX;input_dev->id.product = 0;input_dev->id.version = 0x0001;input_dev->dev.parent = &serio->dev;input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);//input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);input_set_abs_params(pegalax->dev, ABS_X,EGALAX_MIN_XC, EGALAX_MAX_XC, 0, 0);input_set_abs_params(pegalax->dev, ABS_Y,EGALAX_MIN_YC, EGALAX_MAX_YC, 0, 0);input_set_abs_params(pegalax->dev, ABS_PRESSURE, 0, 1, 0, 0);serio_set_drvdata(serio, pegalax);err = serio_open(serio, drv);if (err)goto fail2;err = input_register_device(pegalax->dev);if (err)goto fail3;return 0;fail3: serio_close(serio);
fail2: serio_set_drvdata(serio, NULL);
fail1: input_free_device(input_dev);kfree(pegalax);return err;
}/** The serio driver structure.*/static struct serio_device_id egalax_serio_ids[] = {{.type = SERIO_RS232,.proto = SERIO_EGALAX,.id = SERIO_ANY,.extra = SERIO_ANY,},{ 0 }
};MODULE_DEVICE_TABLE(serio, egalax_serio_ids);static struct serio_driver egalax_drv = {.driver = {.name = "egalax",},.description = DRIVER_DESC,.id_table = egalax_serio_ids,.interrupt = egalax_interrupt,.connect = egalax_connect,.disconnect = egalax_disconnect,
};/** The functions for inserting/removing us as a module.*/static int __init egalax_init(void)
{return serio_register_driver(&egalax_drv);
}static void __exit egalax_exit(void)
{serio_unregister_driver(&egalax_drv);
}module_init(egalax_init);
module_exit(egalax_exit);
只是修改了最后一点,其中egalax_serio_ids中的几个参数在应用程序中需要用到,加上驱动编译内核更新后,此时这个驱动是没有起作用的,需要通过应用程序将串口与之绑定,后才能正常工作。
应用程序如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <errno.h>
#include <string.h>
#include <linux/fb.h>
#include <malloc.h>
#include <sys/mman.h>
#include <termio.h>
#include <linux/serio.h>#define SERIO_ANY 0xff
#define SERIO_EGALAX 0x3fint main(int argc, char* argv[])
{int dev,ret;char comdev[20];int ldisc;unsigned long type;struct termios option;int fd = -1;if(argc != 2){printf("-----------------------------------------\n");printf("\nUsage: %s [serial device(1-5)]\n", argv[0]);printf("Example: %s 5 n", argv[0]);printf("-----------------------------------------\n");return 0;}dev = strtol(argv[1],NULL,10);sprintf(comdev,"/dev/ttyAMA%d",dev);fd = open(comdev,O_RDWR|O_NONBLOCK|O_NOCTTY);if (fd < 0) {perror(comdev);exit(1);}tcgetattr(fd, &option);option.c_iflag = IGNPAR | IGNBRK;option.c_cflag = HUPCL | CS8 | CREAD | CLOCAL | B9600;option.c_cc[VMIN] = 1;option.c_cc[VTIME] = 0;cfsetispeed(&option,B9600);cfsetospeed(&option,B9600);ret = tcsetattr(fd, TCSANOW, &option);if(ret < 0) {perror("TCSANOW");exit(1);}ldisc = N_MOUSE;ret = ioctl(fd,TIOCSETD,&ldisc);if(ret) {perror("TIOCSETD");}type = SERIO_EGALAX | (SERIO_ANY << 8) | (SERIO_ANY << 16);ret = ioctl(fd,SPIOCSTYPE, &type);if(ret) {perror("SPIOCSTYPE");}read(fd,NULL,0);//close(fd);return 0;
}
需要注意的是,应用程序最后这个read一定要执行,不然驱动里不会进行连接.
编译生成可执行文件seriotouch
应用程序配制完串口后需要与之前的驱动连接,看设置spiocstype的设置,需要保证这里的几个参数与驱动进行对应。
系统启动后执行seriotouch 5 &
后面这个5对应的是串口号,执行这个后会看到驱动里的connect执行了,同时会生成一个input节点。
相关文章:
RK3568平台(触摸篇)串口触摸屏
一.什么是串口屏 串口屏,可组态方式二次开发的智能串口控制显示屏,是指带有串口通信的TFT彩色液晶屏显示控制模组。利用显示屏显示相关数据,通过触摸屏、按键、鼠标等输入单元写入参数或者输入操作指令,进而实现用户与机器进行信…...
MySQL数据库-事务
一、什么是事务 1.概念 事务(Transaction):一个最小的不可再分的工作单元,一个事务对应一个完整的业务,一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成,事务只针对DML语句。 数据…...
qt事件类型列表
t提供了一系列丰富的事件类型,这些事件允许应用程序响应各种用户输入、系统通知以及其他类型的交互。以下是一些常见的Qt事件类型及其用途概述: QEvent::None (0): 无事件,用于初始化或作为默认值。 QEvent::Timer (1): 定时器事件ÿ…...
ElasticSearch父子索引实战
关于父子索引 ES底层是Lucene,由于Lucene实际上是不支持嵌套类型的,所有文档都是以扁平的结构存储在Lucene中,ES对父子文档的支持,实际上也是采取了一种投机取巧的方式实现的. 父子文档均以独立的文档存入,然后添加关联关系,且父子文档必须在同一分片,由于父子类型文档并没有…...
二百四十九、Linux——在Linux中创建新用户、赋予新用户root权限并对文件夹赋予新用户的权限
一、目的 安装国产化数据库OceanBase的时候,需要创建新用户、赋予新用户root权限并对文件夹赋予新用户的权限 二、创建新用户 #创建账户 oceanadmin [roothurys22 ~]#useradd -U oceanadmin -d /home/oceanadmin -s /bin/bash [roothurys22 ~]#mkdir -p /home/oc…...
com.mysql.cj.jdbc.Driver 爆红
出现这样的问题就是pom.xml文件中没有添加数据库依赖坐标 添加上这个依赖即可,添加完后重新加载一下Maven即可。 如果感觉对你有用就点个赞!!!...
传神论文中心|第19期人工智能领域论文推荐
在人工智能领域的快速发展中,我们不断看到令人振奋的技术进步和创新。近期,开放传神(OpenCSG)社区发现了一些值得关注的成就。传神社区本周也为对AI和大模型感兴趣的读者们提供了一些值得一读的研究工作的简要概述以及它们各自的论…...
案例分享-国外轻松感UI设计赏析
国外UI设计倾向于采用简洁的布局、清晰的排版和直观的交互方式,减少用户的认知负担,从而营造出轻松的使用体验。这种设计风格让用户能够快速找到所需信息,降低操作难度,提升整体满意度。 在注重美观的同时,更加重视用户…...
操作系统(4)——文件系统
目录 小程一言文件系统管理基础概念&功能基本概念文件的结构和属性文件的操作文件的安全性和权限控制文件系统的实现和分配方式 问题&解答1、文件系统在操作系统中起到什么作用?2、文件的逻辑结构和物理结构有何区别?3、如何理解文件权限控制在操…...
C# 调用Webservice接口接受数据测试
1.http://t.csdnimg.cn/96m2g 此链接提供测试代码; 2.http://t.csdnimg.cn/64iCC 此链接提供测试接口; 关于Webservice的基础部分不做赘述,下面贴上我的测试代码(属于动态调用Webservice): 1ÿ…...
工作流流程引擎框架推荐来了
近期有不少粉丝客户朋友都在询问工作流流程引擎框架推荐。随着行业竞争激烈化,实现流程化办公已经成为当务之急。低代码技术平台及工作流流程引擎拥有够灵活、更可靠、可视化界面等诸多个优势特点,在推动企业实现数字化转型的过程中深受行业信赖与喜爱。…...
从技术博客到个人 IP 矩阵:全面攻略与实战示例
文章目录 摘要引言创建博客选择平台设计和布局 内容规划明确目标受众设定内容方向制定发布计划 SEO 优化关键词研究内链和外链元标签优化 社交媒体推广选择社交平台制定推广策略 可运行的 Demo 代码模块QA 环节问:如何增加博客的曝光度?问:如…...
SOFAJRaft 简介
SOFAJRaft 简介 SOFAJRaft是一个基于Raft一致性算法的生产级高性能Java实现,由蚂蚁金服自主研发。以下是关于SOFAJRaft的详细介绍: 来源与背景: SOFAJRaft是从百度的braft移植而来,并在其基础上进行了一系列的优化和改进。它作为…...
c#中Oracle.DataAccess.dll连接数据库的报错处理
通过DataAccess.dll连接Oracle数据库时,报如下错误 The provider is not compatible with the version of Oracle client 最终原因: dll 文件复制不全(4个文件必须) oracle.dataaccess.dll oci.dll oraociei11.dll oraops11w.dll...
PyCharm2024 专业版激活设置中文
PyCharm2024 专业版激活设置中文 官网下载最新版:https://www.jetbrains.com/zh-cn/pycharm/download 「hack-jet激活idea家族.zip」链接:https://pan.quark.cn/s/4929a884d8fe 激活步骤: 官网下载安装PyCharm ;测试使用的202…...
视觉SLAM第一讲
第一讲-预备知识 SLAM是什么? SLAM(Simultaneous Localization and Mapping)是同时定位与地图构建。 它是指搭载特定传感器的主体,在没有环境先验信息的情况下,于运动过程中建立环境的模型,同时估计自己…...
吴恩达机器学习C1W2Lab05-使用Scikit-Learn进行线性回归
前言 有一个开源的、商业上可用的机器学习工具包,叫做scikit-learn。这个工具包包含了你将在本课程中使用的许多算法的实现。 目标 在本实验中,你将: 利用scikit-learn实现使用梯度下降的线性回归 工具 您将使用scikit-learn中的函数以及matplotli…...
springboot集成thymeleaf实战
引言 笔者最近接到一个打印标签的需求,由于之前没有做过类似的功能,所以这也是一次学习探索的机会了,打印的效果图如下: 这个最终的打印是放在58mm*58mm的小标签纸上,条形码就是下面的35165165qweqweqe序列号生成的&…...
SpringBoot+Vue+kkFileView实现文档管理(文档上传、下载、在线预览)
场景 SpringBootVueOpenOffice实现文档管理(文档上传、下载、在线预览): SpringBootVueOpenOffice实现文档管理(文档上传、下载、在线预览)_霸道流氓气质的博客-CSDN博客_vue openoffice 上面在使用OpenOffice实现doc、excel、ppt等文档的管理和预览。 除此之外…...
从代码层面熟悉UniAD,开始学习了解端到端整体架构
0. 简介 最近端到端已经是越来越火了,以UniAD为代表的很多工作不断地在不断刷新端到端的指标,比如最近SparseDrive又重新刷新了所有任务的指标。在端到端火热起来之前,成熟的模块化自动驾驶系统被分解为不同的独立任务,例如感知、…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...
CMS内容管理系统的设计与实现:多站点模式的实现
在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...
