有可以帮忙搞一个单片机外部中断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(),它会阻塞程序的执行。在实际应用中,最好使用定时器来实现延时,以避免阻塞程序的执行。
#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);
}
}
}
回答:
由于外部中断0和1的控制需要用到硬件中断,因此需要用汇编语言编写程序,具体步骤如下:
首先需要设置端口,其中P0口是外部中断控制端口,P1口控制LED灯。
设置中断,将P0口上的中断0和1使能,并将其优先级设为最高。
编写中断程序,在中断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 ;程序无限循环
注:以上代码仅供参考,可能需要根据具体情况进行修改和调试。