登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[寒假笔记] 按键消抖相关实例

[复制链接]
发表于 2019-1-21 20:19:34 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 按键消抖
学习安排: 下午按照金沙滩教程的消抖相关的讲解,学习了按键消抖
开始时间: 2019-01-21
结束时间: 2019-01-21
本帖最后由 林雨 于 2019-1-21 20:24 编辑

首先说一下我对金沙滩所讲的按键消抖原理的理解:首先要用中断和定时器共同协作来达到一个两毫秒的计时,那么七八次的话就是
16毫秒,这个16毫秒是大于抖动的那个时间的(如果小于十毫秒则可能会产生
误判)。如果连续对按键状态检测8次,检测到的所有值都是1,说明按键在16
毫秒内处于相对稳定的状态,并且是弹起的;如果连续检测8次,检测到的所
有值都是零,说明按键16毫秒内处于相对稳定的状态,并且是按下的。每检测
八次都输出一个标志值,这个标志值与之前设置的备份按键状态值作比较,如
果不相等,那么可以判定按键有动作。由于按键只有两种状态,我们将按键状
态备份值以及中断函数输出的标志值设置为bit类型的变量,(这里说中断函数
“输出”标志值可能有些不合适,但是就相对于整个中断服务函数来说,它的作用
就是给主函数提供这个状态标志值)。ps:按键状态备份值备份的是按键最后一
次动作形成的状态,1--弹起,2--按下;中断服务函数输出标志值代表的是当
前检测到的按键的状态。下面用一个具体的例子来说明。可以实现的功能是
每按一下开发板上的K4按键,数码管的最后一位会从0加到9,而后进行归零,
再进行下一轮加操作。
[mw_shl_code=c,true]#include <STC12C5A60S2.H>

sbit Key  = P2^3;                                               //我们使用开发板上的k4按键

sbit KeyOut1 = P2^4;
sbit KeyOut2 = P2^5;
sbit KeyOut3 = P2^6;
sbit KeyOut4 = P2^7;

sbit A0 = P2^0;
sbit A1 = P2^1;
sbit A2 = P2^2;                                    
sbit ENLED = P1^1;

unsigned char code LedChar[]={
        0xc0,  0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
        0x80,  0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e
};                                                                  //数码管的真值表

bit Interrupt_Back = 1;                                    //  定义一个位类型的变量,这个变量是中断服务函数输出的标志值,这个变量应当设为全局变量

void main ()
{
        
        
        bit Backup = 1;                                              //定义一个位类型的变量,按键状态备份值
        
        unsigned char cnt = 0;                                   //cnt代表按键次数
        
        A0 = 1;
        A1 = 0;
        A2 = 1;                                                       //选择数码管的最后一位进行显示
        
        
        KeyOut1 = 0;
        KeyOut2 = 0;
        KeyOut3 = 0;
        KeyOut4 = 0;                                              //将所有的按键输出都置0
        ENLED = 0;                                                
        
        EA = 1;                                                      //打开总中断
        ET0 = 1;                                                    //打开T0中断
        
        TMOD = 0x01;                                            //设置定时器的工作模式
        TH0 = 0xea;
        TL0 = 0x67;                                               //为定时器的高八位和第八位都设置初值
        TR0 = 1;
        
        
        while (1)
        {
     if (Backup != Interrupt_Back)                 //如果检测到按键状态有变化,则进行下面这波操作
   {
        if (Backup == 0)
             {
                  cnt++;                                   //按键次数自加
                  if (cnt >= 10)
                       {
                            cnt = 0;                        //如果按键次数大于十,则进行归零操作
                       }
            }
            Backup = Interrupt_Back;              //把按键状态备份值更新为中断服务函数传回来的按键状态值
   }
           P0 = LedChar[cnt];                        //数码管显示操作
               
               
        }
               
}        

void Inrrupt_1 () interrupt 1                      //T0中断服务函数,每当达到条件,便会无条件执行这个函数
{
       static unsigned char keybuff = 0xff;    //定义一个静态的字符型变量keybuff,一旦为该变量分配了存储空间,那么这个存储空间就属于该变量,里边
                                                             的值会保持上一次装载的值,按键状态值与该变量进行按位异或
                                                             操作,进行八次操作之后,根据keybuff的值来决定输出Interrupt_Back的值
        
       TH0 = 0xea;
       TL0 = 0x67;                                    //每次执行中断函数时都重新装载初始值,并且下一轮计时自动开始
        
       keybuff = (keybuff<<1)|Key;           //我们设置的这个keybuff变量与按键状态值进行异或操作
        
      if (keybuff == 0x00)                         //接下来对keybuff进行判断,从而决定生成Interrupt_Back的值
           {Interrupt_Back = 0;}
        
      else if (keybuff == 0xff)
      {Interrupt_Back = 1;}
        
      else {}                                             //别的状态,不进行任何操作
        
        
         
        
}[/mw_shl_code]欢迎批评指正。

好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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