【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 #以管理…

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

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

RPC实现原理,怎么跟调用本地一样

回答1 要让⽹络通信细节对使⽤者透明,我们需要对通信细节进⾏封装,我们先看下⼀个 RPC 调⽤的流程涉及到哪些通 信细节: 1. 服务消费⽅( client )调⽤以本地调⽤⽅式调⽤服务; 2. client stub 接收到调…

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

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

【记录52】el-table-column 添加fixed属性 滚动条无法滑动

问题: el-table-column 添加fixed属性 滚动条无法滑动 使用element UI组件,用到el-table的el-table-column的fixed属性时,当滚动条长度小于固定列时,滚动条无法通过鼠标去点击滑动操作 原因 fixed是用来固定列的属性,其…

rtthread学习笔记系列-- 22 dataqueue

文章目录 22 dataqueue https://github.com/wdfk-prog/RT-Thread-Study 22 dataqueue 消息队列:消息队列能够接收来自线程或中断服务例程中不固定长度的消息,并把消息缓存在自己的内存空间中。其他线程也能够从消息队列中读取相应的消息,而当…

了解Node.js

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

微信小程序在使用页面栈保存页面信息时,如何避免数据丢失?

微信小程序在使用页面栈保存页面信息时避免数据丢失的方法: 一、使用全局变量存储关键数据: 定义一个全局变量,例如在 app.js 中,用于存储页面的重要信息。在页面的 onHide 或 onUnload 生命周期中,将需要保存的数据…

文件上传 分片上传

分片上传则是将一个大文件分割成多个小块分别上传,最后再由服务器合并成完整的文件。这种做法的好处是可以并行处理多个小文件,提高上传效率;同时,如果某一部分上传失败,只需要重传这一部分,不影响其他部分…

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大模型技术在信创安全领域中的创新应用…

Picocli 命令行框架

官方文档 https://picocli.info/ 官方提供的快速入门教程 https://picocli.info/quick-guide.html 使用 Picocli 创建命令行应用程序 Picocli 是一个用于构建 Java 命令行应用的强大框架,它简化了参数解析和帮助消息生成的过程。 下面是如何使用 Picocli 构建简单命…

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

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

M4Pro安装homebrew并基于homebrew安装MySQL踩坑记录

系统偏好设置允许安装任何来源应用:sudo spctl --master-disable 清除提示已损坏软件的安全隔离,重新安装: xattr -cr 空格+App路径 安装homebrew: /opt/homebrew/Cellar 安装包目录 /opt/homebrew/etc 默认运行目…

tmux 中鼠标滚动异常:^[[A和^[[B是什么以及如何解决

tmux 中鼠标滚动异常问题及解决方案 在使用 tmux 时,有时我们会遇到一个现象:当尝试使用鼠标滚轮滚动窗口内容时,终端中会出现一串类似 ^[[A^[[A 的字符。这让人困惑,不知道鼠标滚动为什么不起作用,也不清楚这些字符究…

【Vue】mouted、created、computed区别

mouted、created、computed区别 前端vue重构 — computed、watch、组件通信等常用知识整理 created和mouted都是vue生命周期中的钩子函数,通常用来做一些初始化的工作,比如发送http请求、对组件绑定自定义事件 created:实例创建完后立即调用…

前端如何设计一个回溯用户操作的方案

同一个项目,为什么我本地无法复现,只有客户的设备才复现? 如何获取用户的操作路径呢? 两种方案:埋点和rrweb 埋点就很简单了,将所有可能操作的节点都进行预埋数据;但埋点简单并不省心&#xff…

概率论考前一天

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

2Hive表类型

2Hive表类型 1 Hive 数据类型2 Hive 内部表3 Hive 外部表4 Hive 分区表5 Hive 分桶表6 Hive 视图 1 Hive 数据类型 Hive的基本数据类型有:TINYINT,SAMLLINT,INT,BIGINT,BOOLEAN,FLOAT,DOUBLE&a…

FPGA工程师成长四阶段

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