用AT89c51写个中断法满足以上条件的程序
时间: 2024-02-17 16:01:22 浏览: 72
好的,以下是使用AT89C51单片机编写的中断法程序,实现了与前面提到的要求相同的功能:
```c
#include <REG52.H> // 引入AT89C51单片机头文件
void delay(unsigned int xms); // 声明延时函数
void S1_ISR() interrupt 0; // 声明S1按键中断服务函数
void S2_ISR() interrupt 2; // 声明S2按键中断服务函数
bit S1_flag = 0; // S1按键标志位
bit S2_flag = 0; // S2按键标志位
void main()
{
unsigned char i;
P1 = 0x01; // 第一只LED灯亮
for(i=0; i<7; i++) // 循环移位
{
delay(100); // 延时一段时间,用于显示效果
P1 = P1 << 1; // 移位
P1 = P1 | 0x01; // 最低位补1
}
EA = 1; // 开启总中断
EX0 = 1; // 开启INT0中断
IT0 = 1; // INT0中断触发方式为下降沿触发
EX1 = 1; // 开启INT1中断
IT1 = 1; // INT1中断触发方式为下降沿触发
while(1)
{
// 流水显示
if(S1_flag == 0 && S2_flag == 0) // S1和S2都未按下
{
P1 = 0x01; // 第一只LED灯亮
for(i=0; i<7; i++) // 循环移位
{
delay(100); // 延时一段时间,用于显示效果
P1 = P1 << 1; // 移位
P1 = P1 | 0x01; // 最低位补1
}
}
// 左右交替闪烁
if(S1_flag == 1) // S1按键按下
{
P1 = 0xAA; // 10101010,左右交替闪烁
delay(500); // 延时一段时间,用于显示效果
P1 = 0x55; // 01010101,左右交替闪烁
delay(500); // 延时一段时间,用于显示效果
S1_flag = 0; // 清除S1按键标志位
}
// 全部闪亮
if(S2_flag == 1) // S2按键按下
{
P1 = 0xFF; // 所有LED灯全部亮
delay(500); // 延时一段时间,用于显示效果
P1 = 0x00; // 所有LED灯全部灭
delay(500); // 延时一段时间,用于显示效果
S2_flag = 0; // 清除S2按键标志位
}
}
}
void delay(unsigned int xms) // 延时函数
{
unsigned int i, j;
for(i=xms; i>0; i--)
{
for(j=112; j>0; j--);
}
}
void S1_ISR() interrupt 0 // S1按键中断服务函数
{
S1_flag = 1; // 设置S1按键标志位
}
void S2_ISR() interrupt 2 // S2按键中断服务函数
{
S2_flag = 1; // 设置S2按键标志位
}
```
在这个程序中,我们使用了单片机的外部中断0和外部中断1来检测S1和S2按键的状态,当按键被按下时,中断服务函数会设置相应的标志位。在主函数中,我们通过判断这些标志位的值来实现不同的LED灯显示效果。
需要注意的是,在使用中断法时,需要在程序开头声明中断服务函数,并在main函数中开启相应的中断,并设置中断触发方式。同时,需要在中断服务函数中清除相应的标志位,否则会导致程序一直执行中断服务函数,无法正常运行。在AT89C51单片机中,开启总中断的方式是通过EA寄存器实现的。
阅读全文