daiya1981 发表于 2020-8-9 12:44:51

一个多击按键识别程序出现了问题

网上获得一个多击按键程序,理论上可以响应任意次多击,烧进单片机后在实验板上运行,一两次多击可以成功识别,可是8次多击就不能识别了,想了好久也想不出问题出在哪里?请各位高人指导迷津!

#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit LED0 = P1^0;
sbit LED1 = P1^1;
sbit LED2 = P1^2;

sbit KEY1 = P3^2;

uint count = 0,ClickFlag = 0,ClickFlagCount = 0,LongClickFlag = 0;
uchar i = 0,Click = 0;
uchar keynum = 0;

uchar ucLedMode;

typedef struct{
      uchar bBkpGpio;    //原例程中为:bit bBkpGpio
      uchar ucPushNum;
      uint usPopCnt;
      uchar ucScaleCnt;
      
      uchar ucNum;
      
}Key_Typedef;

Key_Typedef stKey;

bit keyscan(void)
{
      bit bThisGpio = 0;
      bit bRtn = 0;

      if (++stKey.ucScaleCnt >= 10)
      {
                stKey.ucScaleCnt = 0;

                bThisGpio = KEY1;
                if (bThisGpio)
                {
                        if (++stKey.usPopCnt >= 50)
                        {
                              stKey.ucNum = stKey.ucPushNum;
                              stKey.ucPushNum = 0;
                              bRtn= 1;
                        }
                }

                if (bThisGpio != stKey.bBkpGpio)
                {
                        if (!bThisGpio)
                        {
                              stKey.ucPushNum++;
                              stKey.usPopCnt = 0;
                        }
                        stKey.bBkpGpio = bThisGpio;
                }
      }

      return bRtn;
}

void main()
{
    EA = 1;       //使能总中断
    TMOD = 0x01;//设置T0为模式1
    TH0= 0xFC;//为T0赋初值0xFC67,定时1ms
    TL0= 0x67;
    ET0= 1;   //使能T0中断
    TR0= 1;   //启动T0

    while (1)
    {
      if(ucLedMode==1)
            LED0 = ~LED0;
      if(ucLedMode==2)
            LED1 = ~LED1;
      if(ucLedMode==8)
            LED2 = ~LED2;
    }   
}

/* 定时器0中断服务函数 */
void InterruptTimer0() interrupt 1
{
    TH0 = 0xFC;//重新加载初值
    TL0 = 0x67;
      if (keyscan())
      {
                ucLedMode = stKey.ucNum;
      }
}

Himem 发表于 2020-8-9 18:58:45

本帖最后由 Himem 于 2020-8-9 19:05 编辑

思路没理清
不过51上的话我大概会这样写

#define CLICK_INTERVAL_MAX 100
void every_10ms() {
    if (!KEY1) {
      while (!KEY1); //until keyup
      ucClickCount++;
      ucTimeOut = CLICK_INTERVAL_MAX;
    }
    if (ucTimeOut) {
      if (--ucTimeOut == 0) {
            ucClickCount = 0;
      }
    }
}

daiya1981 发表于 2020-8-16 11:33:32

修改了一下代码,这下应该可以看懂了,请各位看看问题出在哪里?为什么按8次不响应?

#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit LED0 = P1^0;
sbit LED1 = P1^1;
sbit LED2 = P1^2;

sbit KEY1 = P3^2;

uchar i = 0;

bit bThisGpio = 0;
bit bBkpGpio = 1;

uchar ucPushNum;
uint usPopCnt;
uchar ucScaleCnt;
      
uchar ucNum;
uint count = 0;

void Delay10ms()                //@11.0592MHz
{
        unsigned char i, j;

        i = 18;
        j = 235;
        do
        {
                while (--j);
        } while (--i);
}

uchar keyscan()
{
        bThisGpio = KEY1;

        if (bThisGpio)
        {
                if (++usPopCnt >= 50)
                {
                        ucNum = ucPushNum;
                        ucPushNum = 0;
                }
    }
        if (bThisGpio != bBkpGpio)
        {
                Delay10ms();
                if(bThisGpio == KEY1)
                {
                        ucPushNum++;
                        usPopCnt = 0;
                }
                bBkpGpio = bThisGpio;
        }
        return ucNum;       
}

void main()
{

    while (1)
    {
                i = keyscan();
          if(i==1)
            LED0 = ~LED0;
      if(i==2)
            LED1 = ~LED1;
      if(i==8)
            LED2 = ~LED2;       
        }       
}
页: [1]
查看完整版本: 一个多击按键识别程序出现了问题