DYyanfa 2024-04-23 15:32 采纳率: 31.3%
浏览 2

按键扫描函数,按键关机无效

在main函数while循环中调用 KeyDriver()函数,目前只能开机,不能长按按键关机


#define  _KEY_C

#include "Key.h"
#include "config.h"
#include "Uart.h"

bit keysta = 1;
sbit PWR_key_det = P3^2;
sbit PWR_ON_SYS = P1^0;
sbit PWR_HOLD = P1^1;  
bit istiming = 0;
unsigned long keydowntime = 0; //记录按键按下时间

void  KeyDriver()
{        
    if(keysta == 1)
    {    
        if(keydowntime >=1000 && PWR_ON_SYS ==0)
        {     
            _nop_();
            _nop_();
            PWR_ON_SYS = 1;  //按下按键1.2秒,PWR_ON_SYS拉高
            istiming = 1;    
            keysta = 0;
        }
        else if(keydowntime >=1000 && PWR_ON_SYS == 1)
        {
            _nop_();
            _nop_();    
            PWR_HOLD = 0;
        }
        else
        {}
    }    
}

void KeyScan()  //按键扫描函数
{
    static unsigned char keybuf = 0xFF;
    keybuf = (keybuf <<1) |PWR_key_det;
    if(keybuf == 0x00)
    {
        keydowntime ++;//按键按下每次进入中断就加2
    }
    else if(keybuf == 0xFF)
    {
        keydowntime = 0;
        keysta = 1;
    }
    else
    {}
}

void ConfigTimer0()
{
    AUXR &= 0x7F;   //2ms定时
    TMOD &= 0xF0;
    TH0 = 0xF8;     
    TL0 = 0xCD;
    ET0 = 1;        //使能T0中断
    TR0 = 1;        //启动T0
}

void TM0_Isr() interrupt 1
{
    KeyScan();
    if(istiming)
    {
        keydowntime = 0;
    }
    TH0 = 0xF8;
    TL0 = 0xCD;
    TF0 = 0;    
}
  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-23 15:32
    关注

    引自免费微信小程序:皆我百晓生

    根据您提供的代码,看起来是一个基于51单片机的简单按键驱动程序,用于实现开机、关机功能。从描述来看,按键开机功能正常工作,但长按按键关机的功能似乎有问题。首先,我们分析一下现有代码的问题,并提出相应的修改建议。

    问题:

    1. KeyDriver() 函数中的条件判断逻辑不正确。
    2. 关键变量 keysta 的状态没有及时更新,导致可能无法正确检测到长按关机的情况。

    解决办法:

    1. KeyDriver() 函数中,我们需要确保当 PWR_ON_SYS 为 1(即系统已开机)时,才检查是否长按了关机键进行关机操作。
    2. 确保在 TM0_Isr() 中更新 keysta 的状态,以便在下次 KeyDriver() 被调用时可以正确处理。

    下面是修改后的代码:

    // ...其他包含文件和定义保持不变...
    
    void KeyDriver()
    {
        if(keysta == 1)
        {
            if(PWR_ON_SYS == 1)
            {
                if(keydowntime >= 1000)
                {
                    _nop_();
                    _nop_();
                    PWR_HOLD = 0; // 按下按键1.2秒后,关闭电源
                    keysta = 0;
                }
            }
        }
    }
    
    // ...其他函数保持不变...
    
    void TM0_Isr() interrupt 1
    {
        KeyScan();
    
        if(keydowntime >= 1000 && PWR_ON_SYS == 1)
        {
            keysta = 0; // 当按键持续按住超过1.2秒,设置keysta为0,表示正在长按
        }
        else if(keydowntime == 0)
        {
            keysta = 1; // 按键松开或未达到长按时间,设置keysta为1,表示未长按
        }
    
        // ...其他代码保持不变...
    }
    

    这个改动应该解决了长按关机的问题。现在,当 PWR_ON_SYS 为 1 且长按时,PWR_HOLD 将被置为 0 来关闭电源。同时,在 TM0_Isr() 中,我们根据 keydowntimePWR_ON_SYS 的值动态地更新 keysta,这样 KeyDriver() 就能在下一次执行时正确判断当前的状态。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月23日

悬赏问题

  • ¥15 iE 浏览器不能访问 oracle secure global server, google 浏览器可以
  • ¥50 Namuru2007_Baseband_Verilog代码疑点
  • ¥15 复杂公式求最值问题,含有多个符号常量
  • ¥15 Qt移植后在开发板上无法运行
  • ¥15 关于STID337-32D15YB开发板LINUX调试
  • ¥15 有没有熟悉自动化点胶设备,有个加密狗,想复制一份软件到另个设备
  • ¥15 mysql 部分截取字符串
  • ¥20 只有一个C盘,磁盘管理分区
  • ¥15 PVE8.2版本ceph的监控项状态stopped不能销毁
  • ¥15 如何加快视频观看速度?