51单片机流水灯程序

有可以帮忙搞一个单片机外部中断0控制流水灯从右到左依次点亮最后全亮,外部中断1控制LED闪烁的程序吗


#include <reg52.h>

#define LED P1

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

void main() {
    EA = 1;         // 允许中断
    EX0 = 1;        // 允许外部中断0
    IT0 = 1;        // 设置外部中断0为下降沿触发
    EX1 = 1;        // 允许外部中断1
    IT1 = 0;        // 设置外部中断1为低电平触发

    while (1) {
        LED = 0xff; // 熄灭所有LED
        delay(500);
        LED = 0x00; // 点亮所有LED
        delay(500);
    }
}

void int0_isr() interrupt 0 {
    int i;
    for (i = 0; i < 8; i++) {
        LED = ~(1 << i);    // 依次点亮LED
        delay(100);
    }
    LED = 0xff;             // 全亮
    delay(100);
}

void int1_isr() interrupt 2 {
    while (1) {
        LED = ~LED;         // LED闪烁
        delay(50);
    }
}

在该程序中,我们使用了两个中断函数 int0_isr() 和 int1_isr(),分别用于处理外部中断0和外部中断1。在 int0_isr() 中,我们使用一个循环来依次点亮LED,并在最后将所有LED设置为高电平,实现全亮效果。在 int1_isr() 中,我们使用一个无限循环来让LED不断闪烁。

需要注意的是,我们在程序中使用了一个简单的延时函数 delay(),它会阻塞程序的执行。在实际应用中,最好使用定时器来实现延时,以避免阻塞程序的执行。

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7783497
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:51单片机 定时器0中断实现1秒LED流水灯
  • 除此之外, 这篇博客: 51单片机流水灯程序中的 一、实现 LED 灯流水闪烁的效果 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • #include"reg52.h"
    #include"intrins.h"
    #define led P2
    typedef unsigned char u8;
    typedef unsigned int u16;
    
    void delay(u16 i)
    {
    	while(i--);
    }
    
    void main()
    {
    	u16 i;
    	led=0xfe;
    	delay(50000);
    	
    	while(1)
    	{
    		for(i = 0; i < 7; i ++)
    		led=_crol_(led,1);
    		delay(50000);
    		
    		for(i = 0; i < 7; i ++)
    		{
    			led=_cror_(led,1);
    			delay(50000);
    		}	
    	}
    }
  • 您还可以看一下 朱有鹏老师的巫妖王51单片机开发板配套视频课程课程中的 LED闪烁和流水灯效果小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    回答:

    由于外部中断0和1的控制需要用到硬件中断,因此需要用汇编语言编写程序,具体步骤如下:

    1. 首先需要设置端口,其中P0口是外部中断控制端口,P1口控制LED灯。

    2. 设置中断,将P0口上的中断0和1使能,并将其优先级设为最高。

    3. 编写中断程序,在中断0和1触发时执行相应的操作。对于中断0,需要控制LED流水灯从右到左依次点亮,最后全亮;对于中断1,需要控制LED灯闪烁。

    下面是具体的汇编代码:

    ORG 0H              ;程序从0地址开始
    MOV P1, #0FFH           ;P1口设置为输出口所有LED都熄灭
    MOV P0, #0          ;P0口设置为输入口
    SETB P0.0           ;使能中断0
    SETB P0.1           ;使能中断1
    SETB EA             ;全局中断使能
    SETB EX0            ;外部中断0中断允许
    SETB EX1            ;外部中断1中断允许
    SETB IT0            ;使能中断0下降沿触发
    SETB IT1            ;使能中断1下降沿触发
    SJMP MAIN           ;跳转到主程序
    
    INT0_ISR:           ;中断0服务程序
        MOV P1, #0FFH       ;使所有LED灯全灭
        MOV R3, #8H     ;设置计数器
    loop1:                  
        CPL P1.0            ;将1号LED灯的状态取反
        MOV A, P1           ;将P1的值取出到累加器A中
        RL A            ;将累加器A的值左移一位
        MOV P1, A           ;将累加器A的值存回P1  
        DJNZ R3, loop1      ;计数器减一如果不为0则继续执行loop1循环
        SETB P1.0           ;点亮所有LED灯
        RETI            ;从中断服务程序中返回
    
    INT1_ISR:           ;中断1服务程序
        MOV A, #10H         ;设置计数器
        loop2:                  
            CPL P1.0        ;将1号LED灯的状态取反
            ACALL DELAY     ;延时一段时间
            CPL P1.0        ;将1号LED灯的状态再次取反
            ACALL DELAY     ;延时一段时间
            DJNZ A, loop2       ;计数器减一如果不为0则继续执行loop2循环
        RETI            ;从中断服务程序中返回
    
    DELAY:              ;延时函数
        PUSH ACC            ;保存现场寄存器
        MOV R4, #10H        ;设置计数器
    delay_loop:         
        DJNZ R4, delay_loop     ;计数器减一如果不为0则继续执行delay_loop循环
        POP ACC         ;恢复现场寄存器
        RET             ;返回调用函数
    
    MAIN:               ;主程序
        SJMP MAIN           ;程序无限循环
    

    注:以上代码仅供参考,可能需要根据具体情况进行修改和调试。