pppphhhhyyyy 2023-09-09 20:42 采纳率: 80.6%
浏览 19

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;
                }
            }
        }
    }
}
  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-09-09 22:12
    关注

    【以下回答由 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(); // 在中断中获取按键信号
    }
    

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



    【相关推荐】



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

报告相同问题?

问题事件

  • 创建了问题 9月9日