基于51单片机的按键控制流水灯开启与关闭

如何才能实现:按键s按下一次,流水灯一直保持循环;再次按下关闭流水灯循环//w按键与s相同原理只是方向相反
现状:按键按下开启流水灯;但是流水灯效果只有一次;(代码如下)

#include 
#define uchar unsigned char
#define uint unsigned int
 sbit s=P3^0;
sbit w=P3^1;

int i,temp; 

void delay(void) {
    int i, j;
    for (i = 0; i < 100; i++) {
        for (j = 0; j < 1000; j++);
    }
}
 

void main() {
    
    while(1) {

    if(s == 0) {
        temp = 0x01;
        for(i = 0; i < 8; i++) {
            P0 = ~temp;
            delay();
            temp = temp << 1;
        }
                P0=0xFF;
    }
        if(w == 0) {
        temp = 0x80;
        for(i = 0; i < 8; i++) {
            P0 = ~temp;
            delay();
            temp = temp >> 1;
        }
                P0=0xFF;
    } 
}
 }
 

 

听取评论区意见,添加了while循环,但是效果一样
初来乍到!很多方面还在学习中(包括如何提问,与人交流)!请多多包涵!我会努力的!

本回答参考了GPT:
您需要使用一个变量来记录流水灯状态,例如定义一个名为“led_on”的变量,用于记录流水灯的状态,当按键s按下时,如果led_on为0,打开流水灯,将led_on设置为1;如果led_on为1,则关闭流水灯,将led_on设置为0。按键w也是相同的原理,只是流水灯的方向相反。

以下是修改后的代码:

#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit s = P3^0;
sbit w = P3^1;

int i, temp;
uchar led_on = 0;

void delay(void) {
    int i, j;
    for (i = 0; i < 100; i++) {
        for (j = 0; j < 1000; j++);
    }
}

void main() {
    while (1) {
        if (s == 0) {
            if (led_on == 0) {
                led_on = 1;
                temp = 0x01;
                for (i = 0; i < 8; i++) {
                    P0 = ~temp;
                    delay();
                    temp = temp << 1;
                }
                P0 = 0xFF;
            }
        } else {
            led_on = 0;
        }
        if (w == 0) {
            if (led_on == 0) {
                led_on = 1;
                temp = 0x80;
                for (i = 0; i < 8; i++) {
                    P0 = ~temp;
                    delay();
                    temp = temp >> 1;
                }
                P0 = 0xFF;
            }
        } else {
            led_on = 0;
        }
    }
}


在这个代码中,我们添加了一个名为“led_on”的变量,并将其初始化为0。在while循环中,当按键s按下时,我们首先检查led_on的值,如果它是0,那么我们打开流水灯,并将led_on设置为1。如果led_on的值为1,那么我们关闭流水灯,并将led_on设置为0。按键w的处理也是相同的。

需要注意的是,由于MCU的运行速度非常快,所以在按下按键时,可能会出现按键抖动的现象,这会导致程序多次检测到按键事件。为了避免这种情况,您可以在检测到按键状态改变后,延迟一段时间再进行下一次检测。

是不是可以加个判断,判断上一次按下是0还是1,如果是0,则下一次按下是1,如果是1,则下一次按下是0

三个状态:1、按下s,正向流水灯;2、按下w,反向流水灯;3、两个都不按下,没有灯亮



#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
 sbit s=P3^0;
sbit w=P3^1;
 
int i,temp; 
 
void delay(void) {
    int i, j;
    for (i = 0; i < 100; i++) {
        for (j = 0; j < 1000; j++);
    }
}
 
 
void main() {
 uchar led_on=0;   
    while(1) {
    if(s == 0)
    {
      led_on=1;
    }
    else if if(w == 0)
   {
     led_on=2;
   }
   else
   {
    led_on=0;
   } 

 
    if(led_on == 1) {
        temp = 0x01;
        for(i = 0; i < 8; i++) {
            P0 = ~temp;
            delay();
            temp = temp << 1;
        }
                P0=0xFF;
    }
        if(led_on == 2) {
        temp = 0x80;
        for(i = 0; i < 8; i++) {
            P0 = ~temp;
            delay();
            temp = temp >> 1;
        }
                P0=0xFF;
    } 
    if(led_on == 0)
   {
     temp = 0x00;
     P0 = ~temp;
   }
  }
 }
 


#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit s=P3^0;
sbit w=P3^1;

int i,temp; 

void delay(void) {
    int i, j;
    for (i = 0; i < 100; i++) {
        for (j = 0; j < 1000; j++);
    }
}
void main() {
    while(1) {
        if(P0!=0xff){
            delay(); //消抖
            if(P0!=0xff){        
                if(s == 0) {
                    temp = 0x01;
                    for(i = 0; i < 8; i++) {
                        P0 = ~temp;
                        delay();
                        temp = temp << 1;
                    }
                }
                else if(w == 0) {
                    temp = 0x80;
                    for(i = 0; i < 8; i++) {
                        P0 = ~temp;
                        delay();
                        temp = temp >> 1;
                    }    
                }
                else{
                    P0=0xFF;
                }   
            }
        }
        else{
                P0=0xFF;
        } 
    }
 }