一乐电子

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

微信扫码登录

搜索
楼主: dianzichina

[其他综合] 按键中断老是按一次跳好几次,谁能给出一个防抖例程?

  [复制链接]
发表于 2012-12-8 08:41 | 显示全部楼层
按键放在主程序里面扫描就好
中断一般用来计时
回复

使用道具 举报

发表于 2012-12-13 16:08 | 显示全部楼层
我一般用延时

  1. //实体按键中断服务程序
  2. ISR(PCINT0_vect)
  3. {
  4.         uint keeppressms=1500; //消除抖动
  5.         mydelayms(100);
  6.        
  7.         //sprintf(msg,"ISR=%02x %02x %02x %2x\r\n",!KEY_POWER,!KEY_WIND,!KEY_TURN,!KEY_TIMER);
  8.         //debug(msg,strlen(msg));
  9.         if(!(state&MOD_LEARN)&&(!KEY_POWER||!KEY_WIND||!KEY_TURN||!KEY_TIMER))
  10.         {
  11.           //扫描
  12.           if(!KEY_POWER) //进入学习状态
  13.                 {
复制代码
回复

使用道具 举报

发表于 2012-12-16 20:46 | 显示全部楼层
本帖最后由 狗狗百里游 于 2012-12-16 20:51 编辑

防抖动不需要用中断代码的,因为放抖动只需要识别20ms左右,

if(button_setup_on)    { lcd_delay_ms(20); }   //按键消抖,如果按下不到20ms,就当是干扰

         if(button_setup_on)
            {
//识别出按键按下

               while(button_setup_on) { USB_R_100ms();}  //循环至按键松开,
            }



这样基本可以省掉在按键开关并联104电容。
回复

使用道具 举报

发表于 2012-12-16 20:48 | 显示全部楼层
USB_R_100ms延时函数里面我加有喂看门狗的代码的,不然程序跑飞了都不知道
回复

使用道具 举报

发表于 2013-3-30 09:59 | 显示全部楼层
防抖就是延时啊
回复

使用道具 举报

发表于 2013-4-9 11:10 | 显示全部楼层
额,可以用定时器做延时消抖吧
回复

使用道具 举报

发表于 2013-4-26 15:56 | 显示全部楼层
什么年代了,按键处理还要防抖?
回复

使用道具 举报

发表于 2013-4-26 16:07 | 显示全部楼层
附上很简单的一段按键处理代码:
void key_init(void)  //键盘初始化
{
  DDRD &=~0x0c;  //00001100;~11110011
  PORTD |=0x0c;
}
void KeyRead(void)  //键盘
{
  static uchar key_state=0;   
  uchar ReadData;
  
  ReadData = PIND;
  ReadData = ReadData<<4;
  ReadData = ReadData>>6;
  ReadData = ReadData<<2;
  ReadData = ReadData^0x0c;
  
  Trg = ReadData & (ReadData ^ Cont);      //得到按下触发值     
  Cont = ReadData;                         //得到所有未释放的键值
if(Cont>=4&&kt<0xfffe)                            //键按下计数
          kt++;
  else
    kt=0;       

  switch (key_state)  
  {  
    case 0:                         //无按键状态
      if(Cont==8) key_state=2;      //右键长按
          if(Cont==4) key_state=3;      //左键长按
          key=0;
      break;  
    case 2:                         //右键长按状态处理
      if(!Cont)
      {
        key=1;                     
        key_state=0;
      }  
      else
            if(kt>co) //继续按下,计时if(kt>co)
          {  
            key=3;
            key_state=4;
          }
    break;  
    case 3: //按下键时间的计时
      if(!Cont)  
      {
        key=5;
        key_state=0; //转换到按键初始态  
      }  
      else
          if(kt>co)
        {  
          key=7;
          key_state=4;
        }
      break;              
    case 4:
      if(!Cont)
            key_state=0;
          key=0;
      break;
  }
}
回复

使用道具 举报

发表于 2013-4-27 00:29 | 显示全部楼层
只会汇编的,给个思路,定时器里面20ms定时检测按键(如果主程序运行一次的时间足够按键消抖,按键程序也可以放在主程序循环中执行,这样可以省掉一个定时器)
举例:首先,程序开始时设一个状态位,初始值为0
进入20ms定时中断
a、检测到有键按下,状态位=1,退出中断;
b、检测按键没有按下,继续判断状态位,=1,表示按键是松开了,执行单按功能程序,复位按键各参数,退出中断;=0,按键们没有按下,退出中断;
在a中增加两个寄存器和一个状态位,还可以有连按,长按退出功能。
回复

使用道具 举报

本版积分规则

QQ|一淘宝店|手机版|商店|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-8-19 01:15 , Processed in 0.031834 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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