触摸屏模拟按键

简介: 该项目较为简单,功能需求是用触摸屏模拟20个按键,按下一次打开继电器,再次按下关闭继电器,最多可以同时打开三个,主页面能够显示总电流I。


🎀 文章作者:二土电子
🐸 期待大家一起学习交流!


一、项目简介

该项目较为简单,功能需求是用触摸屏模拟20个按键,按下一次打开继电器,再次按下关闭继电器,最多可以同时打开三个,主页面能够显示总电流。

这里简单做了一下UI。

f5ac12131d0badc9e3b9366e7834e2b3_ea52a3d46b0b403fa91d5cee2ba1cc3b.jpeg

二、实现内容

实现内容主要有以下内容:

1、按键GUI绘制;
2、按键按下一次开启,再次按下关闭;
3、最多同时开启三个;

三、程序实现

1、GUI绘制

初始GUI程序如下

void Gui_Init(void)   // 初始GUI
{
   
    u16 keyXYTemp = 0;   // 按键Y坐标循环变量

    Gui_Drawbmp16(10,3,gImage_qq);   // Logo显示
    LCD_DrawLine(20,60,300,60);   // 分割线

    // 键盘横线
    for (keyXYTemp = 110;keyXYTemp < 240;keyXYTemp += 60)
    {
   
        LCD_DrawLine(20,keyXYTemp,300,keyXYTemp);
    }
    // 键盘横线
    for (keyXYTemp = 20;keyXYTemp < 320;keyXYTemp += 70)
    {
   
        LCD_DrawLine(keyXYTemp,110,keyXYTemp,230);
    }

    // 显示第一排按键值
    LCD_ShowNum(48,125,1,1,24);
    LCD_ShowNum(118,125,2,1,24);
    LCD_ShowNum(188,125,3,1,24);
    LCD_ShowNum(258,125,4,1,24);
    // 显示第二排按键值
    LCD_ShowNum(48,185,5,1,24);
    LCD_ShowNum(118,185,6,1,24);
    LCD_ShowNum(188,185,7,1,24);
    LCD_ShowNum(258,185,8,1,24);

    LCD_ShowFontHZ(30,70,"当前总电流");

2、触摸按键检测

这里给出一个触摸检测的框架

    tp_dev.scan(0);          
    if(tp_dev.sta&TP_PRES_DOWN)            //触摸屏被按下
    {
       
        if(tp_dev.x[0]<lcddev.width&&tp_dev.y[0]<lcddev.height)
        {
       
            // 按下按键1
            if(20<tp_dev.x[0]&&tp_dev.x[0]<90&&110<tp_dev.y[0]&&tp_dev.y[0]<170)
            {
   
                // 松手检测
                while(tp_dev.sta&TP_PRES_DOWN)
                {
   
                   tp_dev.scan(0);
                }
                // 执行相关代码
            }
        }
    }

在网上看到过其他博主的程序,对于触摸屏并没有添加松手检测,而是用了简单的延时,这在实际应用时很容易出问题,这里加入了松手检测,只有松开手才会执行按键对应的程序。

3、开启关闭控制

对于如何实现按下一次开启,再次按下关闭也非常简单,这里不做过多的语言描述,直接上程序

u8 gKey1PutCount = 0;   // 按键1按下计次变量

tp_dev.scan(0);          
if(tp_dev.sta&TP_PRES_DOWN)            //触摸屏被按下
{
   
    if(tp_dev.x[0]<lcddev.width&&tp_dev.y[0]<lcddev.height)
    {
       
        // 按下按键1
        if(20<tp_dev.x[0]&&tp_dev.x[0]<90&&110<tp_dev.y[0]&&tp_dev.y[0]<170)
        {
   
            // 松手检测
            while(tp_dev.sta&TP_PRES_DOWN)
            {
   
                tp_dev.scan(0);
            }
            gKey1PutCount = gKey1PutCount + 1;   // 按下计次变量加1

            if (gKey1PutCount <= 1)
            {
   
                // 开启
            }
            if (gKey1PutCount >= 2)
            {
   
                // 关闭
                gKey1PutCount = 0;   // 清零计次变量
            }
         }
     }
}

4、开启上限

限制开启上限也很简单,只需要定义一个变量用来记录开启的个数,在准备开启下一个负载时会判断是否当前已经开启了三个,然后判断下一个是否要开启,程序如下

值得注意的是,当检测到当前开启数量已经达到三个时,需要将按键计次变量和负载开启数量减1。

u8 gLoadOpenNum = 0;   // 负载开启数量

u8 gKey1PutCount = 0;   // 按键1按下计次变量

tp_dev.scan(0);          
if(tp_dev.sta&TP_PRES_DOWN)            //触摸屏被按下
{
   
    if(tp_dev.x[0]<lcddev.width&&tp_dev.y[0]<lcddev.height)
    {
       
        // 按下按键1
        if(20<tp_dev.x[0]&&tp_dev.x[0]<90&&110<tp_dev.y[0]&&tp_dev.y[0]<170)
        {
   
            // 松手检测
            while(tp_dev.sta&TP_PRES_DOWN)
            {
   
                tp_dev.scan(0);
            }
            gKey1PutCount = gKey1PutCount + 1;   // 按下计次变量加1

            if (gKey1PutCount <= 1)
            {
   
                gLoadOpenNum = gLoadOpenNum + 1;   // 开启负载数加1

                if (gLoadOpenNum > 3)   // 如果开启数量即将超过三个
                {
   
                    gKey1PutCount = gKey1PutCount - 1;   // 按下计次变量减1
                    gLoadOpenNum = gLoadOpenNum - 1;   // 开启负载数减1
                }
                else
                {
   
                    // 开启
                }
            }
            if (gKey1PutCount >= 2)
            {
   
                gLoadOpenNum = gLoadOpenNum - 1;   // 开启负载数减1
                // 关闭
                gKey1PutCount = 0;   // 清零计次变量
            }
         }
     }
}
相关文章
|
11月前
|
机器学习/深度学习 消息中间件 人工智能
活动邀请丨2025 全球机器学习技术大会
阿里云高级技术专家周礼受邀于 10 月 17 日下午分享议题《Apache RocketMQ x AI:面向异步化 Agent 的事件驱动架构》。
347 69
|
3月前
|
存储 运维 数据可视化
SOCKS5动态代理科普:原理、搭建方式与运维痛点解决方案
SOCKS5动态代理是兼容性强、支持全流量转发的通用代理协议。SSH动态代理无需额外部署,仅靠SSH隧道即可实现内网穿透、异地调试与安全上网。传统方案存在连接冗余、管理混乱等痛点,而SSHXTERM创新支持复用已有SSH会话创建多代理,提供可视化管理、加密存储与轻量运行,大幅提升运维效率。(239字)
626 7
|
5月前
|
人工智能 API 开发工具
Coding Plan百科:阿里云百炼Coding Plan订阅套餐介绍、购买链接及使用注意事项解析
阿里云百炼Coding Plan是面向AI编程的订阅制服务,开通百炼官网:https://t.aliyun.com/U/fPVHqY 现仅售Pro版(200元/月),限量抢购(每日9:30开售)。整合Qwen、Kimi、GLM等多模型,提供每月9万次请求额度,支持主流AI开发工具。开通百炼可免费领7000万Tokens。注意:Lite版已下架,首月优惠活动暂停,不支持退款。
2347 7
|
4月前
|
SQL API 数据库
【LangGraph新手村系列】(4)人机协作中断:让 Agent 在关键节点停下来等你
解决"全自动Agent无法审查"的问题。在tools节点前插入interrupt_before中断点,改用stream流式运行实现暂停,通过get_state().next判断中断位置,审查工具调用后用Command(resume=True)恢复执行,实现人机协作的三重干预:审查放行、修改参数、拒绝执行。
562 0
|
IDE 开发工具 数据安全/隐私保护
Python循环嵌套:从入门到实战的完整指南
循环嵌套是Python中处理多维数据和复杂逻辑的重要工具。本文通过实例讲解嵌套循环的基本用法、常见组合、性能优化技巧及实战应用,帮助开发者掌握其核心思想,避免常见错误,并探索替代方案与进阶方向。
814 0
|
9月前
|
机器学习/深度学习 数据采集 人工智能
大模型训练方法与技术术语解释
预训练、微调、RLHF、思维链等技术共同推动大模型发展。预训练构建语言基础,微调适配特定任务,RLHF融入人类偏好,思维链提升推理能力,少样本与零样本实现快速迁移,指令微调增强指令理解,自监督学习利用海量无标数据,温度控制生成风格,蒸馏压缩模型规模,缩放定律指导模型扩展,全面提升大模型理解、生成与泛化能力。
|
12月前
|
存储 数据库 开发工具
HarmonyOS APP应用开发项目- MCA助手(Day04持续更新中~)
本项目为基于HarmonyOS的端云一体化记账App,集成华为AGC云数据库与认证服务,实现用户注册登录及数据云端存储。通过DevEco Studio开发,解决CloudProgram模块显示问题,完成云数据库初始化与用户信息关联功能。
454 1
HarmonyOS APP应用开发项目- MCA助手(Day04持续更新中~)
|
开发工具 开发者
HarmonyOS NEXT实战:接入微信SDK
本教程介绍如何在HarmonyOS Next中集成微信开放SDK,实现微信登录与数据交互功能。内容涵盖应用配置、SDK依赖设置、模块与构建修改、工具类添加及常见问题处理,适用于教育场景下的开发者学习与实践。
924 0
|
索引 Python
%g是什么
`%g` 是 Python 字符串格式化中的一种格式说明符,用于表示浮点数或整数,能自动选择最合适的表示法。当数值为整数时,它显示整数;当数值较大或含小数时,它选择科学记数法或小数点记数法,并去掉无用的零。例如:
2700 1
|
Java 数据库 容器
J2EE的体系架构
J2EE是Java2平台企业版(Java 2 Platform,Enterprise Edition),它的核心是一组技术规范与指南,提供基于组件的方式来设计、开发、组装和部署企业应用。J2EE使用多层分布式的应用模型。
3118 0