51单片机按键控制LED移位问题

#include <REGX52.H>
#include <INTRINS.H>
void Delayms(unsigned int xms)
{
    unsigned char i, j;
    while(xms--)
    {
        _nop_();
        i = 2;
        j = 199;
        do
        {
            while (--j);
        }while (--i);
    }
}
void main()
{
    unsigned char LEDnum = 0;
    P2 = 0xFE;
    while(1)
    {
        if(P3_0 == 0)
        {
            Delayms(20);
            while(P3_0 == 0);
            Delayms(20);
            
            
            if(LEDnum >= 8)             
                LEDnum = 0;
            else
                LEDnum++;          
            P2 = ~(0x01<<LEDnum);
        }

    }
}

if(LEDnum >= 8)             
    LEDnum = 0;
else
      LEDnum++;         

为什么在按键控制LEDR8后再按下按键LED灯全灭,再次按下才会点亮LEDR1

img

  • 你看下这篇博客吧, 应该有用👉 :基于51单片机手机无线蓝牙控制8位LED灯亮灭设计(毕设课设)
  • 以下回答由chatgpt基于相关博客总结生成:

    针对该问题,可能的原因是代码逻辑错误或者硬件电路连接错误。

    下面给出一种可能的优化解决方案:

    1. 首先确定硬件电路连接是否正确,包括按键连接,LED连接,以及其他相关器件如电阻等连接是否正确。

    2. 检查代码逻辑是否有误。可以通过断点调试的方式,在程序运行到每个关键的地方打上断点,逐步排查问题。

    3. 建议采用定时器来控制LED移位,可以避免按键的不确定性带来的影响。

    4. 可以使用PWM技术来控制LED的亮度,提高LED的亮度均匀性。

    5. 此外可以加入延时等待周期结束的方式,而不是直接使用标志位控制LED的状态。

    下面是一个伪代码示例:

    // 定义LED灯的状态,0为关闭,1为打开
    #define LED_ON 1
    #define LED_OFF 0
    
    // 定义LED灯的数量
    #define LED_NUM 8
    
    // 定义LED状态数组,初始全灭
    int LedStatus[LED_NUM] = {LED_OFF, LED_OFF, LED_OFF, LED_OFF,
                              LED_OFF, LED_OFF, LED_OFF, LED_OFF};
    
    // 定义LED移位控制变量
    int LedPos = 0;
    
    // 定义按键状态,0为未按下,1为按下
    int ButtonState = 0;
    
    // 定义定时器周期和占空比
    int TimerPeriod = 1000;   // 1ms
    int TimerDutyCycle = 50;  // 50% 占空比
    
    // 定义定时器中断处理函数
    void TIMER_IRQHandler()
    {
        // 清除中断标志位
        ClearInterruptFlag();
    
        // 修改LED状态
        LedStatus[LedPos] = LED_ON;
        LedPos = (LedPos + 1) % LED_NUM;
    }
    
    // 初始化定时器
    void TIMER_Init()
    {
        // 设置定时器初始值和工作模式等
        ...
        // 开启定时器中断
        ...
    }
    
    // 初始化按键
    void Button_Init()
    {
        // 配置按键引脚为输入模式
        ...
    }
    
    // 检测按键状态
    void Button_Check()
    {
        if (ButtonPressed())
        {
            ButtonState = 1;
        }
        else if (ButtonReleased())
        {
            ButtonState = 0;
        }
    }
    
    // 控制LED移位
    void LedShift()
    {
        // 检测按键状态
        Button_Check();
    
        // 如果按键被按下
        if (ButtonState == 1)
        {
            // 移动LED灯位置
            LedPos = (LedPos + 1) % LED_NUM;
            // 将其他LED灯关闭
            for (int i = 0; i < LED_NUM; i++)
            {
                LedStatus[i] = LED_OFF;
            }
            // 刷新LED灯状态
            RefreshLED();
            // 设置按键状态为未按下
            ButtonState = 0;
        }
        else
        {
            // 修改LED灯状态
            for (int i = 0; i < LED_NUM; i++)
            {
                if (i == LedPos)
                {
                    LedStatus[i] = LED_ON;
                }
                else
                {
                    LedStatus[i] = LED_OFF;
                }
            }
            // 刷新LED灯状态
            RefreshLED();
        }
    } 
    
    // 刷新LED灯状态
    void RefreshLED()
    {
        // 使用PWM技术控制LED灯亮度和均匀性
        ...
        // 等待定时器周期结束
        Delay(TimerPeriod);
        ...
    }
    
    int main()
    {
        // 初始化定时器和按键
        TIMER_Init();
        Button_Init();
    
        // 程序主循环
        while (true)
        {
            LedShift();
        }
    }