DYyanfa 2024-06-24 15:44 采纳率: 31.3%
浏览 1

增加选择分支,无法关机,请问什么原因

不清楚为什么加了2秒时间到,发送串口指令这段代码就无法强制关机,屏蔽这段代码就能够正常关机

//把这段代码屏蔽就能够正常关机
        else if(keydowntime >=1000 && PWR_ON_SYS && !comsend) //2秒钟发送指令到ARM控制开关机重启等D8 00 05 FF
        {
            _nop_();
            _nop_();    
            UartSend(0xD8);
            UartSend(0x00);
            UartSend(0x05);
            UartSend(0xFF);
            comsend = 1;
        }

//完整代码
#define  _KEY_C

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

bit keysta = 1;
bit istiming = 0; 
sbit PWR_key_det = P3^2;
sbit PWR_ON_SYS = P1^0; 
sbit PWR_HOLD = P1^1;  

unsigned long keydowntime = 0; //记录按键按下时间
bit comsend = 0;//控制发送次数

void  KeyDriver()
{        
    if(keysta == 1)
    {    
        if(keydowntime >= 300 && !PWR_ON_SYS )//0.6秒开机
        {     
            _nop_();
            _nop_();
            PWR_ON_SYS = 1;  
            istiming = 1;    
            keysta = 0;
        }
        
        else if(keydowntime >=1000 && PWR_ON_SYS && !comsend) //2秒钟发送指令到ARM控制开关机重启等D8 00 05 FF
        {
            _nop_();
            _nop_();    
            UartSend(0xD8);
            UartSend(0x00);
            UartSend(0x05);
            UartSend(0xFF);
            comsend = 1;
        }
        else if(keydowntime >=2500 && PWR_ON_SYS) //5秒钟强制关机
        {
            _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;
        comsend = 0;
    }
    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;
        istiming = 0;
    }
    TH0 = 0xF8;
    TL0 = 0xCD;
    TF0 = 0;    
}

  • 写回答

2条回答 默认 最新

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

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

    要解决这个问题,首先我们需要了解PWR_ON_SYSPWR_HOLD的状态以及它们如何影响按键检测。根据你的描述,当键按下时,我们有几种情况:按键按下的第一秒,键按下超过300毫秒(0.6秒),键按下超过1000毫秒,并且在关闭系统后再次按下。

    对于PWR_ON_SYS状态:

    • 当键按下超过300毫秒时,我们执行以下操作:
      • 按下键
      • 开启系统电源
      • 记录键按下时间
      • 设置istiming为1

    对于PWR_HOLD状态:

    • 当键按下超过1000毫秒时,我们将设置PWR_HOLD为0。
    • 在这个情况下,我们应该检查是否已经设置了comsend标志位,如果是,则将其重置。

    下面是修改后的关键部分:

    // 把这段代码屏蔽就能够正常关机
    else if(keydowntime >=1000 && PWR_ON_SYS && !comsend) //2秒钟发送指令到ARM控制开关机重启等D8 00 05 FF
    {
        _nop_();
        _nop_();    
        UartSend(0xD8);
        UartSend(0x00);
        UartSend(0x05);
        UartSend(0xFF);
        comsend = 1;
    }
    

    现在,当我们检测到键按下并超过1000毫秒时,我们可以立即发送命令,而不是等待2秒后再做其他操作。这将有助于更快地执行关机过程。

    此外,为了确保正确的关机逻辑,我们还应该检查comsend标志位。如果它已经被设置为1,那么我们不应该再发送任何命令,因为这意味着已经在尝试关机。这样可以减少不必要的延迟。

    完整的代码可能看起来像这样:

    #include <config.h>
    #include <Uart.h>
    
    const int KEY_C = 1;
    
    // 配置定时器0
    void ConfigTimer0() {
        AUXR &= 0x7F;  // 2ms定时
        TMOD &= 0xF0;
        TH0 = 0xF8;
        TL0 = 0xCD;
        ET0 = 1;       // 使能T0中断
        TR0 = 1;       // 启动T0
    }
    
    void Timer0Isr() interrupt 1 {
        KeyScan();
        if (istiming) {
            keydowntime = 0;
            istiming = 0;
        }
    
        if (PWR_ON_SYS && !comsend) {
            if (PWR_KEY_DET) {
                // 检查按键是否按下
                keydowntime++;
            }
            if (keydowntime >= 1000 && PWR_ON_SYS) {
                // 发送关机命令
                PWR_HOLD = 0;
                comsend = 1;
            }
        }
    }
    
    void KeyScan() {
        static unsigned char keybuf = 0xFF;
        keybuf = (keybuf << 1) | PWR_KEY_DET;
        if (keybuf == 0x00) {
            keydowntime++; // 按键按下
        } else if (keybuf == 0xFF) {
            keydowntime = 0;
            keysta = 1;
            comsend = 0;
        } else {
        }
    }
    
    void KeyDriver() {
        if (keysta) {
            if (keydowntime >= 300 && !PWR_ON_SYS) {
                // 关闭系统
                _nop_();
                _nop_();
                PWR_ON_SYS = 1;
                istiming = 1;
                keysta = 0;
            } else if (keydowntime >= 1000 && PWR_ON_SYS && !comsend) {
                // 发送关机命令
                _nop_();
                _nop_();
    
                // 将comsend标志位重置
                comsend = 0;
            } else if (keydowntime >= 2500 && PWR_ON_SYS) {
                // 强制关机
                PWR_HOLD = 0;
            }
        }
    }
    

    请注意,这个示例假设你已经正确配置了定时器0,并且已经添加了必要的硬件接口。此外,你需要在适当的位置调用这些函数,例如在主循环或其他适当的中断服务函数中。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月24日

悬赏问题

  • ¥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 如何加快视频观看速度?