找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

关于单片机按键处理的程序 100%保证可用

查看数: 44036 | 评论数: 19 | 收藏 14
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2015-9-8 15:05

正文摘要:

最近在网上看见一个不错的单片机按键处理程序。所以就和大家分享一下。这个处理程序,对长按和短按都处理的比较细腻。大家在这块不懂的都有可以参照这个程序模板进行修改,本人已经试验,100%保证可用。 单片机 ...

回复

ID:771727 发表于 2020-6-9 03:51
多个按键同时按住,会不会发生冲突。
ID:173256 发表于 2020-6-8 22:35
单个按键组合好像有冲突  比如KYE1要长按实现退出功能  但长按动作前面肯定会经过短按(短按—长按—连击)这时短按就会被触发了
ID:763926 发表于 2020-6-7 16:20
很管用的东西啊
ID:771858 发表于 2020-6-7 14:01
感谢楼主
ID:374361 发表于 2020-5-9 08:58
楼主有点东西
ID:662183 发表于 2020-5-9 00:38
打卡学习,小白报道,感谢分享
ID:711507 发表于 2020-5-8 23:53
学习学习
ID:718536 发表于 2020-4-17 17:58
楼主大大,如果按键进水或者卡死了,导致所有程序运行错误。要如何屏蔽掉这个卡死或者进水的按键呢?
ID:330092 发表于 2018-8-30 03:50
学习了,谢谢分享
ID:377382 发表于 2018-8-4 13:36
不错不错
ID:20672 发表于 2018-8-2 21:24
不错!!!
ID:66287 发表于 2018-7-24 10:21
/*********************************************
工程名:状态机按键处理
作者:


*********************************************/
//#include <reg51.h>
#include <STC15F2K60S2.H>
typedef unsigned char uint8;
typedef unsigned int  uint16;

#define KEY_VALUE_1   0x0e
#define KEY_VALUE_2   0x0d
#define KEY_VALUE_3   0x0b
#define KEY_VALUE_4   0x07
#define KEY_NULL      0x0f

//定义长按键的TICK数,以及连_发间隔的TICK数
#define KEY_LONG_PERIOD         100
#define KEY_CONTINUE_PERIOD     25
//定义按键返回值状态(按下,长按,连_发,释放)
#define KEY_DOWN                0x80
#define KEY_LONG                0x40
#define KEY_CONTINUE            0x20
#define KEY_UP     0x10        //定义按键状态
#define KEY_STATE_INIT           0
#define KEY_STATE_WOBBLE         1
#define KEY_STATE_PRESS          2
#define KEY_STATE_LONG           3
#define KEY_STATE_CONTINUE       4
#define KEY_STATE_RELEASE        5

sbit io_key_1 = P1^1 ;
sbit io_key_2 = P1^2 ;
sbit io_key_3 = P1^3 ;
sbit io_key_4 = P1^4 ;
void Timer0_Init();

void KeyInit(void)
{
     io_key_1 = 1 ;
     io_key_2 = 1 ;
     io_key_3 = 1 ;
     io_key_4 = 1;            
}


static uint8 KeyScan(void)
{
     if(io_key_1 == 0) return KEY_VALUE_1;
     if(io_key_2 == 0) return KEY_VALUE_2;
     if(io_key_3 == 0) return KEY_VALUE_3;
     if(io_key_4 == 0) return KEY_VALUE_4;
     return KEY_NULL ;
}

void GetKey(uint8 *pKeyValue)
{
     static uint8 s_u8KeyState = KEY_STATE_INIT;
     static uint8 s_u8KeyTimeCount = 0 ;
     static uint8 s_u8LastKey = KEY_NULL ;   //保存按键释放时候的键值
     uint8 KeyTemp = KEY_NULL ;

     KeyTemp = KeyScan();         //获取键值
     switch(s_u8KeyState)
     {
         case KEY_STATE_INIT :
                {
                    if(KEY_NULL != (KeyTemp))
                    {
                        s_u8KeyState = KEY_STATE_WOBBLE ;
                    }
                }
         break ;
         case KEY_STATE_WOBBLE:       //消抖
                {
                    s_u8KeyState = KEY_STATE_PRESS ;     
                }
         break ;
         case KEY_STATE_PRESS :
                {
                    if(KEY_NULL != (KeyTemp))
                    {
                        s_u8LastKey = KeyTemp ; //保存键值,以便在释放按键状态返回键值
                        KeyTemp |= KEY_DOWN ;   //按键按下
                        s_u8KeyState = KEY_STATE_LONG ;
                    }
                    else
                    {
                        s_u8KeyState = KEY_STATE_INIT ;
                    }
                }
         break ;
         case KEY_STATE_LONG :
                {
                    if(KEY_NULL != (KeyTemp))
                    {
                        if(++s_u8KeyTimeCount > KEY_LONG_PERIOD)
                        {
                            s_u8KeyTimeCount = 0 ;
                            KeyTemp |= KEY_LONG ;   //长按键事件发生
                            s_u8KeyState = KEY_STATE_CONTINUE ;
                        }
                    }
                    else
                    {
                        s_u8KeyState = KEY_STATE_RELEASE ;
                    }
                }
         break ;
         case KEY_STATE_CONTINUE :
                {
                    if(KEY_NULL != (KeyTemp))
                    {
                        if(++s_u8KeyTimeCount > KEY_CONTINUE_PERIOD)
                        {
                            s_u8KeyTimeCount = 0 ;
                            KeyTemp |= KEY_CONTINUE ;
                        }
                    }
                    else
                    {
                        s_u8KeyState = KEY_STATE_RELEASE ;
                    }
                }
         break ;
         case KEY_STATE_RELEASE :
                {
                    s_u8LastKey |= KEY_UP ;
                    KeyTemp = s_u8LastKey ;
                    s_u8KeyState = KEY_STATE_INIT ;
                }
         break ;
         default : break ;
     }
     *pKeyValue = KeyTemp ; //返回键值   
}

uint8 KeyValue = KEY_NULL;
void main(void)
{     
     
     uint8 temp = 0 ;
     
     Timer0_Init();  
     KeyInit() ;
     EA = 1 ;
     while(1)
     {
         //Timer0MainLoop() ;
         //KeyMainLoop(&KeyValue) ;
         
     }
}

void Timer0() interrupt 1 //定时器中断
        {                    
                          //16位自动重装模式,无需重赋初值
     GetKey(&KeyValue);
         if(KeyValue == (KEY_VALUE_1|KEY_DOWN)) P0 = ~1 ;
         if(KeyValue == (KEY_VALUE_1 |KEY_LONG)) P0 = ~2 ;
         if(KeyValue == (KEY_VALUE_1 |KEY_CONTINUE)) { P0 ^= 0xf0;}
         if(KeyValue == (KEY_VALUE_1 |KEY_UP)) P0 = 0xa5 ;         
   
        }
       
void Timer0_Init()  //定时器初始化
   {
         AUXR &= 0x7F;        //定时器时钟12T模式,10mS
         TMOD &= 0xF0;        //设置定时器模式
         TH0 = 0xDC;        //设置定时初值
         TL0 = 0x00;        //设置定时初值
         //TF0 = 0;                //清除TF0标志
         TR0 = 1;                //定时器0开始计时
         ET0 =1;
         EA = 1;
  }
ID:66287 发表于 2018-7-23 16:23
实际上应该定时10mS,在定时中断中执行void GetKey(uint8 *pKeyValue)函数吧,
ID:207882 发表于 2018-6-20 19:49
如果执行程序的时间小于消抖的时间那不是还是进入了case KEY_STATE_PRESS ????不需要设置消抖时间?
ID:323951 发表于 2018-5-30 15:18
这个看起来不是很理解,可以发一下楼主自己改过以后的源码吗?
ID:304849 发表于 2018-5-16 13:43
汇编程序,怎么利用键值跳转到子程序呢?
ID:82098 发表于 2015-12-28 13:19
hboy 发表于 2015-12-10 11:30
为嘛我用就编译不通过

把KeyMainLoop(&KeyValue) ;换成GetKey(&KeyValue);即可。
ID:98238 发表于 2015-12-10 11:30
为嘛我用就编译不通过
ID:89632 发表于 2015-9-8 18:01
真的很有用啊!

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表