51单片机利用P3.3接一个外部中断输入,控制8个LED灯循环点亮外部中断未发生时,系统通过定时器完成定时0.5s的延时,使发光二极管呈从左到右的顺序一次被点亮,当有中断产生时,发光二极管则闪烁。按下P3.3所接按键,触发外部中断。
时间: 2024-03-18 18:40:06 浏览: 19
以下是相应的C语言代码:
```c
#include <reg51.h> // 51单片机的寄存器定义
// 定义8个LED灯的IO口
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
sbit LED4 = P0^3;
sbit LED5 = P0^4;
sbit LED6 = P0^5;
sbit LED7 = P0^6;
sbit LED8 = P0^7;
// 定义定时器1的初值
#define TH1_INIT 0xFD
#define TL1_INIT 0x4B
// 定时器1中断服务函数
void timer1_isr(void) interrupt 3 using 1
{
static unsigned char cnt = 0; // 计数器
TH1 = TH1_INIT;
TL1 = TL1_INIT; // 重新加载初值
cnt++;
switch(cnt)
{
case 1:
LED1 = 1;
LED2 = 0;
LED3 = 0;
LED4 = 0;
LED5 = 0;
LED6 = 0;
LED7 = 0;
LED8 = 0;
break;
case 2:
LED1 = 0;
LED2 = 1;
LED3 = 0;
LED4 = 0;
LED5 = 0;
LED6 = 0;
LED7 = 0;
LED8 = 0;
break;
case 3:
LED1 = 0;
LED2 = 0;
LED3 = 1;
LED4 = 0;
LED5 = 0;
LED6 = 0;
LED7 = 0;
LED8 = 0;
break;
case 4:
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 1;
LED5 = 0;
LED6 = 0;
LED7 = 0;
LED8 = 0;
break;
case 5:
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
LED5 = 1;
LED6 = 0;
LED7 = 0;
LED8 = 0;
break;
case 6:
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
LED5 = 0;
LED6 = 1;
LED7 = 0;
LED8 = 0;
break;
case 7:
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
LED5 = 0;
LED6 = 0;
LED7 = 1;
LED8 = 0;
break;
case 8:
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
LED5 = 0;
LED6 = 0;
LED7 = 0;
LED8 = 1;
cnt = 0; // 计数器清零
break;
}
}
// 外部中断0的中断服务函数
void ext0_isr(void) interrupt 0 using 1
{
static unsigned char cnt = 0;
while(P3_3 == 0)
{
cnt++;
if(cnt == 50)
{
LED1 = !LED1;
LED2 = !LED2;
LED3 = !LED3;
LED4 = !LED4;
LED5 = !LED5;
LED6 = !LED6;
LED7 = !LED7;
LED8 = !LED8;
cnt = 0;
}
}
}
void main()
{
TMOD = 0x10; // 定时器1工作在模式1,16位定时器
TH1 = TH1_INIT;
TL1 = TL1_INIT; // 初始值
ET1 = 1; // 开启定时器1中断
TR1 = 1; // 启动定时器1
EA = 1; // 开启总中断
EX0 = 1; // 开启外部中断0
IT0 = 1; // 外部中断0触发方式为下降沿触发
while(1)
{
// 程序主循环
}
}
```
需要注意的是,定时器1的初值需要根据实际情况设置,以满足0.5s的要求。另外,定时器1中断服务函数中的LED闪烁顺序可以根据需要进行调整。外部中断0触发时,LED灯的闪烁方式可以根据需要进行修改。