#include <reg51.h> unsigned char code table[] = { 0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6, 0xEE, 0x3E, 0x9C, 0x7A, 0x9E, 0x8E}; unsigned char i, j, flag,num; char Count; bit Sym=0; sbit nred=P1^2; sbit ngreen=P1^4; sbit nyellow=P1^3; void putch(unsigned char n) { SBUF=n; while(TI==0); TI=0; } void main() { TMOD=0X01; EA=1; ET0=1; TH0=(65536-50000)/256; TL0=(65536-50000)%256; flag=0; Count=0; nred=nyellow=ngreen=0; num=0; i=table[Count/10]; j=table[Count%10]; putch(i); putch(j); while(1) { if(num==0) { if(Sym){ ngreen=1; nred=0; nyellow=0; } else{ nred=1; ngreen=0; nyellow=0; } } else{ nyellow=1; nred=0; ngreen=0; } } } void Timer0() interrupt 1 { flag++; TH0=(65536-50000)/256; TL0=(65536-50000)%256; if(flag==20){ flag=0; Count--; } if(Count=num){ Count=10; if(num==0){ num=8; nyellow=0; Sym=~Sym; } else { nyellow=0; num=0; } } i=table[Count/10]; j=table[Count%10]; putch(i); putch(j); }增加两个中断实现交通管制
时间: 2024-04-25 14:26:37 浏览: 39
好的,您的问题是如何在这段代码中增加两个中断实现交通管制?
首先,我们需要知道这段代码是实现了一个计时器,每隔一定时间就会触发中断,同时通过数码管输出倒计时的时间。
那么,我们可以在这个基础上增加两个中断,分别用于控制红绿灯的开关。
具体实现方法如下:
1. 定义两个变量,分别表示红绿灯的状态,比如 red_light 和 green_light,初始值都为 0,表示都是关闭状态。
2. 编写一个新的中断函数,用于控制红绿灯的开关。可以使用定时器中断触发这个中断函数,比如每隔 5 秒触发一次。
3. 在中断函数中,先判断当前红绿灯的状态,如果是关闭状态,就打开红灯,关闭绿灯;如果是打开状态,就关闭红灯,打开绿灯。同时更新红绿灯的状态变量。
4. 在主函数中,添加一个循环,不断检测红绿灯的状态,根据状态控制数码管的显示内容。
5. 编写第二个中断函数,用于控制黄灯的闪烁。和第一个中断函数类似,可以使用定时器中断触发这个中断函数,比如每隔 1 秒触发一次。
6. 在中断函数中,先判断当前黄灯的状态,如果是关闭状态,就打开黄灯;如果是打开状态,就关闭黄灯。同时更新黄灯的状态变量。
7. 在主函数中,添加一个循环,不断检测黄灯的状态,根据状态控制数码管的显示内容。
需要注意的是,由于这里涉及到了多个中断,可能会存在中断嵌套的情况,需要在编写中断函数时注意避免这种情况的发生。另外,为了保证交通管制的效果,需要根据实际需求调整各个中断的触发时间和控制逻辑。
相关问题
#include <reg51.h> unsigned char code table[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E}; unsigned char Count,i,j; void Timer0_Init() { TMOD |= 0x01; TH0 = 0x3C; TL0 = 0xAF; EA = 1; ET0 = 1; TR0 = 1; } void Timer0_ISR() interrupt 1 { TH0 = 0x3C; TL0 = 0xAF; Count--; if(Count == 60) { Count = 0; } i = table[Count / 10]; j = table[Count % 10]; SBUF = i; while(TI == 0); TI = 0; SBUF = j; while(TI == 0); TI = 0; } void main(void) { Count = 60; Timer0_Init(); while(1); }
这段程序与之前的程序相比,只有一个小错误。在定时器中断服务程序中,我们将`if(Count == 0)`修改为了`if(Count == 60)`,这样在计数器减到0时不会将计数器重新设置为60,而是一直保持在0。因此,需要将`if(Count == 60)`修改回`if(Count == 0)`。修改后的程序如下:
```c
#include <reg51.h>
unsigned char code table[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E};
unsigned char Count,i,j;
void Timer0_Init()
{
TMOD |= 0x01;
TH0 = 0x3C;
TL0 = 0xAF;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void Timer0_ISR() interrupt 1
{
TH0 = 0x3C;
TL0 = 0xAF;
Count--;
if(Count == 0)
{
Count = 60;
}
i = table[Count / 10];
j = table[Count % 10];
SBUF = i;
while(TI == 0);
TI = 0;
SBUF = j;
while(TI == 0);
TI = 0;
}
void main(void)
{
Count = 60;
Timer0_Init();
while(1);
}
```
在程序中,我们还是使用了定时器0来实现每隔1秒钟计数器减1的功能。程序中的`Timer0_Init()`函数用于初始化定时器0,`Timer0_ISR()`函数为定时器0的中断服务程序。在程序的`main()`函数中,我们调用了`Timer0_Init()`函数进行定时器0的初始化,并在无限循环中等待定时器0中断的触发。
#include <reg51.h> unsigned char code table[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0, 0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E}; unsigned char Count,i,j; void Mydelay10ms(void) { unsigned char i,j; for(i=250;i>0;i--) for(j=248;j>0;j--); } void putch(unsigned char n) { SBUF=n; while(TI==0); TI=0; } void main(void) { Count=60; i=table[Count/10]; j=table[Count%10]; putch(i); putch(j); Mydelay10ms(); Mydelay10ms(); Mydelay10ms(); Mydelay10ms(); while(1) { Mydelay10ms(); Count--; if(Count==0) { Count=60; } i=table[Count/10]; j=table[Count%10]; putch(i); putch(j); Mydelay10ms(); Mydelay10ms(); Mydelay10ms(); Mydelay10ms(); } }上述程序修改为用定时中断,定时1s,实现0到60的计数,60清零
下面是修改后的程序:
```c
#include <reg51.h>
unsigned char code table[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E};
unsigned char Count,i,j;
void Timer0_Init()
{
TMOD |= 0x01; // 设置定时器0为模式1
TH0 = 0x3C; // 设置定时器0初值为0x3C
TL0 = 0xAF; // 设置定时器0初值为0xAF
EA = 1; // 打开总中断开关
ET0 = 1; // 打开定时器0中断开关
TR0 = 1; // 启动定时器0
}
void Timer0_ISR() interrupt 1 // 定时器0中断服务程序
{
TH0 = 0x3C; // 重新设置定时器0初值
TL0 = 0xAF;
Count--; // 计数器减1
if(Count == 0)
{
Count = 60; // 计数器清零
}
i = table[Count / 10];
j = table[Count % 10];
SBUF = i; // 发送高位数码
while(TI == 0);
TI = 0;
SBUF = j; // 发送低位数码
while(TI == 0);
TI = 0;
}
void main(void)
{
Count = 60;
Timer0_Init();
while(1);
}
```
在修改后的程序中,我们使用了定时器0来实现每隔1秒钟计数器减1的功能。具体来说,我们设置定时器0为模式1,初值为0x3CAF,定时器溢出时触发定时器0中断服务程序,在其中让计数器减1并发送数码管显示的数码。程序中的`Timer0_Init()`函数用于初始化定时器0,`Timer0_ISR()`函数为定时器0的中断服务程序。程序中的`TR0`为定时器0的启动控制位,`ET0`为定时器0的中断允许控制位。在程序的`main()`函数中,我们调用了`Timer0_Init()`函数进行定时器0的初始化,并在无限循环中等待定时器0中断的触发。
阅读全文