【STM8S】STM8S之自定义短、长、连击按键

本文最后修改时间:2018年10月22日 01:57

一、本节简介

本文介绍STM8S系列如何实现按键的短按、长按、连击。

二、实验平台

编译软件:IAR for STM8 1.42.2

硬件平台:stm8s003f3p6开发板

仿真器:ST-LINK

库函数版本:V2.0.0

三、版权声明

1)作者:甜甜的大香瓜

2)声明:喝水不忘挖井人,转载请注明出处。

3)纠错/业务合作:897503845@qq.com

4)香瓜嵌入式之STM8/STM32群:164311667

5)本文出处:原创连载资料《简单粗暴学STM8和STM32》

6)完整开源资料下载地址(电脑端打开):opengua.taobao.com

四、实验前提

1、在进行本文步骤前,请先阅读以下章节:

1)《简单粗暴学STM8STM32》的第一章和第三章章节

2、在进行本文步骤前,请先实现以下章节:

1)《简单粗暴学STM8STM32》的《STM8S之内外部16M晶振》。

五、基础知识

暂无

六、硬件原理

    

由上图可知当K1松开时PD3为高电平,K1按下后PD3为低电平。

七、实验步骤

1、工程中添加自己写的按键驱动

1)写一个按键驱动GUA_Key.c(存放在工程的USER文件夹中)

//**********************************************************************

//name:         GUA_Key.c

//introduce:    按键驱动

//author:       甜甜的大香瓜     

//email:        897503845@qq.com  

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2018.10.16

//**********************************************************************

#include "stm8s.h"

#include "GUA_Key.h"

/*********************宏定义************************/

//按键触发宏 

#define GUA_KEY_TRIGGER            RESET                                //低电平触发 

 

//目测的时钟基准

//#define GUA_KEY_STANDARD_1MS            100

//按键消抖宏 

#define GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT           1000         //短按键消抖数

#define GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT            150000       //长按2.5消抖数

/*********************内部变量************************/ 

static GUA_U32 sGUA_Key_DisappearsShakes_TriggerCount = 0;              //消抖时的触发状态计数值 

 

//**********************************************************************

//name:         GUA_Key_Scan

//introduce:    按键检测触发状态

//parameter:    none

//return:       GUA_KEY_STATUS_IDLE or GUA_KEY_STATUS_TRIGGER_SHORT or GUA_KEY_STATUS_TRIGGER_LONG or GUA_KEY_STATUS_NO_LOOSEN

//author:       甜甜的大香瓜

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2018.10.16

//**********************************************************************

GUA_U8 GUA_Key_Scan(void)     

{     

  GUA_U32 nGUA_TimeOut = 0;   

  

  //触发

  if(GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) == GUA_KEY_TRIGGER)  

  { 

    //如果上一次按键是长按键结束的,需要检测到松开方可开始下一次计数

    if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)

    {

      return GUA_KEY_STATUS_NO_LOOSEN;

    }

    //计数

    sGUA_Key_DisappearsShakes_TriggerCount++;   

   

    //判断计数是否足够 

    while(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT) 

    { 

      //检测到松开、超时的时候,则处理 

      if((GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)) 

      { 

        //长按2.5S时 

        if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) 

        {           

          //返回

          return GUA_KEY_STATUS_TRIGGER_LONG;                          

        }                

        //短按键时 

        else 

        {      

          //超时计数值清零

          nGUA_TimeOut = 0;

           

          //检测是否有连按

          while((GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER))

          {            

            //没有被按下,超时,则表示只有1次按键

            if(nGUA_TimeOut++ > 100000)

            {

              //计数值清零

              sGUA_Key_DisappearsShakes_TriggerCount = 0;

             

              return GUA_KEY_STATUS_TRIGGER_SHORT;

            }                     

          }

         

          //判断计数是否足够 

          while(GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) == GUA_KEY_TRIGGER)

          {

            //开始计数

            sGUA_Key_DisappearsShakes_TriggerCount++;

            //检测到松开、超时的时候,则处理 

            if((GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)) 

            {             

              //长按2.5S时 

              if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) 

              {           

                //清除计数器

                sGUA_Key_DisappearsShakes_TriggerCount = 0;

               

                //返回

                return GUA_KEY_STATUS_TRIGGER_LONG;                          

              }                

              //短按键时 

              else 

              {   

                //清除计数器

                sGUA_Key_DisappearsShakes_TriggerCount = 0;

                

                //返回

                return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT;                 

              } 

            }                         

          }

         

          //清除计数器

          sGUA_Key_DisappearsShakes_TriggerCount = 0;

               

          //返回

          return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT;         

        } 

      } 

     

      //继续计数用来判断长短按键 

      sGUA_Key_DisappearsShakes_TriggerCount++;          

    }    

  } 

  //未触发 

  else 

  { 

    sGUA_Key_DisappearsShakes_TriggerCount = 0;  

  } 

   

  return GUA_KEY_STATUS_IDLE;   

}  

//**********************************************************************

//name:         GUA_Key_Init

//introduce:    按键初始化

//parameter:    none

//return:       none

//author:       甜甜的大香瓜

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2018.10.16

//**********************************************************************

void GUA_Key_Init(void)

{

  //按键IO初始化

  GPIO_Init(GUA_KEY_PORT, GUA_KEY_PIN, GUA_KEY_MODE);      

}

2)写一个驱动头文件GUA_Key.h(存放在工程的USER文件夹中)

//**********************************************************************

//name:         GUA_Key.h

//introduce:    按键驱动的头文件

//author:       甜甜的大香瓜     

//email:        897503845@qq.com  

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2018.10.16

//**********************************************************************

#ifndef _GUA_KEY_H_

#define _GUA_KEY_H_

/*********************宏定义************************/

//类型宏

#ifndef GUA_C

typedef char GUA_C;

#endif

#ifndef GUA_U8

typedef unsigned char GUA_U8;

#endif

#ifndef GUA_8

typedef signed char GUA_8;

#endif

#ifndef GUA_U16

typedef unsigned short GUA_U16;

#endif

#ifndef GUA_16

typedef signed short GUA_16;

#endif

#ifndef GUA_U32

typedef unsigned long GUA_U32;

#endif

#ifndef GUA_32

typedef signed long GUA_32;

#endif

#ifndef GUA_U64

typedef unsigned long long GUA_U64;

#endif

#ifndef GUA_64

typedef signed long long GUA_64;

#endif 

//按键引脚宏

#define GUA_KEY_PORT                    GPIOD

#define GUA_KEY_PIN                     GPIO_PIN_3

#define GUA_KEY_MODE                    GPIO_MODE_IN_PU_NO_IT

//按键的触发状态 

#define GUA_KEY_STATUS_IDLE                     0       //按键没触发 

#define GUA_KEY_STATUS_TRIGGER_SHORT            1       //短按键触发

#define GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT     2       //双击触发

#define GUA_KEY_STATUS_TRIGGER_LONG             3       //长按键2.5S触发

#define GUA_KEY_STATUS_NO_LOOSEN                4       //按键没松开

/*********************外部函数声明************************/

GUA_U8 GUA_Key_Scan(void); 

void GUA_Key_Init(void);

#endif

3)工程中添加GUA_Key.c

4)添加驱动的路径

$PROJ_DIR$\..\USER 

注意USER文件夹是与“Project”、“FWlib”文件夹同级的自定义文件,用于存放香瓜写的代码。

2、添加库的驱动

1)添加库的驱动文件

2)添加库的驱动头文件(stm8s_conf.h中)

#include "stm8s_gpio.h"

3、应用层中调用

1)添加头文件(main.c中)

#include "GUA_Key.h"

2)初始化(main.c的main函数中)

  //按键初始化

  GUA_Key_Init();

3)添加按键判断的逻辑代码(main.c的main函数中)

        GUA_U8 nGUA_Ret;

        //检测按键当前状态

        nGUA_Ret = GUA_Key_Scan();

        //短按键触发时

        if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_SHORT)

        {   

        }

        //连击触发时

        else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT)

        { 

        }

        //长按键触发时

        else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_LONG)

        {

        }

八、注意事项

暂无

九、实验结果

暂无

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

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

相关文章

数据库(MySQL)练习

数据库(MySQL)练习 一、练习1.15练习练习 二、注意事项2.1 第四天 一、练习 1.15练习 win11安装配置MySQL超详细教程: https://baijiahao.baidu.com/s?id1786910666566008458&wfrspider&forpc 准备工作: mysql -uroot -p #以管理…

【深度学习地学应用|滑坡制图、变化检测、多目标域适应、感知学习、深度学习】跨域大尺度遥感影像滑坡制图方法:基于原型引导的领域感知渐进表示学习(一)

【深度学习地学应用|滑坡制图、变化检测、多目标域适应、感知学习、深度学习】跨域大尺度遥感影像滑坡制图方法:基于原型引导的领域感知渐进表示学习(一) 【深度学习地学应用|滑坡制图、变化检测、多目标域适应、感知学习、深度学习】跨域大…

《C++11》并发库:简介与应用

在C11之前,C并没有提供原生的并发支持。开发者通常需要依赖于操作系统的API(如Windows的CreateThread或POSIX的pthread_create)或者第三方库(如Boost.Thread)来创建和管理线程。这些方式存在以下几个问题: …

了解Node.js

Node.js是一个基于V8引擎的JavaScript运行时环境,它允许JavaScript代码在服务器端运行,从而实现后端开发。Node.js的出现,使得前端开发人员可以利用他们已经掌握的JavaScript技能,扩展技能树并成为全栈开发人员。本文将深入浅出地…

js解决 Number失精度问题

const updatePromises adinfo.rows.map(async item > {const cwf await uniCloud.httpclient.request("https://api.oceanengine.com/open_api/v3.0/project/list/", {method: GET,data: {advertiser_id: item.account_id},// 1. 指定text数据格式dataType: tex…

实力认证 | 海云安入选《信创安全产品及服务购买决策参考》

近日,国内知名安全调研机构GoUpSec发布了2024年中国网络安全行业《信创安全产品及服务购买决策参考》,报告从产品特点、产品优势、成功案例、安全策略等维度对各厂商信创安全产品及服务进行调研了解。 海云安凭借AI大模型技术在信创安全领域中的创新应用…

windows系统“GameInputRedist.dll”文件丢失或错误导致游戏运行异常如何解决?windows系统DLL文件修复方法

GameInputRedist.dll是存放在windows系统中的一个重要dll文件,缺少它可能会造成部分游戏不能正常运行。当你的电脑弹出提示“无法找到GameInputRedist.dll”或“计算机缺少GameInputRedist.dll”等错误问题,请不用担心,我们将深入解析DLL文件…

概率论考前一天

判断是不是分布函数:单调不减,右连续,F负无穷为0, F正无穷为1 判断是不是密度函数:非负性(函数任意地方都大于0),规范:积分为1

FPGA工程师成长四阶段

朋友,你有入行三年、五年、十年的职业规划吗?你知道你所做的岗位未来该如何成长吗? FPGA行业的发展近几年是蓬勃发展,有越来越多的人才想要或已经踏进了FPGA行业的大门。很多同学在入行FPGA之前,都会抱着满腹对职业发…

springCloudGateway+nacos自定义负载均衡-通过IP隔离开发环境

先说一下想法,小公司开发项目,参考若依框架使用的spring-cloud-starter-gateway和spring-cloud-starter-alibaba-nacos, 用到了nacos的配置中心和注册中心,有多个模块(每个模块都是一个服务)。 想本地开发,…

向量数据库如何助力Text2SQL处理高基数类别数据

01. 导语 Agent工作流和 LLMs (大语言模型)的出现,让我们能够以自然语言交互的模式执行复杂的SQL查询,并彻底改变Text2SQL系统的运行方式。其典型代表是如何处理High-Cardinality Categorical Data (高基数类别数据&am…

qBittorent访问webui时提示unauthorized解决方法

现象描述 QNAP使用Container Station运行容器,使用Docker封装qBittorrent时,访问IP:PORT的方式后无法访问到webui,而是提示unauthorized,如图: 原因分析 此时通常是由于设备IP与qBittorrent的ip地址不在同一个网段导致…

工程水印相机结合图纸,真实现场时间地点,如何使用水印相机,超简单方法只教一次!

在工程管理领域,精准记录现场信息至关重要。水印相机拍照功能,为工程人员提供了强大的现场信息记录工具,助力工程管理和统计工程量,更可以将图片分享到电脑、分享给同事,协同工作。 一、打开图纸 打开手机版CAD快速看图…

GO语言实现KMP算法

前言 本文结合朱战立教授编著的《数据结构—使用c语言(第五版)》(以下简称为《数据结构(第五版)朱站立》)中4.4.2章节内容编写,KMP的相关概念可参考此书4.4.2章节内容。原文中代码是C语言&…

LeetCode 热题 100_从前序与中序遍历序列构造二叉树(47_105_中等_C++)(二叉树;递归)

LeetCode 热题 100_从前序与中序遍历序列构造二叉树(47_105) 题目描述:输入输出样例:题解:解题思路:思路一(递归): 代码实现代码实现(思路一(递归…

文档智能:OCR+Rocketqa+layoutxlm <Rocketqa>

此次梳理Rocketqa,个人认为该篇文件讲述的是段落搜索的改进点,关于其框架:粗检索 重排序----(dual-encoder architecture),讲诉不多,那是另外的文章; 之前根据文档智能功能&#x…

ubuntu官方软件包网站 字体设置

在https://ubuntu.pkgs.org/22.04/ubuntu-universe-amd64/xl2tpd_1.3.16-1_amd64.deb.html搜索找到需要的软件后,点击,下滑, 即可在Links和Download找到相关链接,下载即可, 但是找不到ros的安装包, 字体设…

使用 WPF 和 C# 绘制覆盖网格的 3D 表面

此示例展示了如何使用 C# 代码和 XAML 绘制覆盖有网格的 3D 表面。示例使用 WPF 和 C# 将纹理应用于三角形展示了如何将纹理应用于三角形。此示例只是使用该技术将包含大网格的位图应用于表面。 在类级别,程序使用以下代码来定义将点的 X 和 Z 坐标映射到 0.0 - 1.…

[Do374]Ansible一键搭建sftp实现用户批量增删

[Do374]Ansible一键搭建sftp实现用户批量增删 1. 前言2. 思路3. sftp搭建及用户批量新增3.1 配置文件内容3.2 执行测试3.3 登录测试3.4 确认sftp服务器配置文件 4. 测试删除用户 1. 前言 最近准备搞一下RHCA LV V,外加2.9之后的ansible有较大变化于是练习下Do374的课程内容. 工…

【IDEA 2024】学习笔记--文件选项卡

在我们项目的开发过程中,由于项目涉及的类过多,以至于我们会打开很多的窗口。使用IDEA默认的配置,个人觉得十分不便。 目录 一、设置多个文件选项卡按照文件字母顺序排列 二、设置多个文件选项卡分行显示 一、设置多个文件选项卡按照文件字…