zoukankan      html  css  js  c++  java
  • [STM32]按键处理 SmartKey

    特别声明并致敬:本文思想及代码来自-->[点击网址跳转https://www.cnblogs.com/yangfengwu/p/11669354.html

    实现的功能(按键的状态)

    1. 检测到按键按下

    2. 检测到按键按下一定时间

    3. 检测到按键松开(按下后的松开)

    4. 检测到按键松开一定时间

    注意:示例代码中,

    1. 检测按下,检测按下一定时间,不能同时使用;

    2. 检测松开,检测松开一定时间,不能同时使用;

    用到的资源

    1. 引脚的输入

    2. 1ms定时器

    3. 主循环扫描处理

    4. 全局变量

    单个按键处理的思路

    1. 主程序中不断扫描按键引脚的状态,根据引脚状态判断按键按下或松开的状态,执行不同的代码;

    2. 在1ms定时器中,对不同状态下,自增消抖变量,自增松开或按下的时间;

    3. 在主程序扫描函数中,处理不同状态的跳转。

    建立全局变量:int KeySmartConfig[7]={0};

    KeySmartConfig[0] KeySmartConfig[1] KeySmartConfig[2] KeySmartConfig[3] KeySmartConfig[4] KeySmartConfig[5] KeySmartConfig[6]
    消抖变量 按下标记 松开标记 按下标记拷贝 松开变价拷贝 按下时间(ms) 松开时间(ms)

    1.扫描按键按下,

    判断按下标记未置位,表明是刚按下,消抖自增;

    超时后,清空消抖变量,置位按下标记,复位松开标记;

    2.扫描按键松开,消抖自增;

    超时后,清空消抖变量,

    判断依然松开,置位松开标记,复位按下标记

    1.消抖后,判断按键按下,置位;

    2.消抖后,判断按键松开,复位

    表示按键已按下(与松开互斥)

    1.消抖后,判断按键松开,置位;

    2.消抖后,判断按键按下,复位

    表示按键已松开(与按下互斥)

    1. 随着按下标记的状态而改变

    2. 主程序中,

    判断置位时,检测按下时间超时,

    则状态为按下一定时间

    1. 随着松开标记的状态而改变

    2. 主程序中,

    判断置位时,检测按下时间超时,

    则状态为松开一定时间

    在1ms定时器中

    按下标记若置位,自增;

    按下标记若复位,清零

    在1ms定时器中

    松开标记若置位,自增;

    松开标记若复位,清零

    具体代码:

    smart_key.h

    #ifndef __SMART_KEY_H_
    #define __SMART_KEY_H_
    
    #ifndef __KEY_C_
    #define __KEY_C_ extern
    #else
    #define __KEY_C_ 
    #endif
    
    #include "key.h"
    
    
    
    #define KeySmartConfigDown 0                                                     /* 按下电平  0-低电平表示按下, 1-高电平表示松开 */
    
    #define SmartConfigKeyPinIn        GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) //PE2    /* 检测的按键引脚 */
    
    __KEY_C_ int KeySmartConfig[7];                                                    //消抖变量||按下标记||松开标记||按下标记考别||按下时间(ms)||松开时间(ms)
    
    void SmartConfigKey(void);
    
    
    #endif
    smart_key.h

    smart_key.c

    #include "smart_key.h"
    
    
    
    int KeySmartConfig[7]={0};    //消抖变量||按下标记||松开标记||按下标记拷贝||松开标记拷贝||按下时间(ms)||松开时间(ms)
    
    
    //按键处理
    void SmartConfigKey(void)
    {
        if(SmartConfigKeyPinIn == KeySmartConfigDown)    //扫描到按键按下
        {
            if(KeySmartConfig[1] == 0)    //判断按下标记为0,表示上次扫描未按下
            {
                KeySmartConfig[0] ++;    //自增消抖变量
                
                if(KeySmartConfig[0] >= 500)    //消抖完成,判断按键按下
                {
                    KeySmartConfig[0] = 0;    //清空消抖变量
                    KeySmartConfig[2] = 0;    //清空松开标记
                    KeySmartConfig[1] = 1;    //置位按下标记
                    KeySmartConfig[3] = 1;    //拷贝按下标记
                    KeySmartConfig[4] = 0;    //拷贝松开标记
                }
            }
        }else        //扫描到按键松开
        {
            KeySmartConfig[0]++;    //自增消抖变量
            if(KeySmartConfig[0] > 2000) //判断松开
            {
                KeySmartConfig[0] = 0;    //清空消抖变量
                if(KeySmartConfig[1] == 1)    //消抖完成,判断按下后松开
                {
                    KeySmartConfig[2] = 1;    //置位松开标记
                    KeySmartConfig[1] = 0;    //清空按下标记
                    KeySmartConfig[3] = 0;    //拷贝按下标记
                    KeySmartConfig[4] = 1;    //拷贝松开标记
                }
                
            }
        }
        
    }
    smart_key.c

    1ms定时器中断

    timer.c

    //定时器3中断服务函数
    void TIM3_IRQHandler(void)
    {
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
        {
            
            if(KeySmartConfig[1])
            {
                KeySmartConfig[5]++;
            }else
            {
                KeySmartConfig[5] = 0;
            }
            
            if(KeySmartConfig[2])
            {
                KeySmartConfig[6]++;
            }else
            {
                KeySmartConfig[6] = 0;
            }
            
        }
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
    }
    定时器中断

    主程序使用

         while(1) 
        {        
            SmartConfigKey();    //扫描按键
            
            //例1: 检测到按键按下,执行某端代码
    //        if(KeySmartConfig[3] == 1)    //判断按键按下:"拷贝的按下按键标记"置位
    //        {
    //            KeySmartConfig[3] = 0;    //清空后,只有按键松开再按下的时候才会进入
    //            
    //            //执行的代码
    //            u3_printf("
    按键按下
    ");
    //        }
            
            //例2:检测到按键按下,然后根据按下时间执行某段代码
            if(KeySmartConfig[3] == 1)
            {
                if(KeySmartConfig[5] >= 3000)    //按下时间大于3s
                {
                    KeySmartConfig[3] = 0;    //清空后,只有按键松开再按下的时候才会进入
                
                    //执行的代码
                    u3_printf("
    按键按下持续时间大于3s
    ");
                }
            }
            
    //        //例3:检测到按键松开执行某段代码
    //        if(KeySmartConfig[4] == 1)
    //        {
    //            KeySmartConfig[4] = 0;    //清空后,只有按键按下再松开的时候才会进入
    //            
    //            //执行的代码
    //            u3_printf("
    按键按下后松开
    ");
    //            
    //        }
            
            //例4:检测到按键松开,然后根据松开时间执行某段代码
            if(KeySmartConfig[4] == 1)
            {
                if(KeySmartConfig[6] >= 3000)    //松开时间大于3s
                {
                    KeySmartConfig[4] = 0;    //清空后,只有按键按下再松开的时候才会进入
                
                    //执行的代码
                    u3_printf("
    按键松开时间大于3s
    ");
                }
                
            }
            
        }                                                
    }
    主程序使用
  • 相关阅读:
    当我有一台服务器时我做了什么
    git 安装及基本配置
    关于大厂面试中问到的二十几个 HTTP 面试题
    日问周刊 | 全栈面试汇总 | 第七期
    dockerfile 最佳实践及示例
    面试官:如果 http 响应头中 ETag 值改变了,是否意味着文件内容一定已经更改
    Nginx 反向代理时获取用户的真实 IP
    Go 语言实现 HTTP 层面的反向代理
    Go 语言中的 Http 路由基础
    Json Schema
  • 原文地址:https://www.cnblogs.com/doitjust/p/13933563.html
Copyright © 2011-2022 走看看