打印

问一个比较老的问题:多个按键在定时中断里面如何实现?

[复制链接]
3592|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
martial|  楼主 | 2008-3-19 16:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有21个按键,我听人说放在定时中断中去抖不耽误功夫,想确定一个定时基准T,然后分时扫描,如果T设大了,一次循环21*T就太长了,如果T设短了,中断会很频繁,中断里面别的事情都做不了,不知道我的想法对不对?

系统中有数据采集、LCD显示代码想放在中断中实现,所以T又不能太短。

相关帖子

沙发
mohanwei| | 2008-3-19 16:40 | 只看该作者

先搜一下本版。重复过多的问题尽量避免再讨论了……

使用特权

评论回复
板凳
martial|  楼主 | 2008-3-19 16:45 | 只看该作者

楼上的,搜了一下,没找到需要的答案才另发帖的

使用特权

评论回复
地板
谈的元| | 2008-3-19 18:31 | 只看该作者

思路,看这样好不?

 
  if (k1==1 and rk1<= 20)
  rk1 == rk1+1
  else 
  rk1 == 0
  if   rk1>= 20-2
  b_k1  ==  1
  else
  b_k1  ==  0    //用该标记做事

使用特权

评论回复
5
救火车| | 2008-3-19 18:37 | 只看该作者

电路图是什么样的?

没有图,光看程序。看不懂。

使用特权

评论回复
6
谈的元| | 2008-3-19 18:54 | 只看该作者

只是一个不用专门延时 读按钮的思路

要电路?

使用特权

评论回复
7
martial|  楼主 | 2008-3-20 08:37 | 只看该作者

救火车、谈的元,我用的是3*7的矩阵键盘

我只是在中断中实现延时去抖的想法没弄明白,假设现在就只有3个按键,独占3个端口,如何在定时中断中实现呢?

使用特权

评论回复
8
5880527| | 2008-3-20 09:48 | 只看该作者

键盘扫描花的时间很少很少的

不是书本上说的要调用个10毫秒的延时消抖,就象你这个,每一中断都扫描一下所有的键盘,不需要消抖,记下有按下的键状态就是,再来一次中断时再扫描一下所有的键盘,两次状态比较看有相同的不,如果有就可以认为键有效了,如果你对可靠性要求比较高,那就判三次四次啥的

使用特权

评论回复
9
xwj| | 2008-3-20 10:00 | 只看该作者

要学会把延时间隔的CPU资源空出来,

这是对入门的程序员的基本要求,
否则只能说明你还没有入门哦


LZ多去想想吧...

使用特权

评论回复
10
tang.sc| | 2008-3-20 10:08 | 只看该作者

不要只想到用软件的方法去抖

在按键的电路上加一个低通滤波就可以,在软件实现上设计一个小的状态机程序,二则结合起来很容易处理键盘的。

使用特权

评论回复
11
ayb_ice| | 2008-3-20 10:26 | 只看该作者

一次中断读出所有状态不就行了

使用特权

评论回复
12
martial|  楼主 | 2008-3-20 11:30 | 只看该作者

xwj及楼上各位老大

xwj:我把按键检测用定时中断来检测就是想把延时间隔的cpu资源空出来,键少的情况下分时检测容易实现,键多了后就感觉会出现我所说的矛盾,不知是不是我的想法方向不对,希望您能指点!

另外楼上几位老大说的一次读出所有状态,开始我也想了,但是担心键多的情况下误操作多个键同时按下时响应会乱,因此我就想分时检测,即使同时按下也会有个先后顺序,所以就想着分时检测的方法了,现在感觉键多的情况下有问题,所以不知道我的思路是不是有问题??

使用特权

评论回复
13
gyt| | 2008-3-20 14:53 | 只看该作者

很多参考资料

仔细看看就行

使用特权

评论回复
14
ayb_ice| | 2008-3-20 17:17 | 只看该作者

根本没有必须在中断中扫键盘

中断尽量做必须在中断中做的事。。。

使用特权

评论回复
15
谈的元| | 2008-3-20 18:19 | 只看该作者

这样,中断后,判断,按键为1,某积存器记数加一,

这样,中断后,判断,按键为1,如果某积存器小于某值,积存器记数加一;


按键为0,某积存器清0。当积存器大于某数,就认为按下了。

这下明白了吧,不明白就到群里交流。群自己找哈

使用特权

评论回复
16
computer00| | 2008-3-20 18:33 | 只看该作者

看看我的:

/******************************************************************
   本程序只供学习使用,未经作者许可,不得用于其它任何用途

        欢迎访问我的USB专区:http://group.**/93/
        欢迎访问我的blog:   http://www.**/blog/computer00
                             http://computer00.21ic.org

KEY.C  file

作者:Computer-lov
建立日期: 2007.03.20
修改日期: 2007.11.18
版本:V1.2
版权所有,盗版必究。
Copyright(C) Computer-lov 2007-2017
All rights reserved            
*******************************************************************/




#include "Key.h"
#include "my_type.h"
#include "config.h"

volatile uint8 idata KeyCurrent,KeyOld,KeyNoChangedTime;
volatile uint8 idata KeyPress;
volatile uint8 idata KeyDown,KeyUp,KeyLast;

volatile uint8 KeyCanChange;

/********************************************************************
函数功能:定时器0初始化,用来做键盘扫描,定时时间大约为5ms。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void InitTimer0(void)
{
 TMOD&=0xF0;
 TMOD|=0x01;
 TH0=0xDC;
 ET0=1;
 TR0=1;
}
/*******************************************************************/


/********************************************************************
函数功能:键盘初始化
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void InitKeyboard(void)
{
 KeyIO=0xFF;      //键盘对应的口设置为输入状态
 KeyPress=0;          //无按键按下
 KeyNoChangedTime=0;
 KeyOld=0;
 KeyCurrent=0;
 KeyLast=0;
 KeyDown=0;
 KeyUp=0;
 InitTimer0();          //初始化定时器
 KeyCanChange=1;      //允许键值改变
}
/*******************************************************************/

/********************************************************************
函数功能:定时器0中断处理。
入口参数:22.1184M晶体约5ms中断一次。
返    回:无。
备    注:无。
********************************************************************/
void Timer0Isr(void) interrupt 1

 TH0=(65536-Fclk/1000/12*5+15)/256;     //定时器0重装
 TL0=(65536-Fclk/1000/12*5+15)%256;

 if(!KeyCanChange)return;     //如果正在处理按键,则不再扫描键盘 

 //开始键盘扫描
 //保存按键状态到当前按键情况
 //KeyCurrent总共有8个bit
 //当某个开关按下时,对应的bit为1
      
 KeyCurrent=~KeyIO;    

 if(KeyCurrent!=KeyOld)  //说明按键情况发生了改变
  {
   KeyNoChangedTime=0;       //键盘按下时间为0
   KeyOld=KeyCurrent;        //保存当前按键情况
   return;
  }
 else
  {
   KeyNoChangedTime++;         //按下时间累计
   if(KeyNoChangedTime>=1)     //如果按下时间足够
    {
     KeyNoChangedTime=1;
     KeyPress=KeyOld;      //保存按键
     KeyDown|=(~KeyLast)&(KeyPress); //求出新按下的键
     KeyUp|=KeyLast&(~KeyPress);     //求出新释放的键
     KeyLast=KeyPress;                 //保存当前按键情况
    }
  }
}
/*******************************************************************/

使用特权

评论回复
17
martial|  楼主 | 2008-3-21 08:17 | 只看该作者

谢谢!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

55

主题

296

帖子

0

粉丝