外部中断未发生时,系统通过定时器完成定时0.5s的延时,使8个发光二极管呈从左到右的顺序一次被点亮,当有中断产生时,发光二极管则闪烁。按下P3.3所接按键,触发外部中断。 编写Keil89C52程序,用按键模拟单片机外部中断输入源,当按键按下时产生中断。外部中断未发生时,系统通过定时器完成定时0.5s的延时,使发光二极管呈从左到右的顺序一次被点亮,当有中断产生时,发光二极管则闪烁。
时间: 2024-03-16 07:44:15 浏览: 85
好的,以下是基于 Keil C51 编译器的代码实现,实现了通过按键模拟外部中断输入源,以及定时器控制发光二极管的亮灭顺序:
```c
#include <reg52.h>
// 定义端口、变量
sbit LED = P1^0; // 定义P1.0口为发光二极管
sbit KEY = P3^3; // 定义P3.3口为按键
unsigned char LEDStatus = 0; // 定义发光二极管状态变量
// 定时器0初始化函数
void InitTimer0(void)
{
TMOD &= 0xF0; // 定时器0工作在模式1,16位定时器模式
TL0 = 0x00; // 定时器0低8位赋初值
TH0 = 0x4C; // 定时器0高8位赋初值,计数初值为65536-50000=15536
TR0 = 1; // 启动定时器0
ET0 = 1; // 使能定时器0中断
EA = 1; // 使能总中断
}
// 定时器0中断函数
void Timer0() interrupt 1
{
static unsigned char cnt = 0; // 定义计数器,用于记录发光二极管的亮灭顺序
TH0 = 0x4C; // 计数初值为65536-50000=15536
TL0 = 0x00;
cnt++; // 计数器加1
if(cnt == 9) cnt = 1; // 计数器归1
LEDStatus = 1<<(cnt-1); // 根据计数器确定发光二极管亮灭状态
}
// 外部中断0初始化函数
void InitINT0(void)
{
IT0 = 1; // 设置外部中断0为下降沿触发
EX0 = 1; // 使能外部中断0
}
// 外部中断0中断函数
void INT0() interrupt 0
{
LEDStatus = ~LEDStatus; // 发光二极管状态取反
}
// 主函数
void main(void)
{
InitTimer0(); // 定时器0初始化
InitINT0(); // 外部中断0初始化
while(1)
{
LED = LEDStatus; // 根据发光二极管状态变量更新发光二极管的亮灭状态
}
}
```
程序初始化时,先调用 `InitTimer0` 函数和 `InitINT0` 函数,分别对定时器0和外部中断0进行初始化。在 `InitTimer0` 函数中,设置定时器0工作在模式1(16位定时器模式),计数初值为65536-50000=15536,即定时0.5s。启动定时器0,使能定时器0中断,使能总中断。在 `Timer0` 函数中,每次定时器0中断时,根据计数器 `cnt` 的值确定发光二极管的亮灭状态,计数器加1。在 `InitINT0` 函数中,设置外部中断0为下降沿触发,使能外部中断0。当外部中断0发生时,调用 `INT0` 函数,将发光二极管状态取反。在主函数中,不断根据发光二极管状态变量 `LEDStatus` 更新发光二极管的亮灭状态。
在此基础上,我们需要在 `INT0` 函数中添加按键检测的代码,模拟外部中断输入源。具体来说,我们可以使用 `KEY` 变量检测按键状态,当按键按下时,模拟外部中断0发生,否则不发生。修改后的代码如下:
```c
#include <reg52.h>
// 定义端口、变量
sbit LED = P1^0; // 定义P1.0口为发光二极管
sbit KEY = P3^3; // 定义P3.3口为按键
unsigned char LEDStatus = 0; // 定义发光二极管状态变量
// 定时器0初始化函数
void InitTimer0(void)
{
TMOD &= 0xF0; // 定时器0工作在模式1,16位定时器模式
TL0 = 0x00; // 定时器0低8位赋初值
TH0 = 0x4C; // 定时器0高8位赋初值,计数初值为65536-50000=15536
TR0 = 1; // 启动定时器0
ET0 = 1; // 使能定时器0中断
EA = 1; // 使能总中断
}
// 定时器0中断函数
void Timer0() interrupt 1
{
static unsigned char cnt = 0; // 定义计数器,用于记录发光二极管的亮灭顺序
TH0 = 0x4C; // 计数初值为65536-50000=15536
TL0 = 0x00;
cnt++; // 计数器加1
if(cnt == 9) cnt = 1; // 计数器归1
LEDStatus = 1<<(cnt-1); // 根据计数器确定发光二极管亮灭状态
}
// 外部中断0初始化函数
void InitINT0(void)
{
IT0 = 1; // 设置外部中断0为下降沿触发
EX0 = 1; // 使能外部中断0
}
// 外部中断0中断函数
void INT0() interrupt 0
{
if(KEY == 0) // 按键按下,模拟外部中断0发生
{
LEDStatus = ~LEDStatus; // 发光二极管状态取反
}
}
// 主函数
void main(void)
{
InitTimer0(); // 定时器0初始化
InitINT0(); // 外部中断0初始化
while(1)
{
LED = LEDStatus; // 根据发光二极管状态变量更新发光二极管的亮灭状态
}
}
```
在 `INT0` 函数中,添加了按键检测的代码,当按键按下时,模拟外部中断0发生,将发光二极管状态取反。在主函数中,不断根据发光二极管状态变量 `LEDStatus` 更新发光二极管的亮灭状态。
阅读全文