一个简单的按键去抖延时程序

发布者:创新之星最新更新时间:2015-06-12 来源: 51hei关键字:按键去抖  延时程序 手机看文章 扫描二维码
随时随地手机看文章
按键去抖,一般采用普通延时,如

if((GPIOC->IDR & 0x01)== 0)
{
    delay_ms(20);
    if(GPIOC->IDR & 0x01)== 0 
    {
            //进行按键处理函数
    }
}

这个程序,需要有一个普通的延时程序,来检测去抖动,这个延时一般采用for循环和while循环。这样的话,就有一个问题,在延时的这20ms中,cpu一直在判断时间有没有到。如果不是中断,是不会打断cpu的程序的。这样的话,去抖延时,就会浪费cpu的效率。
假如,按键扫描的后面跟一个协议处理的函数。
即:

while(1)

        scan_key();    //按键扫描
        exe();              //协议解析

这个时候,若接收中断,在按键扫描时已经处理完成,正好按下按键,这个时候就必须要有20ms的间隔,在判断完按键后,才可以进入协议解析函数。也就是说,如果没有扫描函数,协议会立即执行解析并返回响应数据。而添加按键扫描后,协议有可能会在20ms后,进行解析并返回数据,这样的话,就会使产品的实时性无法保证。

所以我想了另一个方法,采用标致位,来实现延时,当然这个方法,肯定不是我第一个想出来的。如有雷同,可采用翻钢镚方法进行选择。
就是采用if语句来实现延时,只不过写程序时比较麻烦,但稳定性在stm8上测试了一下,感觉还可以。

代码如下
首先申请几个全局变量
unsigned int time_ms,time_us,time_ns,time_flag;
//以上这几个是定时标志和定时计数变量
unsigned key_old, key_new;
//这两个是按键键值

/*******************************************************************************
 函数名:delay_ms()
 函数功能:延时
 参数:ms 毫秒
 返回:无
 备注:此延时函数采用if实现,使用时,必须先申请flag变量然后调用延时函数,最后在
  执行中加入flag判断
例:u16 time_flag,time_ms,time_us,time_ns;
delay_ms(u16 ms);
if(time_flag>0){time_flag=0;......内容}
*******************************************************************************/
void key_delay(unsigned int ms)
{
if(time_ms {
 if(time_us<10)                  //在应用时,不同的单片机,不同的频率,需要进行调整
{
if(time_ns<8)            //在应用时不同的单片机,不同的频率,需要进行调整
{
time_ns++;
}
else
{
 time_us++;
 time_ns=0;
}
}
else
{
 time_ms++;
 time_us=0;
}
}
else
{
 time_flag=1;
 time_ms=0;
}
}


以上代码,有一个time_flag,变量,这个变量就是定时标致变量。一旦这个标致置一,则说明定时器到时间
使用时可以

///////////////////////////////////////////////////////////
//函数名:scan()    
//功能:按键扫描     
//参数:无      
//返回值:无         
//备注:         
///////////////////////////////////////////////////////////
void scan()
{
    u8 key_new;
    key_new = GPIOC->IDR;
    if(key_old != key_new)
    {
        key_delay(150);
        if(time_flag == 1)
        {
            time_flag = 0;
            if(key_old != key_new)
            {
               switch()
               {
                   case 1:  k1_exe();  break;
                   case 2:  k2_exe();  break;
                   case 3:  k3_exe();  break;
                   case 4:  k4_exe();  break;
                   default:        break;
                }
                key_old = key_new; 
            }
            else
            }
                time_ms=0;    
            } 
        }
    }
}

以上就是代码
在大循环中,直接调用即可,和普通的按键函数一样,只不过,这个的实时性,应该相对较高一些。
while(1)

         scan_key();    //按键扫描
         exe();              //协议解析  

让我们来分析一下,为啥这个函数相对较好一些。
首先,我们来看
scan_key();  
首先,扫描IO端口,存放如新按键变量
key_new = GPIOC->IDR; 
然后将新按键与老按键号进行对比,如果新的按键号与老按键号不同,说明有按钮按下。
if(key_old != key_new) 
当有按钮按下的时候进入,延时函数,
key_delay(150); 
这时,进入多个if判断,进行time_ns++;这个函数,最主要的功能就是判断,当前的时间time_ms,与参数时间,是否一致,若不一致,则退出函数。这时time_flag不为1,当前的时间time_ms,与参数时间一致 ,这时time_flag为1。
if(time_flag == 1) 
这个判断就是判断到时标致,如果到时,则说明去抖时间完成,则在判断一次if(key_old != key_new),如果为否,则说明按键确实按下,否则则为没有按下。有按键按下时,则会执行按键处理函数。
若没有按键按下,则清楚计数器。程序继续执行。
也就是说,不管是否在延时状态,程序,都会向下执行,而不会卡在某一个函数或循环内不动。这样的话,程序就会向下继续执行。
在程序中,若既有按键,又有一些对待实时性较高,但又不乐意放在中断里的程序。可以采用这种方法来实现按键延时,可以相对的提高程序的运行效率。目前这个程序,不支持长按,但可以实现简单的组合按键。

关键字:按键去抖  延时程序 引用地址:一个简单的按键去抖延时程序

上一篇:s8050电流驱动能力测试实验
下一篇:关于数组做函数参数

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

stm32 通用定时器 精确延时程序
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 1; //自动装载 TIM_TimeBaseStructure.TIM_Prescaler = 7200; //72M分频率到10KHz TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down; //向下计数 TIM_TimeBaseInit(TIM2, &TI
[单片机]
新手常用单片机延时程序
单片机延时程序(适合初学者) 下面几个是单片机的延时程序(包括asm和C程序,都是我在学单片机的过程中用到的),在单片机延时程序中应考虑所使用的晶振的频率,在51系列的单片机中我们常用的是11.0592MHz和12.0000MHz的晶振,而在AVR单片机上常用的有8.000MHz和4.000MH的晶振所以在网上查找程序时如果涉及到精确延时则应该注意晶振的频率是多大。 软件延时:(asm) 晶振12MHZ,延时1秒 程序如下: DELAY:MOV 72H,#100 LOOP3:MOV 71H,#100 LOOP1:MOV 70H,#47 LOOP0JNZ 70H,LOOP0 NOP DJNZ 71H,LOOP1
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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