51单片机时钟调时间按键不灵敏

各位友友们,下面这个代码怎么让它按键检测更灵敏一点,我做的是一个时钟它现在的情况是在调时间状态下,有时候按一下就可以实现加减,有时候需要按两次,非常不灵敏,有没有什么办法?


#include "regx52.h"
#include "T0.h"
#include "LCD1602.h"
#include "key.h"
#include "Delay.h"

unsigned int count;
char s, min = 59, h = 23;
unsigned char keynum;
char n=1;
unsigned char change;
void main()
{
    T0_init();
    LCD_Init();
    LCD_ShowString(1, 1, "Clock");
    LCD_ShowNum(2, 1, h, 2);
    LCD_ShowChar(2, 3, ':');
    LCD_ShowNum(2, 4, min, 2);
    LCD_ShowChar(2, 6, ':');
    LCD_ShowNum(2, 7, s, 2);
    while (1)
    {
        keynum = key(); 
        if (keynum == 1) { n = -n; if (n == -1)TR0 = 0; else if (n == 1)TR0 = 1; }
        if (keynum == 4) {change = (change + 1) % 3;}
        if (n==-1)
        {
            if(change==1)
            {
                LCD_ShowNum(2, 4, min, 2);
                Delay(20);
                LCD_ShowString(2, 4, "  ");
                Delay(20);
                if (keynum == 2) { min++; if (min >= 60)min = 0; }
                else if (keynum == 3) { min--; if (min < 0)min = 59; }
            }
            else if (change == 0)
            {
                LCD_ShowNum(2, 7, s, 2);
                Delay(20);
                LCD_ShowString(2, 7, "  ");
                Delay(20);
                if (keynum == 2) { s++; if (s >= 60)s = 0; }
                else if (keynum == 3) { s--; if (s < 0)s = 59; }
            }
            else if (change == 2)
            {
                LCD_ShowNum(2, 1, h, 2);
                Delay(20);
                LCD_ShowString(2, 1, "  ");
                Delay(20);
                if (keynum == 2) { h++; if (h >= 24)h = 0; }
                else if (keynum == 3) { h--; if (h < 0)h = 23; }
            }
        }
        else
        {
            LCD_ShowNum(2, 1, h, 2);
            LCD_ShowNum(2, 4, min, 2);
            LCD_ShowNum(2, 7, s, 2);
        }
    }
}

void T0_stop() interrupt 1
{
    TL0 = 0x18;
    TH0 = 0xFC; TF0 = 0;
    count++;
    if (count >= 1000)
    {
        s++; count = 0;
        if (s >= 60)
        {
            min++; s = 0;
            if (min >= 60)
            {
                h++; min = 0;
                if (h >= 24)
                {
                    h = 0;
                }
            }
        }
    }
}

【以下回答由 GPT 生成】

问题分析和解决方案:

问题分析: 在给定的代码中,按键检测不够灵敏,有时需要按两次才能成功操作。这可能是由于按键的抖动或延迟导致的。为了提高按键检测的灵敏度,可以采取以下几个步骤:

  1. 使用外部中断代替轮询:使用外部中断可以减少轮询的延迟,并立即响应按键信号。
  2. 添加按键消抖处理:通过软件实现按键消抖,可以过滤掉按键信号中的抖动,并确保只检测到有效的按键操作。
  3. 优化按键扫描频率:提高按键扫描的频率可以增加检测到按下和松开事件的准确性。

解决方案:

  1. 替换按键检测方法:将按键检测从轮询方式改为使用外部中断。这将显著提高按键的检测时间和响应速度。以下是替换后的代码示例:
#include "regx52.h"
#include "T0.h"
#include "LCD1602.h"
#include "key.h"
#include "Delay.h"

unsigned int count;
char s, min = 59, h = 23;
unsigned char keynum;
char n=1;
unsigned char change;

// 外部中断0服务例程
void ExternalInterrupt0() interrupt 0
{
    keynum = key(); // 在中断中获取按键信号
}

void main()
{
    T0_init();
    LCD_Init();
    LCD_ShowString(1, 1, "Clock");
    LCD_ShowNum(2, 1, h, 2);
    LCD_ShowChar(2, 3, ':');
    LCD_ShowNum(2, 4, min, 2);
    LCD_ShowChar(2, 6, ':');
    LCD_ShowNum(2, 7, s, 2);

    EX0 = 1; // 开启外部中断0
    EA = 1;  // 全局中断使能

    while (1)
    {
        if (keynum == 1)
        {
            n = -n;
            if (n == -1)
                TR0 = 0;
            else if (n == 1)
                TR0 = 1;
        }

        if (keynum == 4)
        {
            change = (change + 1) % 3;
        }

        if (n == -1)
        {
            if(change==1)
            {
                LCD_ShowNum(2, 4, min, 2);
                Delay(20);
                LCD_ShowString(2, 4, "  ");
                Delay(20);

                if (keynum == 2)
                {
                    min++;
                    if (min >= 60)
                        min = 0;
                }
                else if (keynum == 3)
                {
                    min--;
                    if (min < 0)
                        min = 59;
                }
            }
        }
    }
}
  1. 添加按键消抖处理:在外部中断服务例程中添加按键消抖处理。使用一个适当的延时函数来过滤按键信号中的抖动,并确保只检测到有效的按键操作。以下是代码示例:
// 外部中断0服务例程
void ExternalInterrupt0() interrupt 0
{
    // 按键消抖
    Delay(20); // 根据实际情况调整延时时间
    keynum = key(); // 在中断中获取按键信号
}
  1. 优化按键扫描频率:提高按键扫描的频率以增加检测到按下和松开事件的准确性。可以通过减小延时函数中的延时时间来实现。以下是代码示例:
// 外部中断0服务例程
void ExternalInterrupt0() interrupt 0
{
    // 按键消抖
    Delay(10); // 减小延时时间以提高扫描频率
    keynum = key(); // 在中断中获取按键信号
}

修改后的代码中,通过使用外部中断检测按键信号,并加入按键消抖处理和优化扫描频率,可以提高按键检测的灵敏度和响应速度。根据实际情况,可能需要根据具体硬件和需求进行调整。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^