stm32按键 长按 短按 函数

发布者:gamma13最新更新时间:2019-03-28 来源: eefocus关键字:stm32  按键  长按  短按  函数 手机看文章 扫描二维码
随时随地手机看文章

在stm32工程中,长按和短按的代码书写, 调用的读取按键状态的底层函数。封装成的按键函数代码。下面是函数的头文件,和.c文件的代码。使用定时器来扫描按键。


#define KEY_ON 1

#define KEY_OFF 0

#define KEY_NULL 0

#define KEY_SHORT 1

#define KEY_LONG  10

#define SHORT_TIME 200

uint8_t Key_state(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)

{

static uint8_t key_value = KEY_NULL;

static uint16_t longtime;

if( (longtime == 0) && (key_value != KEY_NULL))  //当按键状态为长按或者短按时,而longtime 不为零,则按键状态清零

     key_value = KEY_NULL;

}

if ( time == 5 ) /* 5 * 1 ms = 5ms 定时时间到 */

     {

        time = 0;

if(KEY_PRESS(GPIOx,GPIO_Pin))  //按键按下

    {

         longtime++;

        }

        else  //按键松开

{

    if((longtime >= 3) && (longtime <= SHORT_TIME))  //短按

{

key_value = KEY_SHORT;

}

else if( longtime > SHORT_TIME ) //长按

{

    key_value = KEY_LONG;

}

else  //去抖动

{

    key_value = KEY_NULL;

}

longtime = 0; //清零

}

     }  

 return key_value;

}

上面的代码,是按键松开才能判断按键的状态,是长按还是短按。在实际项目中我需要,按键按下一段时间后,判断为按键长按,不用松开,返回按键长按。参考网上的代码,使用状态机写了如下代码


#define    KEY_PRESS(GPIOx,GPIO_Pin)      GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)

#define KEY_INPUT           KEY_PRESS(GPIOx,GPIO_Pin)    //读取按键状态

 

#define KEY_STATE_0         0       // 按键状态位

#define KEY_STATE_1         1

#define KEY_STATE_2         2

#define KEY_STATE_3         3

 

#define LONG_KEY_TIME       300     //长按的3秒时间

#define SINGLE_KEY_TIME     3       // 短按的消抖时间

 

#define N_KEY    0                  // 无状态

#define S_KEY    1                  // 单击

#define L_KEY    10                 // 长按

函数的主体部分,代码中按下按键读取到高电平。


unsigned char key_driver(void) 

{     

    static unsigned char key_state = 0;         // 按键状态变量

    static unsigned int key_time = 0;           // 按键计时变量

    unsigned char key_press, key_return; 

 

    key_return = N_KEY;                         // 清除 返回按键值

 

    key_press = KEY_INPUT;                      // 读取当前键值

 

    switch (key_state)     

    {       

        case KEY_STATE_0:                       // 按键状态0:判断有无按键按下

            if (key_press == KEY_ON)                     // 有按键按下

            {

                key_time = 0;                   // 清零时间间隔计数

                key_state = KEY_STATE_1;        // 然后进入 按键状态1

            }        

            break;

 

        case KEY_STATE_1:                       // 按键状态1:软件消抖(确定按键是否有效,而不是误触)。按键有效的定义:按键持续按下超过设定的消抖时间。

            if (key_press == KEY_ON)                     

            {

                key_time++;                     // 一次10ms

                if(key_time>=SINGLE_KEY_TIME)   // 消抖时间为:SINGLE_KEY_TIME*10ms = 30ms;

                {

                    key_state = KEY_STATE_2;    // 如果按键时间超过 消抖时间,即判定为按下的按键有效。按键有效包括两种:单击或者长按,进入 按键状态2, 继续判定到底是那种有效按键

                }

            }         

            else key_state = KEY_STATE_0;       // 如果按键时间没有超过,判定为误触,按键无效,返回 按键状态0,继续等待按键

            break; 

 

        case KEY_STATE_2:                       // 按键状态2:判定按键有效的种类:是单击,还是长按

            if(key_press == KEY_OFF)                       // 如果按键在 设定的长按时间 内释放,则判定为单击

            { 

                 key_return = S_KEY;            // 返回 有效按键值:单击

                 key_state = KEY_STATE_0;       // 返回 按键状态0,继续等待按键

            } 

            else

            {

                key_time++;                     

 

                if(key_time >= LONG_KEY_TIME)   // 如果按键时间超过 设定的长按时间(LONG_KEY_TIME*10ms=200*10ms=2000ms), 则判定为 长按

                {

                    key_return = L_KEY;         // 返回 有效键值值:长按

                    key_state = KEY_STATE_3;    // 去状态3,等待按键释放

                }

            }

            break;

 

      case KEY_STATE_3:                         // 等待按键释放

          if (key_press == KEY_OFF) 

          {

              key_state = KEY_STATE_0;          // 按键释放后,进入 按键状态0 ,进行下一次按键的判定

          }         

          break; 

 

        default:                                // 特殊情况:key_state是其他值得情况,清零key_state。这种情况一般出现在 没有初始化key_state,第一次执行这个函数的时候

            key_state = KEY_STATE_0;

            break;

    }

 

    return key_return;                          // 返回 按键值

unsigned char key_handle(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)

{

unsigned char key_value;

  if ( time == 10 ) /* 10 * 1 ms = 10ms 定时器 */

   {

        time = 0;

    key_value = key_driver(GPIOx,GPIO_Pin); 

}

return key_value;

}

 在main.c中调用


int main(void)

{

int8_t key_value;

/* led 初始化*/ 

LED_GPIO_Config();


BASIC_TIM_Init();


Key_GPIO_Config();


  while(1)

  {

 

// key_value = Key_state(KEY1_GPIO_PORT,KEY1_GPIO_PIN);

key_value = key_handle(KEY1_GPIO_PORT,KEY1_GPIO_PIN);

 

if(key_value == KEY_SHORT)

{

  

    LED1_TOGGLE;

}

else if(key_value == KEY_LONG)

{

    LED2_TOGGLE; 

}


  }

}

这样可以实现长按不松手,执行长按的代码。以后遇到好的思想会继续学习,总结下来。

关键字:stm32  按键  长按  短按  函数 引用地址:stm32按键 长按 短按 函数

上一篇:STM32的按键部分
下一篇:关于STM32按键妙用详解

推荐阅读最新更新时间:2024-03-16 16:26

嵌入式系统的LCD人机交互菜单设计
  嵌入式系统的LCD人机交互菜单设计   近年来,LCD显示器的普及和微处理器向大容量的发展使嵌入式系统的人机交互功能得到了显著的提高。在很多场合下,良好的图形用户界面(GUI)和便捷的操作环境是影响产品成败的关键因素之一。如何充分利用成本低、资源少的单片机系统实现完善的人机交互功能已成为单片机设计者需要解决的一个问题。   目前,国内外许多先进的智能仪表不仅在测量精度和采样速率等方面有较高的性能指标,在人机交互的友好性方面也有许多独到之处。笔者在为德国TOX冲压技术有限公司研制智能压力监控仪的过程中,积累了一些嵌入式系统人机交互技术的没计经验。本文以此为实例,介绍其设计方法。    1 智能压力监控仪概述    智能压
[工业控制]
STM32固件库3.3版本在STM3210e-eval开发板上的移植
首先建立工程,我习惯性在工程文件夹下建立以下几个文件夹,分别放不同的文件,以区别不同文件的不同作用,方便寻找和移植。如下: 在PROJECT文件夹下建立工程项目,启动keil,开始建立工程。 注意建立在PROJECT文件夹下。 随便起个名字,我起的名字是MDK,建立后,会提示你选择器件型号 我的器件如上图,所以选择。确定后会询问你是否加入启动文件。我们用stm32的固件库,所以不用mdk的,选择否。 下面配置工程的选项option,右键点Target会看到Options。 以下是各个选项卡的配置内容。 这里注意的是在output选项卡里要选择目标文件存放的位置,
[单片机]
<font color='red'>STM32</font>固件库3.3版本在STM3210e-eval开发板上的移植
【话说定时器系列】之六:STM32定时器输入捕获话题
STM32定时器 是 ST MCU 内部最基础且常用的外设,实际应用尤为普遍。去年,电堂推出了 《STM32 TIMER基础及常规应用介绍》 ,为大家梳理了 STM32 TIMER 的庞大内容,涵盖 TIMER 的基本应用原理、常规应用等。现在将课程内容整理为文章,针对STM32定时器有基本了解的用户,分享具体的应用实现环节及常见问题解决。 STM32定时器除了基本计数定时功能外,还对外拓展了输入、输出通道,从而实现输入捕捉、比较输出功能。 输入捕获【Input Capture】基本原理 : 定时器针对外部输入信号或内部触发信号实行边沿捕捉;产生捕捉事件,并可以触发中断或DMA请求,同时记录捕捉时刻计数器的值。基
[单片机]
stm32 IAP 实现
在对STM32存储器结构及相关知识了解后,我们就可以进行IAP的设计了。 在上一篇笔记中,进行了一个简单的IAP程序结构,以及和User App程序的相互联系的系统设计。 本篇对IAP实现的细节进行了较为详细的论述,包括源码结构的设计;我们从上位机(PC C#)和下位机(MCU C)共同描述IAP功能的实现过程。 1 STM32的IAP实现平台 IAP功能的实现需要两个方面(上位机和STM32上的IAP程序)的密切合作。因此,我们除了需要知道STM32芯片上的IAP程序结构,我们还需要了解上位机的程序结构,这样才能使上位机和STM32很好的相互工作。 下位机(指的是STM32构成的单片机系统): 本下位机系统使用C语言
[单片机]
<font color='red'>stm32</font> IAP 实现
9G-STM32 LwIP测试过程简介
一,准备STM32 LwIP软件包 1,在http://www.st.com/mcu/devicedocs-STM32F107RC-110.html 下载lwIP TCP/IP stack demonstration for STM32F107xx connectivity line microcontrollers软件包 an3102.zip http://www.st.com/stonline/products/support/micro/files/an3102.zip 2,在http://www.st.com/mcu/devicedocs-STM32F107RC-110.html 下载lwIP TCP
[单片机]
PIC单片机AD通道转换函数问题解析
  AD转换   D转换就是模数转换。顾名思义,就是把模拟信号转换成数字信号。主要包括积分型、逐次逼近型、并行比较型/串并行型、Σ-Δ调制型、电容阵列逐次比较型及压频变换型。   A/D转换器是用来通过一定的电路将模拟量转变为数字量。模拟量可以是电压、电流等电信号,也可以是压力、温度、湿度、位移、声音等非电信号。但在A/D转换前,输入到A/D转换器的输入信号必须经各种传感器把各种物理量转换成电压信号。   AD转换分类   1)积分型(如TLC7135)   积分型AD工作原理是将输入电压转换成时间(脉冲宽度信号)或频率(脉冲频率),然后由定时器/计数器获得数字值。其优点是用简单电路就能获得高分辨率, 但缺点是由于转换精度
[单片机]
PIC单片机AD通道转换<font color='red'>函数</font>问题解析
基于STM32的高性能、低成本芯片的税控器方案设计
随着金税工程的推广,税控市场将得到迅猛发展,作为四大税控产品之一,其市场份额不容小觑,税控厂家需要为产品的性能、成本做多方面考量。之前各个厂家的税控器方案,可能因为成本的考虑选择了8位单片机,也有因为性能扩展的需要选择16位、32位MCU作为税控器主控芯片。今天,ST(意法半导体公司)延续了其之前基于STR7的税控器体系架构,并借鉴在STR9银税一体机方案中的经验,推出了一款采用2这一高性能、的税控器方案。   方案介绍  与以往方案(图1)对比,STM32方案(图2)结构简单,模块功能化,减少了外部数据总线的数量,有效减小制板面积,很好地保证了系统的可靠性及安全性。ST还提供详细的设计报告,无论是软件还是硬件的开发都大
[单片机]
用C库函数写文件复制程序
教程里说:相信大家熟悉了Linux系统函数之后,用C库函数来实现相似功能会感觉就容易多了。 所以尝试写出类似L系统函数的文件复制程序。 (C编程语言第二版书摘Chapter 7 - Input and Output 2中有一个使用getc,putc进行复制的示例 ) 下面是可能用到的库函数,但是用得越多出错几率越大 size_t fread(void *ptr, size_t size, size_t nobj, FILE *stream) fread reads from stream into the array ptr at most nobj objects of size size. fread ret
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved