给新型的按键扫描程序,仅三行程序添加去抖动

2019-12-10 18:34发布

原文链接https://www.amobbs.com/thread-4308630-1-1.html
#define Number 20
unsigned char Jitter = Number;      //连续检测20次,每次间隔1ms
unsigned int Value;     //读取的端口,每次和次数据做或操作,原始值为0
unsigned int SaveData;//保存读取的去抖动后的端口数据
unsigned int Trg;
unsigned int Cont;
void KeyRead(unsigned char Time)
{
    if(Time != 0)       //不为0时,1ms时间间隔已到
    {
        if(Jitter == 0)
        {
            SaveData = Value;   //去抖动次数到,保存读取的数据
            Value = 0;          //和端口做or操作
            Jitter =Number;
        }
        else
        {
            --Jitter;
            Value |= GPIO_ReadInputData(GPIOC);//每次去抖动时都是0为有按下,有一次为1,
            //表示已松开,置读取数据以后都为1,到去抖动次数到,再读取是否为0
        }
    }//以上为添加部分
    unsigned int ReadData = SaveData^0xffff;   // 1
    Trg = ReadData & (ReadData ^ Cont);      // 2
    Cont = ReadData;                                // 3
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
retention
1楼-- · 2019-12-10 22:40
我发一个应用也很久的检测独立按键的程序,是单击短按的,欢迎探讨

只耗费一个位变量和一个unsigned char的全局变量,当然也要定时器 每20毫秒产生一个中断

  1. sbit FlagKeyStatus=0;
  2. unsigned char CntSingleKey=0;   
  3. void KeyProcess(void)  //每20ms执行 一次
  4. {            
  5.           if(FlagKeyStatus==0)    //  没有按键按下
  6.            {
  7.                    if(!KeyInput)   //KeyInput为按键输入的IO口
  8.                     {
  9.                             CntSingleKey = 1;
  10.                             FlagKeyStatus = 1;                               
  11.                      }
  12.            }
  13.           else   //有按键按下的处理
  14.            {
  15.                    if(!KeyInput)  //一直被按着
  16.                     {
  17.                                 if(CntSingleKey < 250)   //最长时间:5S
  18.                                  {
  19.                                          CntSingleKey++;
  20.                                  }
  21.                         }
  22.                    else
  23.                     {
  24.                                 FlagKeyStatus = 0;
  25.                                if((CntSingleKey>=2)&&(CntSingleKey<25))     //介于  40ms至 500 之间,就会认为是 单击,可能会有正负20ms的偏差
  26.                                 {
  27.                                     FlagSingleKey = 1;  //检测到一次合法的按下事件,通过FlagSingledKey返回
  28.                                 }
  29.                         }
  30.            }
  31. }
复制代码

这段代码是运行在那个超小容量的MCU上面,RAM只有64byte,因此对RAM的 使用必是精确的到比特位的程度 ,当然我想如果像是ARM这类的大容量 的MCU,随便写都没问题。
特点:占用RAM比较小,只需要一个位变量和一个unsigned char的 变量。当然如果 MCU不支持 位变量的 ,就要两个unsigned char的变量了
          非阻塞的执行过程,支持防抖和按键松手检测。
genhao2
2楼-- · 2019-12-11 04:32
矩阵键盘适用么?
cnxh
3楼-- · 2019-12-11 10:21
本帖最后由 cnxh 于 2019-5-19 18:25 编辑

unsigned int SaveData = 0xffff;//这句初始化一下,不初始化上电相当于按钮已按下
这个一位数据对应一个端口
icoyool
4楼-- · 2019-12-11 14:06
if(Time != 0)这一行就暴露了水平啊。就这样就敢拿出来分享,脸红不?
cnxh
5楼-- · 2019-12-11 14:06
 精彩回答 2  元偷偷看……
cnxh
6楼-- · 2019-12-11 17:21
genhao2 发表于 2019-5-19 17:28
矩阵键盘适用么?

这句里的Value |= GPIO_ReadInputData(GPIOC);从直接端口读出,GPIO_ReadInputData(GPIOC);换成从你的矩阵读出不就可以了

一周热门 更多>