tuantuan_2022 2023-01-11 09:55 采纳率: 50%
浏览 53
已结题

51单片机 按键控制LED状态

功能是一个按键,控制多种LED的多种工作状态,如常亮、常灭、呼吸灯、亮灭等。
发现了一个问题,如果用以下代码,在LED灯效中有delay延迟时候,则程序流程上会导致按键有一定延迟。

#include <REGX52.H>

void Delay(unsigned int xms)
{
    unsigned char i, j;
    while(xms)
    {
        i = 2;
        j = 239;
        do
        {
            while (--j);
        } while (--i);
        xms--;
    }
}

unsigned char ledmod=0;
void main()
{
    while(1)
    {
        if(P3_1==0)
        {
            Delay(50);
            while(P3_1==0);
            Delay(50);
            ledmod++;
            switch(ledmod)
            {
                case 1:P2_0=0;break;
                case 2:P2_1=0;break;
                case 3:
                    for(;ledmod==3;)
                    {
                        P2_3=0;
                        Delay(500);
                        P2_3=1;
                        Delay(500);
                        if(P3_1==0)
                        {
                            Delay(50);
                            while(P3_1==0);
                            Delay(50);
                            ledmod=0;
                            P2_0=1;
                            P2_1=1;
                        }
                    }
                    break;
                }
        }
            
    }

}

请教各位学霸,
1有什么办法解决这个按键延迟?
2在不改变delay延迟函数的前提下,有什么办法消除这个延迟?

  • 写回答

2条回答 默认 最新

  • |__WhoAmI__| 2023-01-11 10:22
    关注

    1、可以使用按键消抖,可以减少按键触发时延迟的影响。按键消抖一般是在检测到按键按下之后,等待一段时间再检测按键状态,如果按键状态仍为按下,就认为用户真正按下了按键。
    2、另一种方法是使用中断。在程序中设置一个标志位,在中断服务程序中设置该标志位。当主程序检测到标志位被设置时,就可以进行按键处理,而不需要使用延时。这样可以在等待按键按下时,程序可以做其它事情,而不会导致程序流程阻塞。
    详细来说,第一种方法可以通过在读取按键状态之后设置一个计时器,在计时器达到一定值之后才读取按键的状态,或者使用按键状态计数等方法。

    第二种方法中,中断处理程序中当检测到按键状态改变时将一个标志位设置,而不是像普通程序中那样使用延时等待。
    仅供参考,望采纳,谢谢。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 1月19日
  • 已采纳回答 1月11日
  • 创建了问题 1月11日

悬赏问题

  • ¥15 网络科学导论,网络控制
  • ¥100 安卓tv程序连接SQLSERVER2008问题
  • ¥15 利用Sentinel-2和Landsat8做一个水库的长时序NDVI的对比,为什么Snetinel-2计算的结果最小值特别小,而Lansat8就很平均
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd