51单片机彩灯控制器

有没有懂得朋友,这段程序如何改,想用独立按键来切换LED花样,达到即可以自动循环,又可以手动切换,按键是P3.7
先谢过各位了,题目如下

img

#include <REGX51.H>
#define Led    P2

unsigned int time=0;     //延时时长变量
sbit key=P3^7;
void InitTimer0(void)     //10ms
{
    TMOD = 0x01;         //定时器模式1
    //赋值
    TH0 = 0xDC;
    TL0 = 0x00;
    EA = 1;                 //开总中断
    ET0 = 1;             //开定时器0中断
}

void delay(unsigned int ms_10)           //延时函数
{     
    if(key==0)
    {
    time=0;
    }
     time=ms_10;                       //给time赋予具体延时时间的数值
     TR0 = 1;                           //打开定时器0
     while(time);                       //等待延时结束
     TR0 = 0;                           //关闭定时器0
}

void light_water()                       //流水灯函数
{
    int i=0,Led_H=0,Led_L=0,temp=0x06,num=0;     //Led_H存储P2高8位Led_L存储P2低8位
    Led=0x01;
    delay(50);//100ms
    for(i=0;i < 7;i++)      //单个左移
    {
        Led=Led<<1;                             //P2数值左移
        delay(50);//100ms    
    }
    for(i=0;i < 7;i++)      //单个右移
    {
        Led=Led>>1;                             //P2数值右移
        delay(50);//100ms    
    }
    for(i=0;i < 7;i++)      //依次向左点亮
    {
        Led=Led<<1|0x01;                         //P2数值左移并将最低位置为1
        delay(50);//100ms    
    }
    for(i=0;i < 7;i++)      //依次向右点亮
    {
        Led=Led>>1;                             //P2数值右移,依次将位1清零
        delay(50);//100ms    
    }
    Led=0x00;
    for(i=0;i < 7;i++)      //两端向内依次点亮
    {
        Led_L=Led<<1|0x01&0x0f;                 //取出P2的低4位,并将其左移最低位置1
        Led_H=((Led&0xf0)>>1)^0x80;             //取出P2的高4位,并将其右移最高位置1
        Led=Led|Led_L;                             //将低4位赋予P2
        Led=Led|Led_H;                             //将高4位赋予P2
        delay(50);//100ms    
    }
    for(i=0;i < 7;i++)      //由内向两端依次点亮
    {
        Led_L=(Led&0x0f)>>1;                     //取P2低4位并右移
        Led_H=(Led&0xf0)<<1;                     //取P2高4位并左移
        Led=Led&Led_L;                             //将低4位赋予P2
        Led=Led^Led_H;                             //将高4位赋予P2
        delay(50);//100ms    
    }
    Led=0x00;
    for(i=0;i < 10;i++)      //依次向左点亮2个灯
    {
        num=Led<<1|0x01;                         //P2数值左移并最低位置1
        if(num>=0x06)                         //23个灯亮后,以2个灯为主体向左移动
        {
            Led=num&temp;
            temp=temp<<1;    
        }
        else 
            Led=num;
        delay(50);//100ms    
    }
    Led=0x00;
    temp=0xc0;
    for(i=0;i < 10;i++)      //依次向右点亮2个灯
    {
        num=Led>>1|0x80;                        //将P2数值右移并最高位置1
        if(num>=temp)                            //67个灯亮时以两个灯为整体向右移动
        {
            Led=num&temp;
            temp=temp>>1;
        }
        else
            Led=num;
        delay(50);//100ms    
    }
}

void main(void)
{

    InitTimer0();             //定时器初始化
    while(1)
    {
        light_water();
    }
}

void Timer0Interrupt(void) interrupt 1
{
    TH0 = 0xDC;
    TL0 = 0x00;
    time--;
    if(time < 0)
    {
        time = 0;              //time为0时不在减
    }

}



【以下回答由 GPT 生成】

根据你提供的代码,首先我们需要了解51单片机的工作原理和按键的检测方法。当按下按键时,P3.7引脚上的电平会从高电平变为低电平,我们可以通过检测这个状态变化来判断按键是否被按下。

现在来讨论如何修改代码以实现自动循环和手动切换LED花样的功能。

  1. 首先,在代码开头声明一个全局变量unsigned char mode来表示当前的模式。我们将mode的初值设为0,表示自动循环模式。
unsigned char mode = 0; // 初始值为自动循环模式
  1. InitTimer0()函数中,初始化按键相关的GPIO口。将key对应的引脚P3.7设为输入,即设置为逻辑输入模式。
void InitTimer0(void) {
    // ...
    key = 1; // 设置为输入
    // ...
}
  1. 修改delay()函数,在等待延时结束之前,一直检测按键是否按下。如果按键按下,我们将mode切换为1(手动切换模式)。
void delay(unsigned int ms_10) {
    if (key == 0) {
        mode = 1; // 切换为手动切换模式
    }
    // ...
}
  1. 修改light_water()函数,在循环中判断当前的模式,分别执行自动循环和手动切换的代码。
void light_water() {
    int i = 0, Led_H = 0, Led_L = 0, temp = 0x06, num = 0;
    Led = 0x01;
    delay(50); // 100ms
    if (mode == 0) {
        // 自动循环模式
        for (i = 0; i < 7; i++) {
            Led = Led << 1;
            delay(50); // 100ms
        }
        for (i = 0; i < 7; i++) {
            Led = Led >> 1;
            delay(50); // 100ms
        }
        for (i = 0; i < 7; i++) {
            Led = Led << 1 | 0x01;
            delay(50); // 100ms
        }
    } else {
        // 手动切换模式
        if (key == 0) {
            Led = Led << 1;
            delay(50); // 100ms
        } else {
            Led = Led >> 1;
            delay(50); // 100ms
        }
    }
}

这样,我们通过检测按键的状态,在自动循环模式和手动切换模式之间进行切换。按下按键时,进入手动切换模式,此时每按下一次按键,LED灯的花样就切换一次。

请注意,以上的解决方案是基于你提供的代码和要求所做的推测。如果问题描述不准确或存在其他前提,请提供更正后的信息。如果你还有其他问题或需要进一步的帮助,请随时告诉我。



【相关推荐】



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