按键通过中断系统实现流水灯

我本意是想使用按键通过中断方式实现流水灯,但是现在按键还没按下就开始流水灯了,麻烦各位指点一二

img

img

img

代码里没有按键识别,k1虽然定义为p30口,代码里没有读取判断按键状态的代码,需要在while(1){按键读取代码},然后根据按键是否按下,控制中断允许或禁止,从而控制流水灯。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7602685
  • 这篇博客你也可以参考下:按键控制流水灯快慢及其方向
  • 除此之外, 这篇博客: 【电子技术实验设计】简易水位控制器设计报告中的 一、设计任务与要求 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    • 简便水塔水位控制器具有四个水位检测输入
    • 由低到高分别为H l、H2、 H3、H4
    • 380V交流航动功率为10KW的电机电动机分别为M l、M2;
    • 控制根器据水位状态控制电机工作
  • 您还可以看一下 陈虎老师的一小时快速学习屏幕录像和视频编辑实战教程课程中的 如何给视频添加水印小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    问题解答:

    由于没有提供具体的代码,所以无法直接检查哪个地方逻辑有误。我们可以根据参考资料提供的代码来进行修改,实现按键中断流水灯的效果。

    1.首先,需要添加外部中断相关的代码。在参考代码中,开启了定时器0中断,我们可以在按键按下时调用一个外部中断来触发流水灯的效果,具体代码如下:

    #include <reg52.h>
    
    typedef unsigned int u16;    
    typedef unsigned char u8;
    
    #define LED P0
    #define KEY P1
    
    bit LED_flag = 0;  //定时到1s的标志位
    u8 n;              //循环变量,用作LED总线的位索引index
    
    void InitTimer0(void);  //定时器0,初始化
    void ExtInt_Init(void); //外部中断初始化
    
    void main()
    {
        LED = 0xFE;     //初始值,最右边的灯亮
        InitTimer0();
        ExtInt_Init();
        while(1)
        {
            if(LED_flag == 1)
            {
                LED_flag = 0;
                LED = (LED >> 1) | 0x80;  //LED右移,最左边的灯亮
            }       
        }
    }
    
    void InitTimer0(void) 
    {
        TMOD |= 0x01;   //用|=防止配置冲突
        TH0 = (65536 - 50000)/256; ///定时器0,置初值(定时50ms)
        TL0 = (65536 - 50000)%256;
        EA = 1;
        ET0 = 1;
        TR0 = 1;
    }
    
    void Timer0() interrupt 1    //定时器0,中断服务函数
    {
        static u16 i;
        TH0 = (65536 - 50000)/256; ///定时器0,重装初值(定时50ms)
        TL0 = (65536 - 50000)%256;
        i++;
        if(i==20) // 1s = 20 × 50ms 
        {
            i=0;
            LED_flag=1; 
        }   
    }
    
    void ExtInt_Init(void)      //外部中断初始化
    {
        EA = 1;
        EX0 = 1;                //开INT0中断
        IT0 = 0;                //设定INT0下降沿触发
    }
    
    void Int0() interrupt 0      //外部中断0处理函数
    {
        LED = 0xFE;     //按下按键,最右边灯亮
    }
    

    2.修改正常计时的流水灯效果。在以上代码中,定时器0定时50ms,20次中断即1s。在每次中断发生时,右移LED的值,实现流水灯的效果。由于LED的最左边一位要一直保持高电平,所以每次右移需要在最左边位写入1,同时在参考代码中,初始值是最右侧一位高电平,所以需要将LED的初始值改为0xFE(二进制11111110),最右侧一位为低电平,其他全是高电平,代码中已经做了修改。

    这样的流水灯效果实现不需要按下按键即可开始,按下按键后最右侧一位就亮了,然后开始流水灯效果。如果需要按下按键后流水灯才开始,可以在初始化时将LED的值赋为0xFF,也就是所有灯都不亮,等待按键触发后开始流水灯效果。


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